前端动画
一、css动画
transition
过渡
transition:transiton-property,transition-duration,transition-timing-function,transition-delay
相关属性说明
属性 | 默认值 | 其他说明 |
---|---|---|
property过渡的属性 | all | 不是所有css属性都支持过渡 |
duration动画完成时间 | 0s | 单位是秒 |
timing-function | ease | linear ease ease-in ease-out step-start step-end |
delay动画开始时间 | 0s | 出发过渡后多久开始实现过渡 |
.transition-box {width: 100px;height: 200px;background-color: pink;transition: all 1s ease 1s;
}.transition-box:hover {width: 150px;background-color: skyblue;
}
transition的优点在于简单易用,但是它有几个很大的局限。
(1)transition需要事件触发,所以没法在网页加载时自动发生。
(2)transition是一次性的,不能重复发生,除非一再触发。
(3)transition只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态。
(4)一条transition规则,只能定义一个属性的变化,不能涉及多个属性。
transition需要明确知道,开始状态和结束状态的具体数值,才能计算出中间状态。transition没法算出0px到auto的中间状态,也就是说,如果开始或结束的设置是height: auto,max-height等,那么就不会产生动画效果。类似的情况还有,display: none到block
animation
属性 | 说明 | 其他 |
---|---|---|
animation-name | 动画名 | |
animation-duration | 动画执行一次的时长 | 可以时秒也可以毫秒,但是必须带单位 |
animation-timing-function | 动画执行在不同阶段的快慢 | linear/ease…… |
animation-delay | 延迟多久开始 | |
animation-iteration-count | 动画执行的次数 | 可以是小数 |
animatioin-derection | 动画播放方向 | normal循环播放时每次都是正向/reverse正到反再到正/alternat正反交替e/alternate-reverse |
animation-fill-mode | 动画在执行之前和之后如何将样式应用于其目标 | |
animation-play-state | paused/running 动画是暂停还是播放 | 恢复暂停的动画将从暂停时停止的位置开始播放,而不是从动画序列的开头重新开始播放 |
transform
只能转换由和模型定位的元素
属性 | 说明 | |
---|---|---|
translate(10,20) | 往x轴(右)平移10px,往y轴(下)平移20px | |
scale(1.5) | 放大1.5倍 | |
rotate(90deg) | 旋转90度 | |
skew | 倾斜 | |
translate3d | ||
scale3d | ||
rotate3d | ||
perspective | 设置视角 |
transform-origin:元素变形的起点
默认值是元素的中心
它的值的类型可以值百分比、px、center/left/right/top/bottom这些
二、js动画
setTimeout()、setInterval()
可以通过setTimeout、setInterval修改元素的css位置信息,修改canvas画出来的东西等
js配合canvas实现动画:
<canvas id="canvas" width="300" height="300"></canvas>
地球公转动画:
const sun = new Image();const earth = new Image();function init() {sun.src = "./img/sun.jpg";earth.src = "./img/eartH.jpg";}function draw() {const ctx = document.getElementById("canvas").getContext("2d");ctx.globalCompositeOperation = "destination-over";ctx.clearRect(0, 0, 300, 300); // 清除画布ctx.save();ctx.translate(150, 150);// 地球const time = new Date();ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() +((2 * Math.PI) / 60000) * time.getMilliseconds());ctx.translate(105, 0);ctx.fillRect(0, -12, 40, 24); // 阴影ctx.drawImage(earth, -12, -12);ctx.restore();ctx.beginPath();ctx.arc(150, 150, 105, 0, Math.PI * 2, false); // 地球轨道ctx.stroke();ctx.drawImage(sun, 0, 0, 300, 300);}init();setInterval(() => {draw();}, 300);
requestAnimationFrame()
**作用:**告诉浏览器你要执行动画,浏览器在下一次重绘之前调用你传入的回调函数来更新动画
回调函数执行次数通常是每秒 60 次,但在大多数遵循 W3C 建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配
调用一次requestAnimationFrame()只会执行一次回调,若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调requestAnimationFrame()
语法:
requestAnimationFrame(callback)
参数callback:
当你的动画需要更新时,为下一次重绘所调用的函数;该函数会传入一个参数,参数代表该函数开始执行的时刻
返回值:
一个 long
整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义;每执行一次就加1
window.cancelAnimationFrame()
终止动画,终止执行
requestAnimationFrame(callback)
动画应用
实现假进度条
loadFakeProgress() {// let preTime = 0;let timer = 0;const vm = this;function timerFun(timestamp) {if (vm.percentage === 100) {cancelAnimationFrame(timerFun);return;}// if (timestamp - preTime < 2000) {// requestAnimationFrame(timerFun);// return;// }// preTime = timestamp;timer = Math.round((timer + 0.01) * 100) / 100;let per = vm.percentage + Math.ceil(Math.random() * 10);requestAnimationFrame(timerFun);// 1》进度条达到了百分之90,不会更新进度条// 2》减慢进度条变化速度;每次调用timer都会增加0.01,就是调用了一百次动画回调才会更新一次// timestamp - preTime和timer都可以控制进度条变化一次的时间;if (per >= 90 || timer % 1 !== 0) {return;}// if (per >= 90) {// return;// }vm.percentage = per < 85 ? per : 99;}requestAnimationFrame(timerFun);}
requestAnimationFrame做动画相比比定时器的优势
定时器动画可能会出现卡顿,而requestAnimationFrame比较稳定、顺畅
定时器为什么卡顿:普通显示器刷新频率是60Hz,一秒钟刷新60次,也就是十多毫秒刷新一次,也就是如果动画能动卡在约17毫秒执行一次,就不会卡顿;但是定时器是一个异步任务,它受到其他宏任务和微任务的影响,比如某次执行时中间前面有大量微任务导致到了17秒后并没有执行,到了刷新,整个动画没变,经过很多次刷新,整个过程动画可能出现一会变,一会不变,就会出现抖动
而requestAnimationFrame的回调函数能够在浏览器下一次重回之前执行,所以不会出现卡顿,更顺畅
svg动画
元素
attributeName:变量属性的属性名
from:变动的初始值
to:结束值
dur:动画持续的时间
<svg width="300" height="100"><title>Attribute Animation with SMIL</title><rect x="0" y="0" width="300" height="100" stroke="black" stroke-width="1" /><circle cx="0" cy="50" r="15" fill="blue" stroke="black" stroke-width="1"><animateattributeName="cx"from="0"to="500"dur="5s"repeatCount="indefinite" /></circle>
</svg>
元素
用于变动 transform 属性
<svg width="300" height="100"><title>SVG SMIL Animate with transform</title><rect x="0" y="0" width="300" height="100" stroke="black" stroke-width="1" /><rectx="0"y="50"width="15"height="34"fill="blue"stroke="black"stroke-width="1"><animateTransformattributeName="transform"begin="0s"dur="20s"type="rotate"from="0 60 60"to="360 100 60"repeatCount="indefinite" /></rect>
</svg>