前端动画
一、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">
<animate
attributeName="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" />
<rect
x="0"
y="50"
width="15"
height="34"
fill="blue"
stroke="black"
stroke-width="1">
<animateTransform
attributeName="transform"
begin="0s"
dur="20s"
type="rotate"
from="0 60 60"
to="360 100 60"
repeatCount="indefinite" />
</rect>
</svg>