第8章 渐变
8.1 linearGradient元素
从一个颜色平滑地过渡到另一个颜色,渐变可以是线性的,即沿着直线过度,也可以是径向的,从中心点向外辐射过渡。
在<defs>中定义,然后在后面把它们作为填充或描边来引用。
使用<linearGradient>元素来定义线性渐变。
<svg width="660" height="220">
<defs>
<linearGradient id="linear" >
<stop offset="0%" stop-color="#05a"/>
<stop offset="100%" stop-color="#0a5"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="600" height="200" fill="url(#linear)" />
</svg>
蓝色->绿色
<stop>元素有两个必要属性,offset和stop-color。offset用于确定哪个点颜色等于stop-color,offset使用 0%-100%或者 0-1表示
<svg width="660" height="220">
<defs>
<linearGradient id="linear" >
<stop offset="0%" stop-color="#05a"/>
<stop offset="50%" stop-color="red"/>
<stop offset="100%" stop-color="#0a5"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="600" height="200" fill="url(#linear)" />
</svg>
<svg width="660" height="220">
<defs>
<linearGradient id="linear" >
<stop offset="0%" stop-color="#05a" stop-opacity="1.0"/>
<stop offset="50%" stop-color="red" stop-opacity="0.5"/>
<stop offset="100%" stop-color="#0a5" stop-opacity="0.3"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="600" height="200" fill="url(#linear)" />
</svg>
定义线性渐变的方向
默认沿着水平线从左到右过渡,如果想要指定过渡方向,使用 x1 x2 y1 y2 指定渐变的起点和终点,由0%-100%或者 0-1表示。
<svg width="250px" height="250px" viewBox="0 0 250 250">
<defs>
<linearGradient id="three_stops">
<stop offset="0%" style="stop-color: #ffcc00;"/>
<stop offset="33.3%" style="stop-color: #cc6699"/>
<stop offset="100%" style="stop-color: #66cc99;"/>
</linearGradient>
<linearGradient id="transition"
xlink:href="#three_stops"
x1="0%" y1="0%" x2="100%" y2="0%"/>
</defs>
<rect x="10" y="10" width="200" height="200"
style="fill: url(#transition); stroke: black;"/>
</svg>
<svg width="250px" height="250px" viewBox="0 0 250 250">
<defs>
<linearGradient id="three_stops">
<stop offset="0%" style="stop-color: #ffcc00;"/>
<stop offset="33.3%" style="stop-color: #cc6699"/>
<stop offset="100%" style="stop-color: #66cc99;"/>
</linearGradient>
<linearGradient id="transition"
xlink:href="#three_stops"
x1="100%" y1="0%" x2="0%" y2="0%"/>
</defs>
<rect x="10" y="10" width="200" height="200"
style="fill: url(#transition); stroke: black;"/>
</svg>
<svg width="250px" height="250px" viewBox="0 0 250 250">
<defs>
<linearGradient id="three_stops">
<stop offset="0%" style="stop-color: #ffcc00;"/>
<stop offset="33.3%" style="stop-color: #cc6699"/>
<stop offset="100%" style="stop-color: #66cc99;"/>
</linearGradient>
<linearGradient id="transition"
xlink:href="#three_stops"
x1="0%" y1="0%" x2="0%" y2="100%"/>
</defs>
<rect x="10" y="10" width="200" height="200"
style="fill: url(#transition); stroke: black;"/>
</svg>
<svg width="250px" height="250px" viewBox="0 0 250 250">
<defs>
<linearGradient id="three_stops">
<stop offset="0%" style="stop-color: #ffcc00;"/>
<stop offset="33.3%" style="stop-color: #cc6699"/>
<stop offset="100%" style="stop-color: #66cc99;"/>
</linearGradient>
<linearGradient id="transition"
xlink:href="#three_stops"
x1="0%" y1="0%" x2="100%" y2="100%"/>
</defs>
<rect x="10" y="10" width="200" height="200"
style="fill: url(#transition); stroke: black;"/>
</svg>
spreadMethod属性
过度方向不一定是从对象的一角到另一角,我们可以指定从(20% 80%)到(40% 80%)渐变,可以通过spreadMethod属性来改变显示内容
pad:起始和结束渐变点会扩散到对象边缘
<svg width="250" height="250" viewBox="0 0 250 200">
<defs>
<linearGradient id="partial"
x1="20%" y1="30%" x2="40%" y2="80%"
spreadMethod="pad">
<stop offset="0%" style="stop-color: #ffcc00;"/>
<stop offset="33.3%" style="stop-color: #cc6699"/>
<stop offset="100%" style="stop-color: #66cc99;"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="200" height="200"
style="fill: url(#partial); stroke: black;"/>
</svg>
repeat:渐变会重复起点到终点的过程,直到充满整个对象
<svg width="250" height="250" viewBox="0 0 250 200">
<defs>
<linearGradient id="partial"
x1="20%" y1="30%" x2="40%" y2="80%"
spreadMethod="repeat">
<stop offset="0%" style="stop-color: #ffcc00;"/>
<stop offset="33.3%" style="stop-color: #cc6699"/>
<stop offset="100%" style="stop-color: #66cc99;"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="200" height="200"
style="fill: url(#partial); stroke: black;"/>
</svg>
reflect:渐变会重复终点到起点,起点到终点的过程,直到充满整个对象
<svg width="250" height="250" viewBox="0 0 250 200">
<defs>
<linearGradient id="partial"
x1="20%" y1="30%" x2="40%" y2="80%"
spreadMethod="reflect">
<stop offset="0%" style="stop-color: #ffcc00;"/>
<stop offset="33.3%" style="stop-color: #cc6699"/>
<stop offset="100%" style="stop-color: #66cc99;"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="200" height="200"
style="fill: url(#partial); stroke: black;"/>
</svg>
8.2 radialGradient元素
<svg width="150" height="150">
<defs>
<radialGradient id="linear" >
<stop offset="0%" stop-color="red"/>
<stop offset="33.3%" stop-color="blue"/>
<stop offset="100%" stop-color="pink"/>
</radialGradient >
</defs>
<rect x="10" y="10" width="150" height="150" fill="url(#linear)" />
</svg>
径向渐变的范围由一个圆确定,其中,中心店是0%,外圆周为100%,使用cx cy和r定义外圆,这些属性的值为外边框的百分比,默认值为50%
<svg width="150" height="150">
<defs>
<radialGradient id="linear" cx="0%" cy="0%" r="100%">
<stop offset="0%" stop-color="red"/>
<stop offset="33.3%" stop-color="blue"/>
<stop offset="100%" stop-color="pink"/>
</radialGradient >
</defs>
<rect x="10" y="10" width="150" height="150" fill="url(#linear)" />
</svg>
第九章 文本
9.1 <text>基本属性
最简单的情况是只给 x和y,指定第一个字符的基线位置。
font-family
font-size
font-weight
font-style
text-decoration
9.2 文本对齐
<text>元素指定了起始点,但是我们无法知道终点,让文本对齐变的困难,我们可以使用text-anchor属性来指定文本生效的位置,值为 start middle end
<svg width="250px" height="600px" viewBox="0 0 250 60">
<g style="font-size: 12pt;">
<path d="M 125 10 125 600"
style="stroke: gray; fill: none;"/>
<text x="125" y="30" style="text-anchor: middle">
Sample Text
</text>
<text x="125" y="60" style="text-anchor: start">
Sample Text
</text>
<text x="125" y="90" style="text-anchor: end">
Sample Text
</text>
</g>
</svg>
9.3 <tspan>元素
类似<span>元素,可以嵌套在文本内容中,改变文本样式。也可以使用dy元素改变某个字母的位置,
<svg width="250px" height="600px" viewBox="0 0 250 60">
<text x="10" y="30">
Sample Text
<tspan dy="4">a</tspan>
<tspan dy="6">a</tspan>
</text>
</svg>
第十章 蒙版和剪裁
第十一章 滤镜
第十二章 动画
12.1 动画基础
<svg width="250" height="50">
<rect x="10" y="10" width="200" height="20" stroke="black" fill="none">
<animate id="animation"
attributeName="width"
attributeType="XML"
from="200" to="20"
begin="0s" dur="5s"
fill="freeze" />
</rect>
atrributeName:动画中持续改变的值
attributeType 值为XML或者CSS ,在本例中改变的是XML属性的width,所以值为XML。默认为auto,先搜索CSS属性,再搜索XML属性
from to属性的起始值和结束值,from值是可选的,如果不指定,使用父元素的值。
begin dur动画开始和持续时间
fill 动画结束后做什么 freeze:冻结 默认值为remove,返回原来的属性
<svg width="275" height="275">
<rect x="10" y="10" width="20" height="20"
style="stroke: black; fill: green; style: fill-opacity: 0.25;">
<animate attributeName="width" attributeType="XML"
from="20" to="200" begin="0s" dur="8s" fill="freeze"/>
<animate attributeName="height" attributeType="XML"
from="20" to="150" begin="0s" dur="8s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="CSS"
from="0.25" to="1" begin="0s" dur="3s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="CSS"
from="1" to="0.25" begin="3s" dur="3s" fill="freeze"/>
</rect>
</svg>
<svg width="200" height="200">
<rect x="10" y="10" width="20" height="20"
style="stroke: black; fill: #cfc;">
<animate attributeName="width" attributeType="XML"
begin="0s" dur="8s" from="20" to="120" fill="freeze"/>
<animate attributeName="height" attributeType="XML"
begin="0s" dur="8s" from="20" to="120" fill="freeze"/>
</rect>
<circle cx="70" cy="70" r="20"
style="fill: #ccf; stroke: black;">
<animate attributeName="r" attributeType="XML"
begin="2s" dur="4s" from="20" to="50" fill="freeze"/>
</circle>
</svg>
12.2 动画时间讲解
svg动画在svg加载完成时启动,用户离开页面停止计时。
(1)时、分、秒(1:20:33)的完整时间
(2)分、秒(02:15)
(3)秒
12.3 同步动画
绑定动画开始时间为另一个动画的结束时间
<svg width="200" height="200">
<circle cx="60" cy="60" r="30" style="fill: #f9f; stroke: gray;">
<animate id="c1" attributeName="r" attributeType="XML"
begin="0s" dur="4s" from="30" to="10" fill="freeze"/>
</circle>
<circle cx="120" cy="60" r="10" style="fill: #9f9; stroke: gray;">
<animate attributeName="r" attributeType="XML"
begin="c1.begin+1.25s" dur="4s" from="10" to="30" fill="freeze"/>
</circle>
</svg>
end给动画设置结束时间,但不能替代dur属性,动画结束时间取min(end,dur)
12.4 重复动作
repeatCount:设置动画执行多少次。
repeatDur:设置动画持续多次时间
<svg width="350" height="120">
<circle cx="60" cy="60" r="30" style="fill: none; stroke: red;">
<animate attributeName="cx" attributeType="XML"
begin="0s" dur="5s" repeatCount="2"
from="60" to="260" fill="freeze"/>
</circle>
<circle cx="260" cy="90" r="30" style="fill: #ccf; stroke: black;">
<animate attributeName="cx" attributeType="XML"
begin="0s" dur="5s" repeatDur="8s"
from="260" to="60" fill="freeze"/>
</circle>
</svg>
12.5 设置复杂属性
<svg width="250" height="250"
xmlns="http://www.w3.org/2000/svg">
<polygon points="30 30 70 30 90 70 10 70"
style="fill:#fcc; stroke:black">
<animate id="animation"
attributeName="points"
attributeType="XML"
to="50 30 70 50 50 90 30 50"
begin="0s" dur="5s" fill="freeze" />
</polygon>
<path d="M15 50 Q 40 15, 50 50, 65 32, 100 40"
style="fill:none; stroke: black" transform="translate(0,50)">
<animate attributeName="d"
attributeType="XML"
to="M50 15 Q 15 40, 50 50, 32 65, 40 100"
begin="0s" dur="5s" fill="freeze"/>
</path>
</svg>
12.6 指定多个值
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="30" style="fill: #ff9; stroke: black;">
<animate
attributeName="fill"
begin="2s"
dur="4s"
values="red;blue;pink;yellow"
fill="freeze"
/>
</circle>
</svg>
12.7 <set>元素
动画归根到底都是修改值,有时候,我们想改变非数字属性或者不能过度的属性,因此svg引入了<set>元素,需要to属性以及适当的时间信息。
<svg width="150" height="100">
<circle cx="60" cy="60" r="30" style="fill: #ff9; stroke: gray;">
<animate
id="c1"
attributeName="r"
attributeType="XML"
begin="0s"
dur="4s"
from="30"
to="0"
fill="freeze"
/>
</circle>
<text text-anchor="middle" x="60" y="60" style="visibility: hidden;">
<set
attributeName="visibility"
attributeType="CSS"
to="visible"
begin="4.5s"
dur="1s"
fill="freeze"
/>
All gone!
</text>
</svg>
12.8 <animateTransform>元素
<animate>元素不适用于旋转,平移缩放和倾斜变换, <animateTransform>元素可以用来解决这个问题,设置attributeName为transform,type属性可以指定哪些值应该变化,(translate,scale,rotate)
<svg width="200" height="100">
<g transform="translate(100,60)">
<rect
x="-10"
y="-10"
width="20"
height="20"
style="fill: #ff9; stroke: black;"
>
<animateTransform
attributeType="XML"
attributeName="transform"
type="scale"
from="1"
to="4 2"
begin="0s"
dur="4s"
fill="freeze"
/>
</rect>
</g>
</svg>
如果打算为多个变换应用动画,必须使用additive属性,它的默认值为replace,会替换之前的动画,通过设置为sum来积累变化
<svg width="200" height="100">
<g transform="translate(100,60)">
<rect
x="-10"
y="-10"
width="20"
height="20"
style="fill: #ff9; stroke: black;"
>
<animateTransform
attributeType="XML"
attributeName="transform"
type="scale"
from="1"
to="4 2"
begin="0s"
dur="4s"
fill="freeze"
/>
<animateTransform
attributeType="XML"
attributeName="transform"
type="rotate"
from="0"
to="45"
begin="0s"
dur="4s"
fill="freeze"
additive="sum"
/>
</rect>
</g>
</svg>
12.9 <animateMotion>元素
我们可以在<animateMotion>元素中使用translate让对象沿着一条路径运动,如果想要对直线运动使用<animateMotion>,设置from和to属性,给每个属性分配一对(x,y)坐标即可,如果想要复杂的路径运动,使用path属性
<svg width="120" height="100" viewBox="0 0 120 100">
<g>
<rect x="0" y="0" width="30" height="30" style="fill: #ccc;" />
<circle cx="30" cy="30" r="15" style="fill: #cfc; stroke: green;" />
<animateMotion from="0,0" to="60,30" dur="4s" fill="freeze" />
</g>
</svg>
<svg width="250" height="250">
<path
d="M50,125 C 100,25 150,225, 200, 125"
style="fill: none; stroke: blue;"
/>
<path d="M-10,-3 L10,-3 L0,-25z" style="fill: yellow; stroke: red;">
<animateMotion
path="M50,125 C 100,25 150,225, 200, 125"
rotate="auto"
dur="6s"
fill="freeze"
/>
</path>
</svg>
q
12.10 使用css处理SVG动画
| animation-name | 规定需要绑定到选择器的 keyframe 名称。。 |
|---|---|
| animation-duration | 规定完成动画所花费的时间,以秒或毫秒计。 |
| animation-timing-function | 规定动画的速度曲线。 |
| animation-delay | 规定在动画开始之前的延迟。 |
| animation-iteration-count | 规定动画应该播放的次数。 |
| animation-direction | 规定是否应该轮流反向播放动画。 |