“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情”
前言
Granim是什么?Granim是一个流体动画库,那么流体动画又是什么?流体动画就是渐变色不断地移动,我们看一个案例就知道了:
我们想要做一个流体动画按钮,有三种方式:
- 设计师制作lottie文件,前端直接播放
- 设计师制作GIF播放
- 前端用css模拟流体动画或者用canvas绘制动画
但是如果设计师不愿意做的话,我们只能自己想办法,用css模拟流体动画性能较好,但是代码成本很高,调试效果成本也很高,所以使用现成的动画库可能更符合我们的需求,那么我们就找到了Granimjs(怎么找到的Granimjs我们在文章最后揭晓)
Granimjs
官网效果很炫酷:sarcadass.github.io/granim.js/
官方文档:sarcadass.github.io/granim.js/a…
基础用法:
var granimInstance = new Granim({
element: '#root',
states : {
"default-state": {
gradients: [
['#834d9b', '#d04ed6'],
['#1CD8D2', '#93EDC7']
],
transitionSpeed: 5000,
loop: true
}
}
);
如果想像背景图一样写渐变色可以这样写,将之前的颜色字符串变为一个对象,这个对象里面有一个pos代表从上一个pos到这个pos是当前这个颜色
gradients:
[
[
{ color: 'rgba(255, 153, 102, .33)', pos: .5 },
{ color: '#ff5e62', pos: 1 }, ...
], [
{ color: 'hsla(144, 100%, 47%, .75)', pos: .1 },
{ color: 'hsl(210, 96%, 46%)', pos: .6 }, ...
],
...
]
下面我们用Granim实现一个小需求
需求1:hover按钮时做动画
我们先实现一个小需求,这里有一个按钮,还有一块画布,我们现在需要hover按钮的时候让画布动起来
hover
对应的事件是onmouseenter
和onmouseleave
,那么我们就在按钮触发onmouseenter
时初始化一个Granim
对象:
<button onmouseenter="startGranim(this)">按钮</button>
<canvas id="root"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/granim/2.0.0/granim.min.js"></script>
<script>
window.onload = function () {
var granimInstance;
const root = document.getElementById('root')
window.startGranim = () => {
granimInstance = new Granim({
element: root,
states: {
"default-state": {
gradients: [
["#834d9b", "#d04ed6"],
["#1CD8D2", "#93EDC7"],
],
transitionSpeed: 5000,
loop: true,
},
},
});
};
};
</script>
效果如下:
这样的话我们还需要处理鼠标离开事件,我们知道hover
时状态会进行一个切换,当离开之后状态立马回归到原始状态了,所以我们在鼠标离开时需要将动画销毁,其实也就是清除画布,这里我们有一个API可以直接调用
window.destroyGranim = () => {
granimInstance.destroy();
};
紧接着我们想把这个动画效果添加到当前按钮身上去,这就是我们的需求2
需求2:将动画效果应用到按钮上
我们先稍微美化一下我们的按钮:
<style>
.box{
position: relative;
width: 140px;
height: 50px;
line-height: 50px;
text-align: center;
background-image: linear-gradient(90deg,#834d9b,#d04ed6);
color: white;
font-size: 16px;
border-radius: 8px;
overflow: hidden;
}
.box span{
position: relative;
z-index: 1;
}
canvas{
position: absolute;
left: 0;
top: 0;
width: 140px;
height: 50px;
}
</style>
<div class="box" onmouseenter="startGranim(this)" onmouseleave="destroyGranim()">
<span>hover出现动画</span>
<canvas id="root"></canvas>
</div>
美化之后效果如图:
还是按照刚才的脚本来写,我们就可以得到一个拥有hover流体动画超能力
的按钮,但是这还不够我们需要把这个按钮抽象为一个组件,以便在所有页面都能够使用到这个按钮
需求3:在React中抽象按钮组件
由于组件可能被多处复用,那么借助id获取元素的方式就不能使用了,所以我们需要借助React的ref来获取Dom元素,由于我们整个项目可能需要保持风格的一致性,所以对于动画的参数我们没有进行props传递:
后记
至此我们的流体动画告一段落,我们利用Granimjs实现了一个具备流体动效的按钮组件,但是请思考一下,如果我们不知道有Granimjs能够实现这个功能,我们想破头皮可能也做不出来,虽然网上有使用css去模拟流体动画的案例,但是那些都很差强人意
我在实践的过程中就是70%的时间在于寻找一款能够符合需求的动画库,而30%的时间用在了写代码上面;怎么样才能节省这个搜索的时间?
我们经常能够看到掘金上面有一些合集,当看到动画库合集时我们需要把它收藏起来让他吃灰,说不定有朝一日它就起了大作用