Steer clear of dividing words

I am attempting to showcase sentences letter by letter with a fade in/fade out effect. However, I am facing an issue where words break in the middle. How can this word breaking be prevented?

var quotes = document.getElementsByClassName('quote');
var quoteArray = [];
var currentQuote = 0;
quotes[currentQuote].style.opacity = 0;
for (var i = 0; i < quotes.length; i++) {
  splitLetters(quotes[i]);
}
function changeQuote() {
  var cw = quoteArray[currentQuote];
  var nw = currentQuote == quotes.length-1 ? quoteArray[0] : quoteArray[currentQuote+1];
  for (var i = 0; i < cw.length; i++) {
    animateLetterOut(cw, i);
  }
  for (var i = 0; i < nw.length; i++) {
    nw[i].className = 'letter behind';
    nw[0].parentElement.style.opacity = 1;
    animateLetterIn(nw, i);
  }
  
  currentQuote = (currentQuote == quoteArray.length-1) ? 0 : currentQuote+1;
}
function animateLetterOut(cw, i) {
  setTimeout(function() {
cw[i].className = 'letter out';
  }, 0);
}
function animateLetterIn(nw, i) {
  setTimeout(function() {
nw[i].className = 'letter in';
  }, 340+(i*30));
}
function splitLetters(quote) {
  var content = quote.innerHTML;
  console.log(quote.innerHTML);
  quote.innerHTML = '';
  var letters = [];
  for (var i = 0; i < content.length; i++) {
    var letter = document.createElement('span');
    letter.className = 'letter';
    letter.innerHTML = content.charAt(i)==' '?'&nbsp;':content.charAt(i);
    quote.appendChild(letter);
    letters.push(letter);
  }
  
  quoteArray.push(letters);
}
changeQuote();
setInterval(changeQuote, 10000);
body {
  font-weight: 600;
  font-size: 40px;
}
.text {
  position: relative;
}
.quote {
  position: absolute;
  opacity: 0;
}
.letter {
  display: inline-block;
  position: relative;
  float: left;
  -webkit-transform: translateZ(25px);
          transform: translateZ(25px);
  -webkit-transform-origin: 50% 50% 25px;
          transform-origin: 50% 50% 25px;
}
.letter.out {
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s 0.7s, opacity 0.7s linear;
}
.letter.behind {
  visibility: hidden;
  opacity: 0;
}
.letter.in {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.7s linear;
}
<body>
<div class="text">
  <p>
    <span class="quote">TEXT ONE(1): For example, if you are designing a brand new website for someone, most times you will have to make sure the prototype looks finished by inserting text or photos or what have you. </span>
    <span class="quote">TEXT TWO(2): The purpose of this is so the person viewing the prototype has a chance to actually feel and understand the idea behind what you have created.</span>
  </p>
  
</div>

Answer №1

Your setInterval(changeQuote, 5000) is responsible for the unique effect you have skillfully implemented in a concise manner. Initially playing around with the timing intervals from 5000ms to 15000ms down to approximately 8000~10000ms seemed to yield the best results.

Try changing it to setInterval(changeQuote, 9000) and observe the difference.

However, considering scalability, there needs to be a way to ensure that the setInterval function waits until the quoteArray has completed pushing all the letters.

MODIFICATION

Based on the valuable feedback provided in the comments, I deduced the following:

  • From a JavaScript standpoint, each letter in the sequence is encapsulated within a <span> element, thus serving as individual entities. What was missing was the ability to group these letters into words to enable proper formatting according to their parent container.

In terms of CSS styling, the container housing the letters, known as quote, required specific styles to accurately represent its contents. By incorporating properties such as white-space: nowrap and display: block, I was able to provide a flexible container for its children to adjust based on screen width.

Refer to the corrected snippet below for further clarification.

var quotes = document.getElementsByClassName('quote'),
  quoteArray = [],
  currentQuote = 0;

quotes[currentQuote].style.opacity = 0;

