1、translate
正常矩形 <svg width="500" height="200" viewBox="0 0 500 200">
<rect x="0" y="0" width="100" height="50" fill="red" />
</svg>
右移10px
<svg width="500" height="200" viewBox="0 0 500 200">
<rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,0)" />
</svg>
左右各移10px
<svg width="500" height="200" viewBox="0 0 500 200">
<rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10)" />
</svg>
2、rotate
旋转 <svg width="500" height="200" viewBox="0 0 500 200">
<rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10) rotate(30)" />
</svg>
3、skewX(30)倾斜
沿X轴倾斜30度<svg width="500" height="200" viewBox="0 0 500 200">
<rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10) skewX(30)" />
</svg>
4、skewY
沿Y轴倾斜30度 <svg width="500" height="200" viewBox="0 0 500 200">
<rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10) skewY(30)" />
</svg>
5、scale放大缩小
正常缩小为原来一半
<svg width="500" height="200" viewBox="0 0 500 200">
<rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10) scale(.5)" />
</svg>
6、matrix复杂变形
正常形状复杂变形后
<!--
[2,-1,50] => 2*_x+(-1)*_y+50 = x
[1,2,0] =>1*_x+2*_y+0=y
顶点坐标
[0,0] => [50,0]
[100,0] => [250,100]
[100,50] => [200,200]
[0,50] => [0,100]
-->
<svg width="500" height="200" viewBox="0 0 500 200">
<rect x="0" y="0" width="100" height="50" fill="red" transform="matrix(2 1 -1 2 50 0)" />
</svg>
7、环形进度条
stroke-dasharray的用法
<template>
<div>
<div class="container">
<!--
[2,-1,50] => 2*_x+(-1)*_y+50 = x
[1,2,0] =>1*_x+2*_y+0=y
顶点坐标
[0,0] => [50,0]
[100,0] => [250,100]
[100,50] => [200,200]
[0,50] => [0,100]
-->
<svg width="500" height="200" viewBox="0 0 500 200">
<rect
class="rect"
x="0"
y="0"
width="100"
height="50"
fill="none"
stroke="blue"
stroke-width="5" />
</svg>
</div>
<div class="container">
<svg
width="400"
height="400">
<circle cx="200" cy="200" r="180" stroke-width="20" stroke="#d1d3d7" fill="none"></circle>
<circle
class="circle"
cx="200"
cy="200"
r="180"
stroke-width="20"
stroke="#00a5e0"
fill="none"></circle>
</svg>
</div>
</div>
</template>
<script setup>
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
}
.rect{
stroke-dasharray:10 20 30;
}
.circle{
stroke-dasharray:10 1131;
}
</style>
环形动态进度条
<template>
<div>
<div class="container">
<svg width="500" height="200" viewBox="0 0 500 200">
<rect
class="rect"
x="0"
y="0"
width="100"
height="50"
fill="none"
stroke="blue"
stroke-width="5" />
</svg>
</div>
<div class="container">
<svg
width="400"
height="400">
<circle cx="200" cy="200" r="180" stroke-width="20" stroke="#d1d3d7" fill="none"></circle>
<circle
class="circle"
cx="200"
cy="200"
r="180"
stroke-width="20"
stroke="#00a5e0"
fill="none"></circle>
</svg>
</div>
</div>
</template>
<script setup>
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
}
.rect{
stroke-dasharray:10 20 30;
}
.circle{
animation:circle 5s linear infinite;
}
@keyframes circle{
from {
stroke-dasharray:0 1131;
}
to {
stroke-dasharray: 1131 0;
}
}
</style>
如果想让起点旋转到正上方,可任意取三点,根据计算公式解出一元三次方程,
[2,-1,50] => 2*_x+(-1)*_y+50 = x
[1,2,0] =>1*_x+2*_y+0=y
得出
transform="matrix(0 -1 1 0 0 400)"
8、矩形动态进度条
rect动态进度条.gif<template>
<div>
<div class="container">
<svg width="500" height="200" viewBox="0 0 500 200">
<rect
class="rect"
x="0"
y="0"
width="100"
height="50"
fill="none"
stroke="blue"
stroke-width="5" />
</svg>
</div>
<div class="container">
<svg
width="400"
height="400"
viewBox="0 0 400 400"
>
<circle cx="200" cy="200" r="180" stroke-width="20" stroke="#d1d3d7" fill="none"></circle>
<circle
class="circle"
cx="200"
cy="200"
r="180"
stroke-width="20"
stroke="#00a5e0"
fill="none"
transform="matrix(0 -1 1 0 0 400)"
></circle>
</svg>
</div>
<div class="container">
<svg
width="200"
height="200"
viewBox="0 0 200 200"
>
<rect x="0" y="0" width="200" height="200" stroke-width="8" stroke="grey" fill="none"></rect>
<rect x="0" y="0" width="200" height="200" stroke-width="8" stroke="blue" fill="none" class="rect-process" transform="matrix(0,1,-1,0,200,0)"></rect>
</svg>
</div>
</div>
</template>
<script setup>
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
}
.rect{
stroke-dasharray:10 20 30;
}
.circle{
animation:circle 5s linear infinite;
}
@keyframes circle{
from {
stroke-dasharray:0 1131;
}
to {
stroke-dasharray: 1131 0;
}
}
.rect-process{
animation:rect-process 5s linear infinite;
}
@keyframes rect-process{
from {
stroke-dasharray:0 800;
}
to {
stroke-dasharray:800 0;
}
}
</style>
9、描边动画
(1)、矩形描边
rect描边.gif
<div class="container">
<svg class="line-container" width="400" height="400" viewBox="0 0 400 400">
<line class="line" x1="0" y1="50" x2="400" y2="50" fill="none" stroke-width="20" stroke="red"/>
</svg>
</div>
.container{
border:1px solid #000;
width:400px;
}
.line {
stroke-dasharray:400;
stroke-dashoffset:400;
transition:stroke-dashoffset .5s ease-out;
}
.line-container:hover .line{
stroke-dashoffset:0;
}
(2)、心形描边
获取path长度
const path = documet.getElementById('logo')
const pathLen = path.getTotalLength()
心描边定长.gif
<div class="container">
<svg t="1630632068637" viewBox="0 0 1024 1024" p-id="1844" width="64" height="64">
<path class="logo" d="M629.28 200.192a213.056 213.056 0 0 0-111.616 37.28l-5.696 4.032-5.696-4.032a212.704 212.704 0 0 0-120.32-37.472c-120.8 0-217.952 101.568-217.952 225.376 0 59.872 16.768 97.856 56.32 157.216 30.144 45.248 79.104 95.392 140.416 148.48l16.8 14.368 16.32 13.6 15.552 12.64 21.312 16.864 12.48 9.6 10.784 8.064a90.656 90.656 0 0 0 108.256-0.224l15.36-11.52 12.032-9.344 13.216-10.464 14.144-11.456 14.912-12.32 15.424-13.056 7.872-6.72c61.312-53.12 110.272-103.264 140.416-148.48 39.648-59.456 56.384-97.344 56.384-157.248-0.096-123.84-97.28-225.376-218.048-225.376l-8.64 0.192zM637.952 256c89.28 0 161.984 75.968 162.048 169.376 0 45.856-17.664 80.448-35.584 108.8l-7.68 11.744-3.712 5.632c-14.88 22.304-35.232 45.92-57.632 68.992l-12.384 12.48-12.672 12.352-6.4 6.08-12.832 11.904-19.168 17.152-12.48 10.88-18.08 15.36-27.2 22.24-21.824 17.216-19.552 14.88c-11.264 8.384-26.24 9.152-38.176 2.272l-4.128-2.752-18.912-14.4-21.824-17.216-21.44-17.44-11.68-9.76-18.368-15.744-19.008-16.864-12.864-11.744a1183.712 1183.712 0 0 1-6.4-6.016l-12.768-12.192-12.544-12.416c-22.72-22.944-43.744-46.624-59.584-69.152l-4.16-6.112a1241.6 1241.6 0 0 1-7.552-11.392l-7.68-12.16C239.264 500.864 224 467.968 224 425.376 224 331.936 296.64 256 385.984 256c49.6 0 95.648 23.776 125.984 62.976C542.304 279.776 588.384 256 637.952 256z" p-id="1845"></path>
</svg>
</div>
.logo{
fill:none;
stroke:#333;
stroke-width:10;
animation:logos 5s linear forwards;
}
@keyframes logos{
0% {
stroke:#333;
fill:white;
stroke-dasharray:3812;
stroke-dashoffset:3812;
}
50%{
stroke:#333;
fill:white;
stroke-dasharray:3812;
stroke-dashoffset:0;
}
75%{
stroke:#aaa;
fill:red;
}
100%{
stroke:#aaa;
fill:blue;
}
}
10、SMIL动画
全称:Synchronized Multimedia Integration Language。通过HTML标签实现动画效果,可以用于:
- 实现过渡动画
- 实现补间动画
- 动画颜色变换
- 路径运动动画
包含以下标签:
<set>
<animate>
<animateColor>
<animateTransform>
<animateMotion>
(1)、set用法
<template>
<div>
<div class="container">
<svg width="200" height="200">
<rect x="0" y="0" fill="red" width="100" height="50">
<set attributeName="x" attributeType="XML" to="10" begin="1s"></set>
<set attributeName="x" attributeType="XML" to="20" begin="2s"></set>
<set attributeName="fill" attributeType="XML" to="blue" begin="3s"></set>
</rect>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
(2)、animate的用法
<template>
<div>
<div class="container">
<svg width="200" height="200">
<circle cx="0" cy="0" r="30" fill="blue" stroke="black" stroke-width="2">
<animate attributeName="cx" attributeType="XML" from="0" to="100" dur="2s" repeatCount="indefinite"></animate>
</circle>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
attributeType
的值有XML
和css
,后者的话标识所操作属性从css中获取
fill
的值有freeze
表示动画停留在截止时状态。remove
动画结束时回归原位。
SMILanimate叠加.gif动画可叠加
<template>
<div>
<div class="container">
<svg width="200" height="200">
<circle cx="0" cy="0" r="30" fill="blue" stroke="black" stroke-width="2">
<animate attributeName="cx" attributeType="XML" from="0" to="100" dur="2s" repeatCount="1" fill="freeze"></animate>
<animate attributeName="cy" attributeType="XML" from="0" to="50" dur="2s" repeatCount="1" fill="freeze"></animate>
</circle>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
匪夷所思的补间动画
<template>
<div>
<div class="container">
<svg width="400" height="400">
<polygon fill="#fcc" stroke="black">
<animate attributeName="points" attributeType="XML" from="30 30 70 30 90 70 10 70" to="50 30 70 50 50 90 30 50" dur="2s" repeatCount="1" fill="freeze"></animate>
</polygon>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
(3)、animationColor
animationColor已经很少使用(废弃状态),可以使用animate替换
<animate attributeName="fill" from="red" to="blue" dur="5s" repeatCount="indefinite"></animate>
(4)、animateTransform
<template>
<div>
<div class="container">
<svg width="200" height="200">
<circle cx="0" cy="0" r="30" fill="blue" stroke="black" stroke-width="2">
<animateTransform attributeName="transform" attributeType="XML" begin="0" dur="2s" type="scale" from="1" to="2" repeatCount="1" fill="freeze"></animateTransform>
</circle>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
(5)、animateMotion
<template>
<div>
<div class="container">
<svg width="200" height="200">
<rect x="0" y="0" fill="red" width="10" height="10">
<animateMotion
path="M10 10 L110 10 L110 110 L10 110 Z"
dur="5s"
rotate="auto"
fill="freeze"
repeatCount="1"
/>
</rect>
<path d="M10 10 L110 10 L110 110 L10 110 Z" fill="none" stroke="green"></path>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
rotate值改为0,在转弯处就不会抖动
归程动画
<template>
<div>
<div class="container">
<svg width="200" height="200">
<rect x="00" y="0" fill="red" width="10" height="10">
<animateMotion
id="forward"
path="M10 10 L110 10 L110 110 L10 110"
dur="5s"
rotate="0"
fill="freeze"
begin="0"
/>
<animateMotion
id="backward"
path="M10 110 L110 110 L110 10 L10 10"
dur="5s"
rotate="0"
fill="freeze"
begin="forward.end"
/>
</rect>
<path d="M10 10 L110 10 L110 110 L10 110" fill="none" stroke="green"></path>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
复合归程动画
<template>
<div>
<div class="container">
<svg width="200" height="200">
<rect x="00" y="0" fill="red" width="10" height="10">
<animateMotion
id="forward"
path="M10 10 L110 10 L110 110 L10 110"
dur="5s"
rotate="0"
fill="freeze"
begin="0;backward.end+0.5s"
/>
<animateMotion
id="backward"
path="M10 110 L110 110 L110 10 L10 10"
dur="5s"
rotate="0"
fill="freeze"
begin="forward.end + 0.5s"
/>
<animate
id="red-to-blue"
attributeName="fill"
attributeType="XML"
from="red"
to="blue"
dur="5s"
begin="0;backward.end+0.5s"
fill="freeze"
/>
<animate
id="blue-to-red"
attributeName="fill"
attributeType="XML"
from="blue"
to="red"
dur="5s"
begin="red-to-blue.end+0.5s"
fill="freeze"
/>
</rect>
<path d="M10 10 L110 10 L110 110 L10 110" fill="none" stroke="green"></path>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
复杂动画
<template>
<div>
<div class="container">
<svg width="200" height="200" viewBox="0 0 200 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"
></animate>
</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"
fill="freeze"
></animate>
</rect>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
})
</script>
<style type="text/css" scoped>
.container{
border:1px solid #000;
width:200px;
}
</style>
网友评论