0

I'm using Anime.js to do some animation on a site I am building. Right now I am trying to animate a string of a few words.

I have the animation working and everything with Anime.js is working fine. The problem I am having is that I want to store the words I am animating in my React component's state like this:

this.state = {
      heading: "Hudson Valley Web Design"
    }

As you can see my heading consists of several words with spaces. I implement the Anime.js effects by iterating over this.state.heading like this:

<h1 className="ml9">
          <span className="text-wrapper">
            {Object.values(this.state.heading).map((letter) => {
              // This regular expression that checks for spaces isn't 
              // working
              if(letter === /\s/g.test(letter)) {
                return <span className="letters">" "</span>
              }
              return (
                <span className="letters">{letter}</span>
              );
            })}
          </span>
        </h1>

The effect works properly but all the words are squished together i.e. "HudsonValleyWebDesign". How can I detect white spaces in this.state.heading inside my Object.keys function and put spaces between each word?

Also, for clarification, I need the individual letters to be in span tags for the sake of applying the CSS for the Anime.js functionality.

4
  • I don't use Anime, but shouldn't " " be &nbsp; or so? Commented Jan 12, 2019 at 19:56
  • If I'm understanding correctly you want to split the original string into words so they can be animated, and at the end of the animation, the original string is rendered? If so, you don't really need regex - you can use var splitHeading = this.state.heading.split(" ") which returns [ 'Hudson', 'Valley', 'Web', 'Design' ]. Map the new var and return <span className="letters">{letter + " "}</span> Commented Jan 12, 2019 at 19:59
  • @stever That's correct. It's unclear why it's shown as HudsonValleyWebDesign. I assume the behaviour that the OP describes is specific to Anime lib. Commented Jan 12, 2019 at 20:02
  • <span className="letters">{letter + " "}</span> ? Commented Jan 12, 2019 at 20:03

2 Answers 2

1

You can use "split" to have a CHAR array from your string, and then loop through it, char by char, like:

<h1 className="ml9">
          <span className="text-wrapper">
            {Object.values(this.state.heading.split('')).map((letter) => {
              // just check if the letter is space 
              if(letter === " ") {
                return <span className="letters">" "</span>
              }
              return (
                <span className="letters">{letter}</span>
              );
            })}
          </span>
        </h1>

** NOTE: .split('') gives you an array like : (including spaces as an element)

["H", "u", "d", "s", "o", "n", " ", "v", "a", "l", "l", "e", "y", .......]

Sign up to request clarification or add additional context in comments.

4 Comments

This worked for me. The only change was I had to use &nbsp; in the span in place of " ". The quotations were being displayed. Thanks for the help. This definitely didn't require regex, I was overthinking it.
Object.values is not needed at all.
@estus My solution used Object.values to return the exact same thing as the above in just one line but I'm now curious as to how you would go about this. Can you post an answer or forked my CodePen above? Cheers.
@AndrewL It's either Object.values(this.state.heading) or this.state.heading.split(''). Both convert a string to an array of chars. The use of both at the same time is redundant.
1

The white-space is a string character too so you can return the white-space character just as you would with the other string characters like this:

{Object.values(this.state.heading).map(letter => {
  return <span className="letters">{letter}</span> 
})}

You can check this CodePen or run the Code Snippet below to see how the above code returns Hudson Valley Web Design with each letter and white-space inside the .letters <span> tag.

class App extends React.Component{
    constructor(props){
        super(props);
        
        this.state = {
            heading: "Hudson Valley Web Design"
        }
    }
    render() {
        return (
            <div>
                <h1 className="ml9">
                    <span className="text-wrapper">
                        {Object.values(this.state.heading).map(letter => {
                           return <span className="letters">{letter}</span> 
                        })}
                    </span>
                </h1>
            </div>
        )
    }
}
      
ReactDOM.render(<App />, document.getElementById('main'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="main"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.