likes
comments
collection
share

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

作者站长头像
站长
· 阅读数 51

炫酷的效果背后所蕴含的往往是最深刻的编程思想和应用场景。

就像下面这个文字的跃动效果,你有没有实现思路呢?

大家好,我是渡一前端子辰老师,今天再来挑战一下你的编程能力吧

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

这种排列不仅适用与文字,任何元素的排列都可以把它做成更加丰富的形式。

我们来看一下这是怎么做的。

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

设计思路

完成这个效果,我们需要用到 JS 的函数来控制每个文字元素的位置和偏移量。

如果我们用 CSS 来做,就需要为每个文字元素单独设置样式,这样非常麻烦,而且如果文字内容发生变化,CSS 还得重新写。

我们首先思考第一个问题,就是你怎么告诉 JS,你要排列成什么样子。

这里就要捡一捡我们之前学过的曲线函数了:

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

比如这个曲线看上去是不是很眼熟?像不像正弦函数,一个正弦函数的曲线不就是这个样子吗。

那我们把曲线函数告诉 JS,然后再告诉 JS 一个截取范围,就是横坐标的取值范围:

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

还有没有别的要告诉 JS 呢?我们看图,截取范围是一个连续平滑的曲线,曲线上的点却是无限的。

但是我们排列的文字是有限的,那怎么办?

只能告诉 JS 点的数量了,比如我们告诉 JS 有 11 个点,那么这些点就应该在截取的范围内均匀排列:

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

现在我们告诉 JS 三个东西,还有什么东西呢?我们继续看。

图上的 x y 坐标它的值是在竖轴上的 x y 的坐标,而不是我们在页面呈现上的坐标系,所以说呢,我们要把它应用到页面上去的时候,在计算这个坐标点的时候,还要对它进行相应的缩放,比如说你的取值范围是 0 ~ 10,而页面上呢整个元素排列出来有 100 个像素,是不是 x 和 y 坐标都要放大 10 倍。

所以一共要告诉 JS 四个东西,函数本身以及取值范围和点的个数,还有整个排列元素的总宽度。

只要告诉 JS 这四个东西,是不是就可以把每一个点的 y 坐标给它算出来,y 坐标就是元素的偏移量,那剩下的事情就是去实现这个 JS 函数了。

这个函数子辰已经提前实现了。

首先我们定义一个 getCurvePoints 函数,它接受四个参数:

  • curveFunc 表示曲线函数;
  • range 表示取值范围;
  • number 表示点的数量;
  • xLength 表示 x 的长度。

然后它返回一个数组,表示每个点在 y 轴上的偏移量:

/**
 * 创建一个曲线,得到曲线上的均分散列点
 * @param {(number)=>number} curveFunc:曲线函数
 * @param {[number, number]} range:取值范围
 * @param {number} number:点的数量
 * @param {number} xLength:x 的长度
 * @returns
 */
function getCurvePoints(curveFunc, range, number, xLength) {
  if (number < 1) {
    return [];
  }
  if (number === 1) {
    return [0];
  }
  const piece = (range[1] - range[0]) / (number - 1);
  const result = [];
  const scale = xLength / (range[1] - range[0]);
  for (let i = 0; i < number; i++) {
    result.push(-curveFunc(i * piece + range[0]) * scale);
  }
  return result;
}

函数代码也没几行,函数一共接收四个参数,就是我们刚才说的四个参数了,这个函数就能帮我们计算出每一个点的 y 坐标了,也就是偏移量。

这个函数有兴趣的同学可以自己写一下,非常的简单,也可以拿子辰的代码去参考一下。

代码实现

我们在控制台中直接使用一下 getCurvePoints 函数并传入参数,看看效果:

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

可以看到 getCurvePoints 函数给我们返回了 20 个点的纵向坐标了,到时候把元素按照这个纵坐标去排列,是不是就可以了。

我们去具体写一下。

// 首先拿到我们整个的容器
const container = document.querySelector(".container");
// 目前我们的容器里都是文字,所以我们要将每一个文字拆开,生成一个元素
// 并覆盖掉原来的内容
container.innerHTML = container.textContent
  .split("")
  .map((l) => `<span>${l}</span>`)
  .join("");

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

可以看到目前我们的容器里所有的文字,都变成了 span 元素,我们的第一步完成了。

接下来就是设置每一个 span 元素的位置了:

const container = document.querySelector(".container");
container.innerHTML = container.textContent
  .split("")
  .map((l) => `<span>${l}</span>`)
  .join("");
// 写一个函数用来对 getCurvePoints 函数进行进一步的封装
/**
 * @param {(number)=>number} func:曲线函数
 * @param {[number, number]} range:取值范围
 */
function createCurve(func, range) {
  // 在这里调用 getCurvePoints 函数,把曲线函数和取值范围传进去
  // 多少个点就是 container 有多少个子元素 container.children.length,
  // 第四个参数也就是 container 的宽度 container.clientWidth
  // 这样子就得到了所有的点
  const points = getCurvePoints(func, range, container.children.length, container.clientWidth);
  // 循环每一个元素
  for (let i = 0; i < points.length; i++) {
    // 找到对应的子元素,改变子元素的 y 偏移量
    container.children[i].style.transform = `translateY(${points[i]}px)`;
  }
}
createCurve((x) => Math.sin(x), [0, 2 * Math.PI]);

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

可以看到效果已经出来了。

这种写法灵活度非常高,它不像 CSS 是写死的,无论你里边是什么样的文字都无所谓,它都能正常的排列。

因为灵活度很高,所以我们还可以去改动它的取值范围,来实现滚动效果。

// 定一个偏移量
let offset = 0;
createCurve((x) => Math.sin(x), [offset, offset + 2 * Math.PI]);
setInterval(() => {
  // 每间隔一段时间改变偏移量
  offset += 0.1;
  createCurve((x) => Math.sin(x), [offset, offset + 2 * Math.PI]);
}, 30);

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

可以看到动画已经实现了,是不是很简单?

带你实现花式的文字跃动与曲线效果,可不要掉队哦!

总结

我们做效果的时候要首先要把这个东西想通,你打算怎么做,怎么做逻辑是通的,然后再去具体实现代码,好的思考是避坑的前提,也是效率的前提,更是我们未来发展的前提。

这是一个很好的编程练习,也是一个很有用的技巧。

在未来的开发中,类似这样的文字排列效果会经常用到,特别是在需要给网页增加一些动态和个性的场景下,比如制作一个个人主页、一个博客、一个广告等等。

文章所实现的文字排列不仅仅是一个看起来很酷的效果,它背后所蕴含的是深刻的编程思想和应用场景。

本文来源

本文来源自渡一官方公众号:Duing,欢迎关注,获取最新、最全、最深入的技术讲解

感谢你阅读本文,如果你有任何疑问或建议,请在评论区留言,如果你觉得这篇文章有用,请点赞收藏或分享给你的朋友!

转载自:https://juejin.cn/post/7249386837369028663
评论
请登录