头图

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)


南城FE
2.2k 声望574 粉丝