css动画
动画的原理:
- 视觉暂留作用
- 画面逐渐变化
动画的作用
- 愉悦感
- 因其作用
- 操作进行反馈
- 掩饰(程序在后台加载)
动画类型
- transition补间动画(中间的过程浏览器脑补起来)
- keyframe关键帧动画(也是补间动画,但是有很多关键帧)
- 逐帧动画
transition(补间动画)
transition 属性设置元素当过渡效果,是一个复合属性,包括四个简写属性:
- transition-property:指定CSS属性的name,transition效果(默认值:all)
- transition-duration(必须):过渡效果持续时间(不指定默认为0,不会有任何效果)
- transition-timing-function:指定过渡效果的转速曲线(默认值:ease)
- transition-delay:指定过渡延迟开始时间(默认为0)
/* 复合写法 */
/*transition: property duration timing-function delay;*/
.container{
width: 100px;
height: 100px;
background: red;
/* 复合属性 */
transition:width 1s ease 2s ,background 3s;
/* transition: all 1s; */
/* 采用以下分属性也是可以的 */
/*transition-duration: 2s;
transition-property: all;
transition-timing-function: ease;
transition-delay: 0s;*/
}
.container:hover{
width: 800px;
background:green;
}
transition-timing-function属性指的是过渡的“缓动函数”,用来指定属性过渡时动画运动形式,值可以是关键字、贝塞尔曲线(bezier),默认值为ease 关键字:linear| ease| ease-in| ease-out| ease-in-out| 贝塞尔:cubic-bezier(n,n,n,n);
- ease:开始和结束慢,中间快
- linear:匀速
- ease-in:开始慢,越来越快
- ease-out:结束慢,越来越慢
- ease-in-out:先加速后减速,与ease类似,但比ease幅度大
- cubic-bezier(n,n,n,n)贝塞尔曲线中4个值随意调整,就会得到不同的效果
.tra{
width: 50px;
height: 50px;
display: block;
background-color: lightcoral;
transition: 1s cubic-bezier(.75,2.03,0,.14);
}
.tra:hover{
border-radius: 50%;
background-color: blue;
}
事件回调:transition属性只有一个事件,那就是transitionend事件,它在过渡事件完成后触发
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#test{
height: 60px;
width: 60px;
background-color: lightpink;
transition: width 1.5s;
font-size: 12px;
}
#test:hover{
width: 250px;
}
</style>
</head>
<body>
<div id="test"></div>
</body>
<script>
//监听 transitionend 事件
test.addEventListener("transitionend", myFunction);
// 回调函数
function myFunction(e){
e = e || event;
test.innerHTML = "过渡结束,执行事件回调内容"
}
</script>
</html>
keyframes动画
- 相当于多个补间动画
- 与元素状态的变化无关
- 定义更加灵活
.container{
width: 100px;
height: 100px;
background: red;
animation: run 1s linear;
/* animation-direction: reverse; */
/* animation-fill-mode: forwards; */
animation-iteration-count: infinite;
/* animation-play-state: paused; */
}
@keyframes run{
0%{
width: 100px;
}
50%{
width: 800px;
}
100%{
width: 100px;
}
}
- 先定义动画
- 在调用定义好的动画
div {
/* 调用动画 */
animation-name: 动画名称;
/* 持续时间 */
animation-duration: 持续时间;
}
@keyframes 动画名称 {
0% {
width: 100px;
}
100% {
width: 200px
}
}
div {
width: 100px;
height: 100px;
background-color: aquamarine;
/* 动画名称 */
animation-name: move;
/* 持续时间 */
animation-duration: 4s;
/* 动画速度曲线 */
animation-timing-function: ease;
/* 动画开始时间 */
animation-delay: 1s;
/* 动画播放次数 */
/* animation-iteration-count: 2; */
/* 动画播放方向 */
/* animation-direction: alternate; */
/* 动画结束后状态 */
animation-fill-mode: forwards;
/* 复合属性 */
/* animation: 动画名称 持续时间 运动曲线 何时开始 播放次数 是否反方向 起始与结束状态 */
animation: name duration timing-function delay iteration-count direction fill-mode
简写里面不包含 animation-paly-state 暂停动画 animation-paly-state: paused; 经常和鼠标经过等其他配合使用
svg 动画(CSS)(keyframes动画)
环形进度条
<div>
<svg width="440" height="440" viewbox="0 0 440 440">
<circle cx="220" cy="220" r="170" stroke-width="50" stroke="#D1D3D7" fill="none"></circle>
<circle
class="circle"
cx="220"
cy="220"
r="170"
stroke-width="50"
stroke="#00A5E0"
fill="none"
transform="matrix(0,-1,1,0,0,440)"
/>
</svg>
</div
<style>
.circle {
animation: circle 5s linear infinite;
}
@keyframes circle {
from {
stroke-dasharray: 0 1069;
}
to {
stroke-dasharray: 1069 0;
}
}
</style>
LOGO 描边
const path = document.getElementById('logo')
const pathLen = path.getTotalLength()
<style>
.logo-path {
fill: none;
stroke: #333;
stroke-width: 1;
animation: taobao 5s linear infinite forwards;
}
@keyframes taobao {
from {
stroke-dasharray: 6885;
stroke-dashoffset: 6885;
}
to {
stroke-dasharray: 6885;
stroke-dashoffset: 0;
}
}
</style>
### 逐帧动画
- 每帧都是关键帧,中间没有补间过程
- 依然使用关键帧动画
- 属于关键帧动画中的一种特殊情况
- 适用于无法补间计算的动画
- 资源较大
- 使用steps()
```js
animation-timing-function:steps(1);
//中间不要加东西,每个区间就只有一个状态
step是指定每个区间帧数
问题
CSS中动画实现的方式有几种
- transition
- keyframes(animation)
过渡动画和关键帧动画的区别
- 过度动画需要有状态变化,关键帧动画不需要有状态变化
- 关键帧动画能控制更精细
CSS动画的性能
- 性能不坏
- 部分情况下优于JS
- 但JS可以做到更好
- 部分高危属性,box-shadow等
svg 动画(SMIL)
SMIL 全称 Synchronized Multimedia Integration Language,它允许我们通过 HTML 标签实现动画效果,它可以用于:
- 实现过渡动画
- 实现补间动画
- 动画颜色变换
- 路径运动动画(CSS3无法实现)
SMIL 包含以下标签:
<set>
<animate>
<animateColor>
<animateTransform>
<animateMotion>
set 标签
实现属性的延迟设置
<svg width="400" height="400">
<rect x="0" y="0" width="100" height="100" fill="red">
<set attributeName="x" attributeType="XML" to="10" begin="1s" />
<set attributeName="x" attributeType="XML" to="20" begin="2s" />
<set attributeName="x" attributeType="XML" to="30" begin="3s" />
<set attributeName="x" attributeType="XML" to="40" begin="4s" />
<set attributeName="x" attributeType="XML" to="50" begin="5s" />
</rect>
</svg>
animation 标签
移动的小球
<svg width="500" height="200" viewBox="0 0 500 200">
<circle cx="0" cy="0" r="30" fill="blue" stroke="black" stroke-width="1">
<animate attributeName="cx" from="0" to="200" dur="5s" repeatCount="indefinite" />
<animate attributeName="cy" from="0" to="200" dur="5s" repeatCount="indefinite" />
</circle>
</svg>
形状补间动画
<svg width="400" height="400">
<polygon points="30 30 70 30 90 70 10 70" fill="#fcc" stroke="black">
<animate attributeName="points" attributeType="XML" to="50 30 70 50 50 90 30 50" dur="5s" fill="freeze" repeatCount="1" />
</polygon>
</svg>
animateMotion 标签
按 path 轨迹运动的正方形
<svg width="200" height="200" viewBox="0 0 200 200">
<rect x="0" y="0" width="10" height="10" fill="red">
<animateMotion
path="M 10 10 L 110 10 L 110 110 L 10 110 Z"
dur="5s"
rotate="auto"
fill="freeze"
repeatCount="indefinite"
/>
</rect>
<path id="motion-path" d="M 10 10 L 110 10 L 110 110 L 10 110 Z" fill="none" stroke="green" />
</svg>
混合动画
<svg viewBox="0 0 200 200" width="200" height="200">
<rect x="0" y="0" rx="0" ry="0" width="10" height="10" fill="red">
<animateMotion
id="forward-rect"
path="M 10 10 L 110 10 L 110 110 L 10 110"
dur="2s"
rotate="0"
fill="freeze"
begin="0; backward-rect.end + 0.5s"
/>
<animateMotion
id="backward-rect"
path="M 10 110 L 110 110 L 110 10 L 10 10"
dur="2s"
rotate="0"
fill="freeze"
begin="forward-rect.end + 0.5s"
/>
<animate
id="red-to-blue"
attributeType="XML"
attributeName="fill"
begin="0; blue-to-red.end + 1s"
from="red"
to="blue"
dur="2s"
fill="freeze"
/>
<animate
id="blue-to-red"
attributeType="XML"
attributeName="fill"
begin="red-to-blue.end + 1s"
from="blue"
to="red"
dur="2s"
fill="freeze"
/>
</rect>
<path d="M 10 10 L 110 10 L 110 110 L 10 110" fill="none" stroke-width="1" stroke="blue"/>
</svg>
点击变色或位移
<svg viewBox="0 0 200 200" width="200" height="200">
<g id="rect1">
<rect x="0" y="0" rx="0" ry="0" width="100" height="100" fill="red">
<animate
attributeType="XML"
attributeName="fill"
from="red"
to="green"
begin="rect1.click"
dur="2s"
fill="freeze"
/>
</rect>
</g>
<animateTransform
attributeType="XML"
attributeName="transform"
type="translate"
from="0, 0"
to="50, 50"
begin="rect1.click"
dur="2s"
fill="freeze"
/>
<rect x="0" y="100" width="100" height="100" fill="blue">
<animate
attributeType="XML"
attributeName="fill"
from="blue"
to="green"
begin="rect1.click"
dur="2s"
fill="freeze"
/>
</rect>
</svg>
Loading 效果
<div style="width:200px;height:200px">
<svg viewBox="0 0 50 50">
<circle
cx="25"
cy="25"
r="22"
fill="none"
stroke-width="3"
stroke="#3be6cb"
stroke-dasharray="34"
stroke-linecap="round"
>
<animateTransform
attributeName="transform"
type="rotate"
from="0 25 25"
to="360 25 25"
dur="2s"
repeatCount="indefinite"
/>
<animate
attributeName="stroke"
values="#3be6cb;#02bcfe;#3be6cb"
dur="4s"
repeatCount="indefinite"
/>
</circle>
<circle
cx="25"
cy="25"
r="12"
fill="none"
stroke-width="3"
stroke="#02bcfe"
stroke-dasharray="18.85"
stroke-linecap="round"
>
<animateTransform
attributeName="transform"
type="rotate"
values="360 25 25;0 25 25"
dur="2s"
repeatCount="indefinite"
/>
<animate
attributeName="stroke"
values="#02bcfe;#3be6cb;#02bcfe"
dur="4s"
repeatCount="indefinite"
/>
</circle>
</svg>
</div>
流星轨迹边框效果
<div style="width:400px;height:400px;background-color:#333">
<svg viewBox="0 0 400 400">
<defs>
<path
id="fly-box-path"
d="M5 5 L395 5 L395 395 L5 395 Z"
fill="none"
/>
<radialGradient
id="radial-gradient"
cx="50%"
cy="50%"
fx="100%"
fy="50%"
r="50%"
>
<stop offset="0%" stop-color="#fff" stop-opacity="1"></stop>
<stop offset="100%" stop-color="#fff" stop-opacity="0"></stop>
</radialGradient>
<mask id="fly-box-mask1">
<circle r="100" cx="0" cy="0" fill="white">
<animateMotion
dur="3s"
path="M5 5 L395 5 L395 395 L5 395 Z"
rotate="auto"
repeatCount="indefinite"
/>
</circle>
</mask>
</defs>
<use
href="#fly-box-path"
stroke-width="1"
stroke="#235fa7"
/>
<use
href="#fly-box-path"
stroke-width="3"
stroke="#4fd2dd"
mask="url(#fly-box-mask1)"
/>
</svg>
</div>