用html写文本变形动画

html 复制代码
<!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>
css 复制代码
/* 引用文字 */
@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;
}
js 复制代码
/*
	巧妙地利用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(); 
相关推荐
腹黑天蝎座19 小时前
浅谈React19的破坏性更新
前端·react.js
东华帝君19 小时前
react组件常见的性能优化
前端
第七种黄昏19 小时前
【前端高频面试题】深入浏览器渲染原理:从输入 URL 到页面绘制的完整流程解析
前端·面试·职场和发展
angelQ19 小时前
前端fetch手动解析SSE消息体,字符串双引号去除不掉的问题定位
前端·javascript
Huangyi19 小时前
第一节:Flow的基础知识
android·前端·kotlin
林希_Rachel_傻希希19 小时前
JavaScript 解构赋值详解,一文通其意。
前端·javascript
Yeats_Liao19 小时前
Go Web 编程快速入门 02 - 认识 net/http 与 Handler 接口
前端·http·golang
金梦人生19 小时前
🔥Knife4j vs Swagger:Node.js 开发者的API文档革命!
前端·node.js
东华帝君19 小时前
react 虚拟滚动列表的实现 —— 固定高度
前端
Larcher19 小时前
n8n 入门笔记:用零代码工作流自动化重塑效率边界
前端·openai