Today, I will share a cool text transition animation effect, as shown in the GIF below. Have you ever seen this kind of animation? Think about it if it feels very complicated. Usually, this transition effect is achieved through the more complex available WebGl. Another way to achieve, there is a magical code at the end of the article, come and have a look~
Code
The text is constantly switching, and it is determined that there is an array containing plain text. Here we define the following html code, and then alternately display one of the span tags to achieve the animation effect.
<div id="container">
<span id="text1"></span>
<span id="text2"></span>
</div>
Then define simple CSS code to stack the two spans together by positioning.
#container {
position: absolute;
margin: auto;
width: 100vw;
height: 80pt;
top: 0;
bottom: 0;
}
#text1, #text2 {
position: absolute;
width: 100%;
display: inline-block;
font-size: 80pt;
text-align: center;
user-select: none;
}
At this point, our basic structure has been completed, and the logic of the animation is started. The animation between two texts is implemented alternately using two animations, filter
and opacity
, by calculating a 0 to 1 function to update the two text elements filter
and the value of opacity
.
// 控制动画速度
const morphTime = 1;
const cooldownTime = 0.25;
let morph = 0;
let cooldown = cooldownTime;
function doMorph() {
morph -= cooldown;
cooldown = 0;
let fraction = morph / morphTime;
if (fraction > 1) {
cooldown = cooldownTime;
fraction = 1;
}
setMorph(fraction);
}
function setMorph(fraction) {
text2.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`;
text2.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`;
fraction = 1 - fraction;
text1.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`;
text1.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`;
}
After each execution of the animation, clear the filter
and opacity
values in the CSS.
function doCooldown() {
morph = 0;
elts.text2.style.filter = "";
elts.text2.style.opacity = "100%";
elts.text1.style.filter = "";
elts.text1.style.opacity = "0%";
}
The last is initialization, based on requestAnimationFrame
to create animation to ensure the smoothness of animation.
function animate() {
requestAnimationFrame(animate);
let newTime = new Date();
let shouldIncrementIndex = cooldown > 0;
let dt = (newTime - time) / 1000;
time = newTime;
cooldown -= dt;
if (cooldown <= 0) {
if (shouldIncrementIndex) {
textIndex++;
}
doMorph();
} else {
doCooldown();
}
}
The animation effect at this time is as follows. It can be seen that the animation is based on our settings filter
and opacity
implemented, but it is still far from the initial animation effect. That's the crux of this article.
Add the following SVG code to the HTML. The main function is to set the opaque pixels high enough to be completely opaque, and the remaining pixels to be completely transparent.
<svg id="filters">
<defs>
<filter id="threshold">
<feColorMatrix in="SourceGraphic"
type="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 255 -140" />
</filter>
</defs>
</svg>
Combined with a magical CSS code to complete our final step, the animation effect is complete~
#container {
...
filter: url(#threshold) blur(0.6px);
}
See the effect online: demo
At last
The overall code is over. The most critical code is the combination of the last svg
and css filter
. Interested students can study the principle behind it. After reading it, you find it useful, remember to like and save it, maybe you will use it someday~
Focus on front-end development, share dry goods related to front-end technology, public account: Nancheng Front-end (ID: nanchengfe)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。