for (var i = 0; i < quotes.length; i++) {
  splitLetters(quotes[i]);
}

function changeQuote() {
  var cw = quoteArray[currentQuote];
  var nw = currentQuote == quotes.length - 1 ? quoteArray[0] : quoteArray[currentQuote + 1];
  for (var i = 0; i < cw.length; i++) {
    animateLetterOut(cw, i);
  }
  for (var i = 0; i < nw.length; i++) {
    nw[i].className = 'letter behind';
    nw[0].parentElement.style.opacity = 1;
    animateLetterIn(nw, i);
  }

  currentQuote = (currentQuote == quoteArray.length - 1) ? 0 : currentQuote + 1;
}

function animateLetterOut(cw, i) {
  setTimeout(function() {
    cw[i].className = 'letter out';
  }, 0);
}

function animateLetterIn(nw, i) {
  setTimeout(function() {
    nw[i].className = 'letter in';
  }, 340 + (i * 30));
}

function splitLetters(quote) {
  var content = quote.innerHTML,
  words = [],
      word = document.createElement('span');
  
  word.className = "word";
  word.innerHTML = "";
  quote.innerHTML = "";
  
  for (var i = 0; i < content.length; i++) {
    var letter = document.createElement('span');
    letter.className = 'letter';
    
    if(content.charAt(i) !== " "){
    letter.innerHTML = content.charAt(i);
      word.innerHTML = word.innerHTML.concat(letter.innerHTML);
    }
    else {
    letter.innerHTML = "&nbsp";
      word.innerHTML = word.innerHTML.concat(letter.innerHTML);
      quote.appendChild(word);
      words.push(word);
      word = document.createElement('span');
      word.className = "word";
    }
  }

  quoteArray.push(words);
}
changeQuote();
setInterval(changeQuote, 10000);
body {
  font-weight: 600;
  font-size: 40px;
}

.text {
  position: relative;
}

.quote {
  position: absolute;
  display: block;
  opacity: 0;
  white-space: nowrap;
}

.letter {
  display: inline-block;
  position: relative;
  float: left;
  -webkit-transform: translateZ(25px);
  transform: translateZ(25px);
  -webkit-transform-origin: 50% 50% 25px;
  transform-origin: 50% 50% 25px;
}

.letter.out {
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s 0.7s, opacity 0.7s linear;
}

.letter.behind {
  visibility: hidden;
  opacity: 0;
}

.letter.in {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.7s linear;
}
<div class="text">
  <p>
    <span class="quote">TEXT ONE(1): For example, if you are designing a brand new website for someone, most times you will have to make sure the prototype looks finished by inserting text or photos or what have you. </span>
    <span class="quote">TEXT TWO(2): The purpose of this is so the person viewing the prototype has a chance to actually feel and understand the idea behind what you have created.</span>
  </p>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Dojo widgets in Xpages

I'm having trouble applying CSS to certain dojo elements within my Xpage. Here is the CSS style sheet I am using: .formFields { color: rgb(5, 56, 107); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: nor ...

Is there a way to extract data from the Redux state in a React component?

Seeking assistance with making an API request from Redux, followed by saving the data in my React state (arrdata). Although the API call is successful, I am facing challenges updating the App.js state based on the Redux API call. Any suggestions or insig ...

Obtaining localStream for muting microphone during SIP.js call reception

My approach to muting the microphone involves using a mediastream obtained through the sessionDescriptionHandler's userMedia event. session.sessionDescriptionHandler.on('userMedia', onUserMediaObtained.bind(this)) function onUserMediaObta ...

Access to the Express Node.js server is restricted to the machine that is currently hosting the server

I am facing a beginner issue with using express. I am on Ubuntu 14.04 and created a new directory where I ran "express" in the terminal to set up a project template. Following that, I ran "npm install" to install the dependencies. I then made changes to &a ...

Transform the MUI Typescript Autocomplete component to output singular values of a specific property rather than a complete object

