赞
踩
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文本变形动画</title> <link rel="stylesheet" href="./style.css"> </head> <body> <!-- 两个文本部分 --> <div id="container"> <span id="text1"></span> <span id="text2"></span> </div> <!-- 用于创建合并效果的 svg 过滤器 --> <svg id="filter"> <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> <!-- partial --> <script src="./script.js"></script> </body> </html>
/* 引用文字 */ @import url('https://fonts.googleapis.com/css?family=Raleway:900&display=swap'); body { margin: 0px; } #container { /* 将文本在视口里居中 */ position: absolute; margin: auto; width: 100vw; height: 80pt; top: 0; bottom: 0; /* 这个过滤器很神奇哦~可以试着注释一下,看变形是如何工作的~ */ filter: url(#threshold) blur(0.6px); } #text1, #text2 { position: absolute; width: 100%; display: inline-block; font-family: 'Raleway', sans-serif; font-size: 80pt; text-align: center; user-select: none; }
/* 巧妙地利用SVG过滤器来创建“变形文本”效果。 从本质上讲,它将两个文本元素层叠在一起,并根据哪个文本应该更突出来模糊它们。 一旦应用了模糊,两个文本一起通过一个阈值过滤器,产生“胶粘”效果。 */ const elts = { text1: document.getElementById("text1"), text2: document.getElementById("text2") }; /* 要在其中变形的字符串。你可以把这些换成你想要的任何东西! */ const texts = [ "Can", "I", "have", "one", "click", "triple?" ]; /* 控制变形的速度。 */ const morphTime = 1; const cooldownTime = 0.25; let textIndex = texts.length - 1; let time = new Date(); let morph = 0; let cooldown = cooldownTime; elts.text1.textContent = texts[textIndex % texts.length]; elts.text2.textContent = texts[(textIndex + 1) % texts.length]; function doMorph() { morph -= cooldown; cooldown = 0; let fraction = morph / morphTime; if (fraction > 1) { cooldown = cooldownTime; fraction = 1; } setMorph(fraction); } /* 将模糊过滤器应用于文本 */ function setMorph(fraction) { // fraction = Math.cos(fraction * Math.PI) / -2 + .5; elts.text2.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`; elts.text2.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`; fraction = 1 - fraction; elts.text1.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`; elts.text1.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`; elts.text1.textContent = texts[textIndex % texts.length]; elts.text2.textContent = texts[(textIndex + 1) % texts.length]; } function doCooldown() { morph = 0; elts.text2.style.filter = ""; elts.text2.style.opacity = "100%"; elts.text1.style.filter = ""; elts.text1.style.opacity = "0%"; } /* 动画循环 */ 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(); } } /* 启动动画。 */ animate();
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。