前言
在前端我们写动画基本都是使用css的过渡属性或者动画属性,再或者使用一些库比如:animation.css
、gsap
。直到最近才知道,原来web早就提供了Animation API
,可以通过js
的方式来实现动画。
Animation API
的属性、方法及兼容性见:Web Animation
基本用法
文档里提供的是使用构造函数的方式(没太看懂),除了文档里的方式,还有一种更简单的方式
const element = document.querySelector('.animate');
const webAnimation = element.animate(keyframes, options);
keyframes
关键帧,通常是一个对象数组,每个对象都是关键帧的样式,比如:
let runList = [
{
transform: 'translateX(0) rotate(0deg)'
},
{
transform: 'translateX(300px) rotate(360deg)'
},
{
transform: 'translateX(0) rotate(0deg)'
},
]
默认情况下,第一个是起始相当于css中的0%
,最后一个相当于结束100%
,中间那个是50%
。
大体的计算方式就是100/(个数-1)
当然也可以像css那样自定义关键帧,可以借助offset
属性来实现,比如10%
{
transform: 'translateX(300px) rotate(360deg)', offset: 0.1
},
options
.animate() 函数的 options 属性值有两种用法
第一种使用方式是直接传入一个 duration,单位是毫秒,表示动画在该时间内完成
element.animate([
{ opacity: 1 },
{ opacity: 0 }
], 1000);
第二种方式是完整的对象
const options = {
// 动画执行次数
iterations: Infinity,
// 动画开始时间点
iterationStart: 0,
// 动画开始之前的延迟
delay: 0,
// 动画结束之后的延迟
endDelay: 0,
// 动画是否在下一周期逆向播放
direction: 'alternate',
// 动画时长
duration: 1000,
// 动画前后保持的状态
fill: 'forwards',
// 动画缓动类型
easing: 'ease-in-out',
}
element.animate(keyframes, options);
常用方法
play(): 播放动画
pause(): 暂停动画
finsh(): 终止动画
cancel(): 清除动画所有的关键帧,并停止动画
reverse(): 反转播放动画,直到播放到动画开始时停止。 如果动画完成或未播放,它将从头到尾播放
兼容性
IE不支持,其他浏览器如果版本过低也不支持。具体见:Web API Animation
Demo
<template>
<div>
<el-button type="primary" @click="start">开始</el-button>
<el-button type="primary" @click="pause">暂停</el-button>
<div class="container">
<div class="ball" id="ball"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
//小球的动画对象
let ballAnimation = ref()
//数组中的元素代表动画的状态
let runList = [
{
transform: 'translateX(0) rotate(0deg)'
},
{
transform: 'translateX(300px) rotate(360deg)'
},
{
transform: 'translateX(0) rotate(0deg)'
},
]
onMounted(() => {
let ball = document.getElementById('ball')
//给小球添加动画
//查一下有哪些属性
ballAnimation.value = ball?.animate(runList, {
duration: 4000,
fill: 'forwards'
})
//开始时设置为暂停状态
ballAnimation.value.pause()
})
//开始
let start = () => {
ballAnimation.value.play()
}
//暂停
let pause = () => {
ballAnimation.value.pause()
}
</script>
<style lang="scss" scoped>
.container {
width: 400px;
height: 120px;
margin-top: 50px;
margin-left: 800px;
border: 1px solid blue;
}
.ball {
width: 100px;
height: 100px;
margin-top: 20px;
background-color: #4158d0;
background-image: linear-gradient(43deg, #4158d0 0%, #c850c0 46%, #ffcc70 100%);
border-radius: 50%;
}
</style>
效果