Here's a fun animation problem. Let's say you have a paragraph of text and
you put it inside a <div />
. The browser internally builds your DOM tree and
then renders it onto your screen as a web page. Now, Suppose you're trying
to animate a paragraph where each line has a slightly different animation.
How would you achieve it? Give it a shot at thinking!
If you're me, Your first idea would be to split your single paragraph element into multiple line elements similar to what browser does internally. Now you've reached the problem. How do you know the final dimensions before the text is even rendered by the browser? Well! You can't. There isn't a DOM API exposed by the browser for you to query this information before render. So! How do you solve it now?
Here's the hack.
- You create a
<canvas />
and give it the same font size & style as your rest of the application font. - You now grab your paragraph and split it into words.
- You can then use canvas context's
measureText
to measure each word. Now! You know the length of each word in pixels. - You'll now craft your lines. You get either get the
width
of original text rendered by DOM or you arbitrarily set a maximumwidth
your lines could take. You then divide this by 2 (an assumption; you'll have to play around to find your sweet spot. I found dividing by 2 onclientHeight
to do the thing). - You can now,
- Add
i'th
word to a temporary string. - Add
i'th
word'swidth
to a temporary number. This number starts at 0. - Check if your temporary number has hit your assumed container
width
from 4. If you hit it, push the temporary string as a new line and set your temporary number back to 0. - Repeat! Until you reach the last word.
- You'll end up with an array that has your desired lines formed off a paragraph.
- You can them map and animate them anyway you want.
This isn't a perfect solution since it relies on assumption (divide by 2) but it approximately mimics the original browser render.
update.
Instead of stepping between desktop and client width at the breakpoint. We can also linearly interpolate between them. I was able to fix the above issue where the content shifts to new line thereby making the paragraph look odd. This makes the animation responsive. I've also updated the code to be much more readable!
Happy Hacking! :3