文章目录
- 文字不断的在切换,确定的是有一个包含纯文字的数组,在此我们定义如下的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实现,但是离最开始的动画效果还差很远,接下来就是本文的重头戏。 在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); } 在线看效果:demo
- 整体代码就结束啦,最关键的代码就是最后的 svg 和 css filter 结合,有兴趣的同学可以研究一下其背后的原理。看完觉得有用,记得点赞收藏起来吧,说不定哪天就用上啦~ 专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)
今天分享一个炫酷的文本过渡动画效果,如下面GIF所示,曾经是否有见过这种动画呢,想想是不是感觉挺复杂呢,通常这个过渡效果通过较为复杂的可用WebGl实现,本文通过另一种方式实现,文章尾部有神奇的代码,快来瞧瞧看吧~,
,文字不断的在切换,确定的是有一个包含纯文字的数组,在此我们定义如下的html代码,后面通过交替显示其中一个span标签来达到动画的效果。,然后定义简单的CSS代码,通过定位的方式将两个span叠在一起。,此时我们的基本结构结构已经完成了,接下来开始动画的逻辑。两个文本之间的动画交替使用两个动画实现,
filter 和
opacity,通过计算一个 0 到 1 的函数更新两个文本元素
filter 和
opacity 的数值。,每执行一次动画结束后清空css中
filter 和
opacity数值。,最后就是初始化,基于
requestAnimationFrame创建动画保障动画的流畅。,这个时候的动画效果如下所示,是可以看到动画是基于我们设置的
filter 和
opacity实现,但是离最开始的动画效果还差很远,接下来就是本文的重头戏。
,在HTML中新增以下SVG代码,主要功能就是将足够高不透明的像素设置为完全不透明,剩余其他像素设置为完全透明。,再结合一段神奇的CSS代码即可完成我们最后的一步,动画效果就完成啦~,在线看效果:
demo,整体代码就结束啦,最关键的代码就是最后的
svg 和
css filter 结合,有兴趣的同学可以研究一下其背后的原理。看完觉得有用,记得点赞收藏起来吧,说不定哪天就用上啦~,专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe),
今天分享一个炫酷的文本过渡动画效果,如下面GIF所示,曾经是否有见过这种动画呢,想想是不是感觉挺复杂呢,通常这个过渡效果通过较为复杂的可用WebGl实现,本文通过另一种方式实现,文章尾部有神奇的代码,快来瞧瞧看吧~

文字不断的在切换,确定的是有一个包含纯文字的数组,在此我们定义如下的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实现,但是离最开始的动画效果还差很远,接下来就是本文的重头戏。 
在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);
}
在线看效果:demo
整体代码就结束啦,最关键的代码就是最后的 svg 和 css filter 结合,有兴趣的同学可以研究一下其背后的原理。看完觉得有用,记得点赞收藏起来吧,说不定哪天就用上啦~
专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)