我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!
前言
之前在b站没少看到会动的爱心的特效,类似于
但是这些很明显是写死的一个动画效果,不够灵活,所以今天我们来把它抽成配置,让你一键生成一个会跳动的爱心
实现
实现过程
首先就是利用css的动画来进行变换,这些在b站的教程里面有很多,我在这里就不从头讲起,我们先实现一个会跳动的心,然后慢慢的把参数都抽成配置
思路
首先既然是抽配置,那么就要考虑这个页面有什么最基本的公司构成,首先页面由一个大的盒子以及里面多个竖着排放的元素组成,并且竖着排放的元素会随着时间伸缩,那么首先我们就需要把这些元素抽出来,让用户能够去自定义这些元素,有几个竖着摆放的元素,元素伸长后的长度是多少,伸长之后元素的偏移量,元素的颜色,等等,这些都是可以抽成配置的,那么我们首先就是想到用一个数组来表示这个配置。
lineList: [
{ length: 60, offset: -30, backgroundColor: 'red', delay: 0.2 },
{ length: 125, offset: -60, backgroundColor: 'darkturquoise', delay: 0.4 },
{ length: 160, offset: -75, backgroundColor: 'darksalmon', delay: 0.6 },
{ length: 180, offset: -60, backgroundColor: 'deeppink', delay: 0.8 },
{ length: 200, offset: -45, backgroundColor: 'yellow', delay: 1 },
{ length: 180, offset: -60, backgroundColor: 'deeppink', delay: 1.2 },
{ length: 160, offset: -75, backgroundColor: 'darksalmon', delay: 1.4 },
{ length: 125, offset: -60, backgroundColor: 'darkturquoise', delay: 1.6 },
{ length: 60, offset: -30, backgroundColor: 'red', delay: 1.8 },
]
上面这个就是我们按照能够抽成配置的元素抽取出来的一个数组,生成的图案也和文章最开始的爱心是完全相同的。
动画的生成
那么既然能够拿到配置,我们就要用这个配置,来生成对应的元素以及样式。
首先是我们要解决的就是动画的问题,因为每一个元素的动画都可以是不一样的,展示我们可以支持用户配置长方体伸长后的长度以及上下的偏移量,那么我们就要帮他把这两个值拼凑起来生成一个动画。
那么首先我们就要考虑,我们怎么利用js去修改css的动画呢?
通过百度得知,只需要把动画属性按照字符串额方式拼接完整,然后作为一个 style 元素的 innerHTML 添加到页面的 head 元素当中去就ok了。那么我们就能够写出下面这个方法,通过一个key 和 一些其他参数,去生成我们想要的动画并且进入页面的 head 中。
/**
* key String 需要新增的动画key
* styleArr Array<Object> 需要新增的动画
* time Array<string> || String 单个或者多个动画时间
* style String css 动画
**/
addKeyframes(key, styleArr) {
let runkeyframe = "";
styleArr.forEach((item) => {
if (typeof item.time === "string") {
runkeyframe += `${item.time}${item.style}`;
} else if (Array.isArray(item.time)) {
let times = item.time.reduce((a, b) => a + "," + b);
runkeyframe += `${times}${item.style}`;
}
});
const runkeyframes = ` @keyframes ${key}{${runkeyframe}}`;
// 创建style标签
const style = document.createElement("style");
// 设置style属性
style.type = "text/css";
// 将 keyframes样式写入style内
style.innerHTML = runkeyframes;
// 将style样式存放到head标签
document.getElementsByTagName("head")[0].appendChild(style);
}
并且因为我们需要的动画中只有最长长度和偏移量是可以改变的,其他都是不变的,那么我们可以在抽取一个函数,单独将这两个可以改变的变量暴露出来。
setAnimation(i, length, offset) {
this.addKeyframes(`rhythm${i}`, [
{
time: ["30%", "50%"],
style: `{
height: ${length}px;
transform: translateY(${offset}px);
}`,
},
{
time: ["70%", "100%"],
style: `{
height: 20px;
transform: translateY(0px);
}`,
},
]);
}
那么到这里动画的生成就搞定了,我们只要把用户传入的参数传入这个函数,就可以自动生成对应的动画。
元素的创建
在有了动画之后,我们就要来为页面创建元素,这没什么好说的,通过用户给出的列表的长度,创建相应个数的元素,然后统一加入一个盒子当中。
并且在每一个元素创建的时候我们需要为它添加配置信息,
data.forEach((item, i) => {
let node = document.createElement("div");
node.className = `rhythm${i + 1}`;
node.style.animation = `rhythm${i + 1} 5s ${item.delay || 0}s infinite`;
node.style.backgroundColor = item.backgroundColor || this.defaultBg[i];
this.setAnimation(i + 1, item.length, item.offset);
box.appendChild(node);
});
分别就是元素的类名,动画,背景颜色,等等参数,最后统一加入一个元素下面。
结果
通过上面两步,其实这个类的一个基础大概功能已经都实现的,剩余的都是一些补充,比如说我实现了一个随机背景色的函数,并且按照用户传入的数组的长度,会对应的生成 'ABCDCBA' 这种形式的背景色来作为用户没有传入背景色时的默认值。
将一些都放入一个类当中,并且在创建实例的时候传入必要参数,我们就能够拿到一串会跳舞的线。
并且当线的长度为20的时候,那么展示的形式就会是一个点,利用这个点,以及多个类的实例进行重合,我们还能够画出很多很有意思的动图。
总结
本文主要是将一个新的伸缩案例抽取变成能够支持参数配置的类,并且用这个类还能够实现很多很有意思的动态图案,这些就交给接下去对它感兴趣的读者了。