When utilizing MUI Autocomplete, the generic value specified in onChange / value is determined by the interface of the object set in the options property. For instance, consider an autocomplete with the following setup: <Autocomplete options={top ...

Issue with Express.js and EJS application: The edit form fails to display the current category of the post

I've been developing a blogging application using Express, EJS, and MongoDB. You can check out the GitHub repository by clicking on the link. Within my application, I have separate collections for Posts and Post Categories. One issue I'm encoun ...

What could be causing my UI Bootstrap datepicker-popup to suddenly stop functioning?

After updating to UI Bootstrap 0.11.0, I encountered an issue where my datepickers were no longer appearing correctly. To demonstrate this problem, I have created a plunker which can be viewed here. Essentially, the code snippet causing the problem is as f ...

"Exploring the various configurations for session handling in NodeJs

I am trying to implement a login system using the express-session module. I'm unsure if I have set everything up correctly, especially when it comes to the secret option. Currently, my initialization code for express-session looks like this: app.use( ...

Tips for resolving the error "Cannot access the title property of undefined" when utilizing NextJS prerendering

I am preparing this page in advance for a specific post within my Next.js application: import Head from 'next/head'; import Link from 'next/link'; import client from '../../lib/apollo/client' import POSTS_WITH_SLUGS from &apos ...

I cannot locate the dropdown list anywhere

As a beginner in html and css, I decided to follow a tutorial on youtube. The tutorial focuses on creating a navigation bar with dropdown menus using html and css. I wanted the names Ria, Kezia, and Gelia to be displayed when hovering my mouse over the Su ...

Implementing closure within a recursive function allows for better control

One of my functions is designed to take a parameter and print the last number in the Fibonacci Series. For example, if the parameter is 3, it would return 2 as the series progresses like 1, 1, 2. function recursionFib(num){ if(num ...

"Exploring the Magic of Jquery's Fadein() Animation

i have experience with writing code for a jQuery fadein effect. imagine I have an HTML element stored in a variable, like this: var sHtml="<div>Other content</<div><div id='frm'>hello</<div>"; modal.load(jQuery(sHt ...

retrieving the webpage's HTML content from the specified URL using AngularJS

Utilizing the $http.get('url') method to fetch the content located at the specified 'url'. Below is the HTML code present in the 'url': <html> <head></head> <body> <pre style = "word-wrap: break ...

transfer the value of a method to a different component

In my Component called IncomeList, there is a method named sumValue. This method simply adds different numbers together to produce one value, for example 3+5 = 8. Similarly, in another Component named OutputList, the same logic is applied but with a method ...

Ways to address the problem of returning assignments

I encountered an issue while working on my code Error message: Arrow function should not return assignment no-return-assign The problematic code snippet is as follows: await DB.Place.find( match, // key to filter (err, doc) => (listOfObje ...

Adjust the font weight to bold for specific sections of the option value within a reactjs component

I have a component that generates a dropdown menu. I want to apply bold formatting to certain text within the dropdown values. Specifically, I need to make the ${dataIdText} text appear in bold within the dropdown menu. Here is a snippet of my code: < ...

Is there a way to access the rear camera on a mobile device using webcam.js?

Currently, I am utilizing webcam.js from the following link: https://github.com/jhuckaby/webcamjs. When accessing the website on mobile devices, the front camera tends to open by default. My objective is to switch this default setting to access the rear ...

Acquiring a property from an object that is specified within a function

I have created an object with properties inside a function: function createObject() { const obj = { property1: value, property2: value } } How can I access this object from outside the function? Would redefining it like ...

Struggling to decide on the perfect CSS selector for my puppeteer script

I am trying to use puppeteer page.type with a CSS selector. <div class="preloader"> <div class="cssload-speeding-wheel"></div> </div> <section id="wrapper" class="login-register"> <div class="login-box"> <d ...

Undefined scope

angular.module('CrudApp', []). config(['$routeProvider', function($routeProvider) { $routeProvider. when('/', { templateUrl: 'assets/tpl/lists.html', controller: ListCtrl }). when('/add-user&apos ...