CSS 炫酷文本过渡动画-HTML实例论坛-子比插件商城

CSS 炫酷文本过渡动画

今天分享一个炫酷的文本过渡动画效果,如下面GIF所示,曾经是否有见过这种动画呢,想想是不是感觉挺复杂呢,通常这个过渡效果通过较为复杂的可用WebGl实现,本文通过另一种方式实现,文章尾部有神奇的代码,快来瞧瞧看吧~

图片[1]-CSS 炫酷文本过渡动画-HTML实例论坛-子比插件商城

代码实现

文字不断的在切换,确定的是有一个包含纯文字的数组,在此我们定义如下的html代码,后面通过交替显示其中一个span标签来达到动画的效果。

<div id="container">
  <span id="text1"></span>
  <span id="text2"></span>
</div>

然后定义简单的CSS代码,通过定位的方式将两个span叠在一起。

#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;
}

此时我们的基本结构结构已经完成了,接下来开始动画的逻辑。两个文本之间的动画交替使用两个动画实现,filter 和 opacity,通过计算一个 0 到 1 的函数更新两个文本元素 filter 和 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}%`;
 
}

每执行一次动画结束后清空css中filter 和 opacity数值。

function doCooldown() {
 morph = 0;
 
 elts.text2.style.filter = "";
 elts.text2.style.opacity = "100%";
 
 elts.text1.style.filter = "";
 elts.text1.style.opacity = "0%";
}

最后就是初始化,基于requestAnimationFrame创建动画保障动画的流畅。

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();
 }
}

这个时候的动画效果如下所示,是可以看到动画是基于我们设置的filter 和 opacity实现,但是离最开始的动画效果还差很远,接下来就是本文的重头戏。

图片[2]-CSS 炫酷文本过渡动画-HTML实例论坛-子比插件商城

在HTML中新增以下SVG代码,主要功能就是将足够高不透明的像素设置为完全不透明,剩余其他像素设置为完全透明。

<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>

再结合一段神奇的CSS代码即可完成我们最后的一步,动画效果就完成啦~

#container {
 ...
 filter: url(#threshold) blur(0.6px);
}

最后

整体代码就结束啦,最关键的代码就是最后的 svg 和 css filter 结合,有兴趣的同学可以研究一下其背后的原理。看完觉得有用,记得点赞收藏起来吧,说不定哪天就用上啦~

请登录后发表评论