三个例子上手,用CSS和SVG制作饼图

by admin on 2019年3月25日

二个例证上手 SVG 动画

2017/05/05 · HTML5 ·
SVG

原稿出处:
坑坑洼洼实验室   

CSS3动画已充裕强大,可是照旧有局部它做不到的地点。合作SVG,让Web动作效果有越来越多的或然性。这一次要做的效率是一个loading动画(如图):个中旋转通过CSS来形成,不过旋转之后圆弧减少变成笑脸的嘴巴必要正视SVG来贯彻。

必发88 1

用CSS和SVG制作饼图

2015/08/10 · CSS ·
SVG

原稿出处: Lea
Verou   译文出处:lulux的博客   

在关乎到CSS技术时,没有人会比Lea
Verou更执着、但是又丰硕聪明,努力去找寻难题的各样解决方案。近来,Lea自身撰写、设计和出版了一本书——CSS
Secrets,那本书很是幽默,包罗部分CSS小技巧以及缓解周边难题的技巧。如果你认为温馨的CSS技术还不易,看看那本书,你会吃惊的。在那篇小说中,大家宣布了书里的一部分有些,这也被刊登在Lea近日在SmashingConf
New
York的演说内容中——用CSS设计简约的饼图。注意,因为浏览器的协理少数,有个别demo大概或不可能健康运维。——编辑

饼图,就算是最简便的唯有二种颜色的款式,用Web技术创设也并不简单,固然都以一对广泛的音讯内容,从容易的总结到进程条目的还有计时器。平日是应用外部图像编辑器来分别为多个值创设多个图像来落实,或是使用大型的JavaScript框架来陈设更复杂的图形。

即便那个东西并不像它已经看起来那么难以达成,不过也尚无什么直接并且不难的法门。可是,未来早就有不少更好、更易于维护的措施来完结它。

SVG 图像入门教程

2018/08/07 · HTML5 ·
SVG

初稿出处: 阮一峰   

三看 SVG Web 动效

2016/11/30 · HTML5 · 1
评论 ·
SVG

原作出处:
坑坑洼洼实验室   

必发88 2

CSS3 动作效果玩腻了啊?不要紧的,我们还有 SVG。

Welikesmall
是二个互连网牌子宣传代理,这是自家见过的最欣赏使用 SVG
做动效的网页设计团队。事实上,越多的网页动作效果达人选拔在 SVG
的疆土上开发动效的泥土,固然 SMIL 寿将终寝,事实上那反而将 SVG
动效推向了1个新的社会风气:CSS3 Animation + SVG。

必发88 3

(SMIL is dead! Long live SMIL! A Guide to Alternatives to SMIL
Features)

还记得作者在长久的《以摄像之立即 CSS3
动画》中商量:“CSS3
动画大约拥有了一切世界!”那么带上 SVG 的 CSS3
动画则已突破天际向着宇宙级的可能性前进(感觉给协调挖了二个极致伟大的坑,网页动画界可不敢再出新技巧了[扶额])。

CSS 与 SVG 的开挖无疑将 html 代码的可读性又推上一个阶梯,大家能够通过
CSS 控制 SVG
图形的尺寸、填色、边框色、过渡、移动变幻等非凡实用的种种品质,除外,将图纸分解的动画片在那种规则下也变得十一分简单。

Step1、声明SVG视口

XHTML

<svg width=”100″ height=“100”></svg>

1
<svg width="100" height=“100”></svg>

点名三个宽高都为100像素的区域,width=”100”和width=”100px”是等价的,当然也足以运用其它的合法单位,例如cm、mm、em等

开卷器会设置一个暗中同意的坐标体系,见图:左上角为原点,个中国水力电力对外集团平(x)坐标向右递增,垂直(y)坐标向下递增。

必发88 4

在一贯不点名的景况下,全部的的数值默许单位都是像素。

依照变换的化解方案


这一个方案从HTML的角度来说是最佳的:它只必要3个因素,别的的都得以用伪成分、变换和CSS渐变完结。大家从底下这么些简单的成分初步:

<div class=”pie”></div>

1
<div class="pie"></div>

近日,假如我们期望显示叁个 伍分一 比例的饼图。灵活性的题材我们前边再消除。大家先给成分添加样式,让它变成四个圆,也正是我们的背景:

必发88 5

图1:第壹步是先画三个圆(或许可以说是展现0%百分比的饼图)

CSS

.pie { width: 100px; height: 100px; border-radius: 50%; background:
yellowgreen; }

1
2
3
4
5
.pie {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: yellowgreen;
}

 

大家的饼图是水泥灰(特指 yellowgreen )和深黄( #655 )显示的百分比。或者会在比例部分尝试使用
transform 中的 skew ,可是通过一次考试之后申明,那是贰个至极混乱的方案。因此,大家用那二种颜色为这几个饼图的左右片段各自着色,然后对于我们想要的百分比,使用旋转的伪成分来兑现。

咱俩应用三个粗略的线性渐变,给右半部分着樱草黄:

CSS

background-image: linear-gradient(to right, transparent 50%, #655 0);

1
background-image: linear-gradient(to right, transparent 50%, #655 0);

必发88 6

图2:用三个不难易行的线性渐变给右半圆着茶青

如图2所示,那样就做到了。未来,大家能够持续为伪成分添加样式,让它变成3个蒙版:

CSS

.pie::before { content: ”; display: block; margin-left: 50%; height:
100%; }

1
2
3
4
5
6
.pie::before {
  content: ”;
  display: block;
  margin-left: 50%;
  height: 100%;
}

必发88 7

图3:虚线内的始末表示伪元素将用作蒙版的区域

您能够在图3中来看大家的伪成分当前稳定相对于大家的pie成分。近年来,它还尚未增加样式,也平素不掩盖任张静西,只是2个晶莹剔透的矩形。在开班添加样式此前,大家先来分析一下:

  • 因为我们盼望它覆盖圆的普鲁士蓝部分,大家须求给它应用1个紫罗兰色的背景,使用
    background-color: inherit 来防止再一次定义,因为我们自然就巴望它和父成分的背景颜色保持一致。
  • 作者们愿意它绕着圆的主干点旋转,核心点在伪成分的左边,所以大家必要给它的
    transform-origin ,应用三个0 3/6 ,恐怕是一向多少个 left 。
  • 作者们不想要它是一个矩形,因为它会超越饼图的边缘,所以大家要求给 .pie 应用 overflow: hidden ,或然是叁个正好的
    border-radius 让它成为多少个半圆。

归咎,伪成分的CSS样式如下:

CSS

.pie::before { content: ”; display: block; margin-left: 50%; height:
100%; border-radius: 0 100% 100% 0 / 50%; background-color: inherit;
transform-origin: left; }

1
2
3
4
5
6
7
8
9
.pie::before {
  content: ”;
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
}

必发88 8

图4:添加体制之后的伪成分(那里用虚线表示)

留神:不要采用 class=”crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco”
style=”font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;”> class=”crayon-pre crayon-code”
style=”font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;”> class=”crayon-e”>background class=”crayon-sy”>: class=”crayon-i”>inherit class=”crayon-sy”>; ,要用 id=”crayon-5b8f6c8720464547585400″
class=”crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco”
style=”font-size: 13px 三个例子上手,用CSS和SVG制作饼图。!important; line-height: 15px !important;font-size: 13px !important;”> class=”crayon-pre crayon-code”
style=”font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;”> class=”crayon-e”>background-color class=”crayon-sy”>: class=”crayon-i”>inherit ;,不然父成分背景图像上的渐变也会被一而再

我们的饼图近期如图4所示。现在伊始有趣起来了!大家能够初阶旋转伪成分,给它采用一个rotate() 变换。要展现 五分一 的比例,大家得以给它3个 72deg ( 0.2 x 360 = 72 ),或 .2turn ,那一个可读性更好。你能够在图5中见到区别旋转角度值的结果。

必发88 9

图5:分别展现不相同期相比较重的饼图,从左到右: 1/10  ( 36deg 或 .1turn ), 伍分一  ( 72deg 或  .2turn ), 百分之四十  ( 144deg  或 .4turn )

你恐怕会想大家早就到位了,不过它可没那样简单。大家的饼图在展现050%的尺寸的内容时是不曾任何难题的,不过只要大家要描绘一个伍分叁 的旋转(通过运用 .6turn ),就会发生如图6的图景。可是,别担心,我们能够缓解这么些事情!

必发88 10

图6:对于超越50%的比例,我们的饼图就跪了orz(那里的是6/10)

就算我们把 百分之五十-百分百 比例的气象作为单身的贰个标题,可能会专注到能够利用以前的化解方案的反相版本:从0.5turn旋转的黄铜色伪成分。所以,对于3个60%的饼图,伪成分的CSS代码如下:

CSS

.pie::before { content: ”; display: block; margin-left: 50%; height:
100%; border-radius: 0 100% 100% 0 / 50%; background: #655;
transform-origin: left; transform: rotate(.1turn); }

1
2
3
4
5
6
7
8
9
10
.pie::before {
  content: ”;
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background: #655;
  transform-origin: left;
  transform: rotate(.1turn);
}

必发88 11

图7: 3/5 饼图的不错打开格局~

您能够在图7中看到结果。因为我们曾经制定了二个得以描绘出任何百分比的法门,大家甚至能够为饼图从0%100%添加动画功用,创立出1个妙趣横生的进度条:

CSS

@keyframes spin { to { transform: rotate(.5turn); } } @keyframes bg {
50% { background: #655; } } .pie::before { content: ”; display: block;
margin-left: 50%; height: 100%; border-radius: 0 100% 100% 0 / 50%;
background-color: inherit; transform-origin: left; animation: spin 3s
linear infinite, bg 6s step-end infinite; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@keyframes spin {
  to { transform: rotate(.5turn); }
}
 
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  content: ”;
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: spin 3s linear infinite,
             bg 6s step-end infinite;
}

 

See the Pen zGbNLJ by Airen
(@airen) on CodePen.

来得没不平日,不过大家只要给多个例外比例的静态饼图添加样式呢,最普遍的用例是?在曼妙图景下,我们盼望得以简单地输入如下的始末:

<div class=”pie”>20%</div> <div
class=”pie”>60%</div>

1
2
<div class="pie">20%</div>
<div class="pie">60%</div>

然后就可以赢得多个饼图,3个意味20%,1个象征60%。首先,大家先研商一下哪些运用内联样式来形成,然后我们得以写3个简便的脚本来分析文本内容,对应地抬高内联样式,而且要代码优雅、封装、可维护性,还有最要紧的一点,可访问性。

动用内联样式控制饼图百分比的二个不便是:用于安装百分比CSS代码是用伪成分实现的。而且你也明白,大家不能够给伪成分设置内联样式,所以大家必要立异。

注意:若是你想要使用的值是在有个别不须求通过再一次的复杂的测算的限制内的境况,你能够接纳同一的技术,包含透过它们一步一步调节和测试动画的场合。看该技能的叁个简短的以身作则。

 

See the Pen YXgNOK by Airen
(@airen) on CodePen.

消除方案来自最不容许的地点之一。我们就要选取大家已经介绍过的动画片,可是它是刹车状态的。大家不会让它像一个健康的动画那样运转,我们将利用负延迟来让它能够静态地暂停在某些点。很意外?贰个负的animation-delay的值不仅在正式中是允许的,在类似那样的案例中也是可怜好用:

负延迟是卓有作用的。和0s的延期类似,它意味着动画将登时执行,可是是根据延迟的相对值来自动运转的,所以一旦动画已经在钦赐的时日从前就开头运转了,那它就会直接从active的时光中途运行。
—CSS Animations Level
1

因为大家的卡通片是刹车的,它的率先帧正是我们唯一突显的那一帧(通过大家的animation-delay概念)。饼图上显得的比重将会是我们的animation-delay的总时间。例如,当前的持续时间是6s,我们的
animation-delay 值为-1.2s则显示20%的比重。为了简化总括,大家设置1个100s的持续时间。记住因为大家的动画片是永久暂停的,大家给它钦赐的延期大小并不会有哪些影响。

还有最后1个难点:动画是赋给伪成分的,可是大家想要给.pie要素设置内联样式。因为<div>上并未动画,咱们得以给它设置animation-delay作为内联样式,然后给伪成分应用
animation-delay: inherit; 。综上所述,20%60%的饼图的HTML代码如下:

<div class=”pie” style=”animation-delay: -20s”></div>
<div class=”pie” style=”animation-delay: -60s”></div>

1
2
<div class="pie" style="animation-delay: -20s"></div>
<div class="pie" style="animation-delay: -60s"></div>

正巧建议的这些动画的CSS代码如下(省略 .pie 规则,因为从没变动):

CSS

@keyframes spin { to { transform: rotate(.5turn); } } @keyframes bg {
50% { background: #655; } } .pie::before { /* [Rest of styling stays
the same] */ animation: spin 50s linear infinite, bg 100s step-end
infinite; animation-play-state: paused; animation-delay: inherit; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@keyframes spin {
  to { transform: rotate(.5turn); }
}
 
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  /* [Rest of styling stays the same] */
  animation: spin 50s linear infinite, bg 100s step-end infinite;
  animation-play-state: paused;
  animation-delay: inherit;
}

此时,能够把HTML标签改成采纳比例作为内容,和一起来期待的一律,然后经过2个不难易行的台本为其添加
animation-delay 内联样式。

JavaScript

$$(‘.pie’).forEach(function(pie) { var p = parseFloat(pie.textContent);
pie.style.animationDelay = ‘-‘ + p + ‘s’; });

1
2
3
4
$$(‘.pie’).forEach(function(pie) {
  var p = parseFloat(pie.textContent);
  pie.style.animationDelay = ‘-‘ + p + ‘s’;
});

必发88 12

图8:没有隐藏文本前的图

  • 把饼图的height更换来 line-height (或抬高1个和height值卓殊的line-height,然而那值是毫无意义的重复代码,因为line-height会自动测算height的值)。
  • 经过相对定位给伪成分设置大小和岗位,那样它不会把公文挤下去。
  • 添加 text-align: center; 让文本水平居中。

最后的代码如下:

CSS

.pie { position: relative; width: 100px; line-height: 100px;
border-radius: 50%; background: yellowgreen; background-image:
linear-gradient(to right, transparent 50%, #655 0); color: transparent;
text-align: center; } @keyframes spin { to { transform: rotate(.5turn);
} } @keyframes bg { 50% { background: #655; } } .pie::before { content:
”; position: absolute; top: 0; left: 50%; width: 50%; height: 100%;
border-radius: 0 100% 100% 0 / 50%; background-color: inherit;
transform-origin: left; animation: spin 50s linear infinite, bg 100s
step-end infinite; animation-play-state: paused; animation-delay:
inherit; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.pie {
  position: relative;
  width: 100px;
  line-height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image: linear-gradient(to right, transparent 50%, #655 0);
  color: transparent;
  text-align: center;
}
 
@keyframes spin {
  to { transform: rotate(.5turn); }
}
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  content: ”;
  position: absolute;
  top: 0; left: 50%;
  width: 50%; height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: spin 50s linear infinite, bg 100s step-end infinite;
  animation-play-state: paused;
  animation-delay: inherit;
}

 

See the Pen qdvRMv by Airen
(@airen) on CodePen.

一、概述

SVG 是一种基于 XML 语法的图像格式,全称是可缩放矢量图(Scalable Vector
Graphics)。别的图像格式都是遵照像素处理的,SVG
则是属于对图像的形制描述,所以它实质上是文件文件,体量较小,且不论放大多少倍都不会失真。

必发88 13

SVG 文件能够直接插入网页,成为 DOM 的一片段,然后用 JavaScript 和 CSS
举行操作。

<!DOCTYPE html> <html> <head></head>
<body> <svg id=”mysvg” xmlns=”三个例子上手,用CSS和SVG制作饼图。”
viewBox=”0 0 800 600″ preserveAspectRatio=”xMidYMid meet” >
<circle id=”mycircle” cx=”400″ cy=”300″ r=”50″ /> <svg>
</body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head></head>
<body>
<svg
  id="mysvg"
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 800 600"
  preserveAspectRatio="xMidYMid meet"
>
  <circle id="mycircle" cx="400" cy="300" r="50" />
<svg>
</body>
</html>

下边是 SVG 代码间接插入网页的例子。

SVG
代码也可以写在1个独立文件中,然后用<img><object><embed><iframe>等标签插入网页。

<img src=”circle.svg”> <object id=”object” data=”circle.svg”
type=”image/svg+xml”></object> <embed id=”embed”
src=”icon.svg” type=”image/svg+xml”> <iframe id=”iframe”
src=”icon.svg”></iframe>

1
2
3
4
<img src="circle.svg">
<object id="object" data="circle.svg" type="image/svg+xml"></object>
<embed id="embed" src="icon.svg" type="image/svg+xml">
<iframe id="iframe" src="icon.svg"></iframe>

CSS 也可以接纳 SVG 文件。

CSS

.logo { background: url(icon.svg); }

1
2
3
.logo {
  background: url(icon.svg);
}

SVG 文件仍是能够转为 BASE64 编码,然后作为 Data U冠道I 写入网页。

<img src=”data:image/svg+xml;base64,[data]”>

1
<img src="data:image/svg+xml;base64,[data]">

索引

本文将讲到三个动效例子:

  • 箭头描线动作效果
  • 播放按钮滤镜动作效果
  • 虚线描线动作效果

动作效果来源:WLS-Adobe

快要聊到的 SVG 标签:

  • <path>
  • <g>
  • <symbol>
  • <defs>
  • <use>
  • <clipPath>
  • <mask>

以及质量:

  • viewBox
  • preserveAspectRatio
  • fill
  • stroke
  • stroke-dasharray
  • stroke-dashoffset
  • d
  • clip-path
  • mask

Step二 、绘制购物袋

购物袋由两个部分组成,先画下面的主体:

XHTML

<path d=”M 20 40 L 80 40 L 80 90 A 10 10 90 0 1 70 100 L 30 100 A 10
10 90 0 1 20 90″ style=”fill: #e9e8ee;” />

1
<path d="M 20 40 L 80 40 L 80 90 A 10 10 90 0 1 70 100 L 30 100 A 10 10 90 0 1 20 90" style="fill: #e9e8ee;" />

别的模样都可以选拔路径成分画出,描述概略的数码放在它的d属性中。
a.样式中的fill用来设置填充色。
b.路径数据由命令和坐标构成:

指令 说明
M 20 40 表示移动画笔到(20,40)
L 80 40 表示绘制一条线到(80, 40)
A 10 10 90 0 1 70 100 绘制一个椭圆弧

圆弧命令以字母A起初,后边紧跟着多少个参数,那多个参数分别用来代表:

  • 椭圆的x半径和y半径
  • 椭圆的x轴旋转角度
  • 圆弧的角度小于180度,为0;大于或等于180度,则为1
  • 以负角度绘制为0,不然为1
  • 终点的x、y坐标

必发88 14

接下来绘制购物袋上面的部分

XHTML

<path d=”M 35 40 A 15 15 180 1 1 65 40″ style=”fill: none; stroke:
#e9e8ee; stroke-width: 5;” />

1
<path d="M 35 40 A 15 15 180 1 1 65 40" style="fill: none; stroke: #e9e8ee; stroke-width: 5;” />

地方的一些是一个半半圆,小编同一用路径来画出,也足以使用基础形状来完结。

体制中的stokestroke-width各自用来设置描边色和描边的拉长率。

必发88 15

基于SVG的消除方案


SVG使得许多图形工作变得更为简明,饼图也不例外。可是,用path途径创制饼图,要求复杂的数学总结,大家得以选择一些小技巧来代替。

咱俩从叁个圆起初:

<svg width=”100″ height=”100″> <circle r=”30″ cx=”50″ cy=”50″
/> </svg>

1
2
3
<svg width="100" height="100">
<circle r="30" cx="50" cy="50" />
</svg>

于今,给它使用有的基础的样式:

CSS

circle { fill: yellowgreen; stroke: #655; stroke-width: 30; }

1
2
3
4
5
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 30;
}

瞩目:你恐怕清楚,那几个CSS属性也能够视作SVG成分的习性使用,如若把可移植性考虑在内的话那大概挺便宜的。

必发88 16

图9:从三个淡绿的SVG圆形,带1个胖胖的#655描边开始

您能够在图9中见到大家绘制的加了描边的圆。SVG描边不止有strokestroke-width特性。还有许多不是特地流行的描边相关的性情能够用来对描边进行微调。在那之中1个是stroke-dasharray,用于成立虚线描边。例如,大家可以行使如下:

CSS

stroke-dasharray: 20 10;

1
stroke-dasharray: 20 10;

必发88 17

图10:叁个粗略的虚线描边,通过stroke-dasharray品质创制

那行代码的情趣是大家的虚线是20的尺寸加上10的边距,如图10所示。在那边,你恐怕会奇怪那几个SVG描边属性和饼图毕竟有啥关联吗。要是大家给描边应用2个值为0的虚线宽度,和3个不止或等于我们脚下圆的周长的边距,它只怕就清清楚楚一些了(总计周长:
C = 2πr , 所以在那边  C = 2π × 30 ≈ 189 ):

CSS

stroke-dasharray: 0 189;

1
stroke-dasharray: 0 189;

必发88 18

图11:不同stroke-dasharray值对应的作用;从左到右: 0 189; 40 189; 95 189; 150 189 

如图1第11中学的第三个圆所示,它的描边的都被移除了,只剩下3个钴紫的圆。然而,当我们开始增大第多少个值的时候,遗闻务发生了(图11):因为边距太长,大家就一贯不虚线描边了,唯有三个描边覆盖了大家钦定的圆的周长的比例。

您或者早已开首弄掌握了那是怎么回事:如若大家把圆的半径减小到自然水准,它恐怕就会完全被它的描边覆盖,最终获得的是2个十二分相近于饼图的事物。例如,你可以在图12中见到:当给圆应用三个25的半径和八个50stroke-width,像下边包车型地铁功效:

必发88 19

图12:大家的SVG图像起先像2个饼图了O(∩_∩)O

牢记:SVG描边总是相对于成分边缘五成在内1/2在外的(居中的)。现在理应能够控制这一行事。

<svg width=”100″ height=”100″> <circle r=”25″ cx=”50″ cy=”50″
/> </svg> circle { fill: yellowgreen; stroke: #655;
stroke-width: 50; stroke-dasharray: 60 158; /* 2π × 25 ≈ 158 */ }

1
2
3
4
5
6
7
8
9
10
<svg width="100" height="100">
  <circle r="25" cx="50" cy="50" />
</svg>
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 50;
  stroke-dasharray: 60 158; /* 2π × 25 ≈ 158 */
}

现行反革命,把它成为大家在上叁个缓解方案中创建的饼图的榜样是极度不难的:我们只须要在描边上边添加二个更大的蓝灰圆形,然后逆时针转动90°,那样它的源点就在顶部中间。因为<svg>要素也是HTML成分,大家得以给它助长样式:

CSS

svg { transform: rotate(-90deg); background: yellowgreen; border-radius:
50%; }

1
2
3
4
5
svg {
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;
}

必发88 20

图13:最后的SVG饼图

你能够在图第13中学看出最后结出。那种技术能够让饼图更便于实现从0%100%扭转的动画。大家只需求成立3个CSS动画,让stroke-dasharray
0 158 变成 158 158 :

CSS

@keyframes fillup { to { stroke-dasharray: 158 158; } } circle { fill:
yellowgreen; stroke: #655; stroke-width: 50; stroke-dasharray: 0 158;
animation: fillup 5s linear infinite; }

1
2
3
4
5
6
7
8
9
10
11
@keyframes fillup {
  to { stroke-dasharray: 158 158; }
}
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 50;
  stroke-dasharray: 0 158;
  animation: fillup 5s linear infinite;
}

用作一个至极的革新,大家能够在圆上钦点二个一定半径,使其周长无限接近100,那样大家能够用百分比内定stroke-dasharray的长度,而不须求做计算。因为周长是2πr,我们的半径则是100 ÷ 2π ≈ 15.915494309,约等于16。大家还足以用viewBox特色内定SVG的尺寸,能够让它自动调整为容器的尺寸,不要选取widthheight属性。

通过以上调整,图13的饼图的HTML标签如下:

<svg viewBox=”0 0 32 32″> <circle r=”16″ cx=”16″ cy=”16″ />
</svg>

1
2
3
<svg viewBox="0 0 32 32">
  <circle r="16" cx="16" cy="16" />
</svg>

CSS如下:

CSS

svg { width: 100px; height: 100px; transform: rotate(-90deg);
background: yellowgreen; border-radius: 50%; } circle { fill:
yellowgreen; stroke: #655; stroke-width: 32; stroke-dasharray: 38 100;
/* for 38% */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
svg {
  width: 100px; height: 100px;
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;
}
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 32;
  stroke-dasharray: 38 100; /* for 38% */
}

在意现行反革命比例已经足以很有益于地改变了。当然,就算已经简化了标签,大家照旧不想在绘制各样饼图的时候都重复二次全体那几个SVG标签。那是时候拿出JavaScript来帮我们一把了。大家写二个简约的台本,让我们的HTML标签直接省略地那样写:

<div class=”pie”>20%</div> <div
class=”pie”>60%</div>

1
2
<div class="pie">20%</div>
<div class="pie">60%</div>

接下来在各种.pie要素里边添加三个内联SVG,包涵富有须求的成分和性质。它还会添加八个<title>要素,为了充实可访问性,这样显示器阅读器用户还可以驾驭当前的饼图表示的比重。最终的台本如下:

JavaScript

$$(‘.pie’).forEach(function(pie) { var p = parseFloat(pie.textContent);
var NS = “”; var svg =
document.createElementNS(NS, “svg”); var circle =
document.createElementNS(NS, “circle”); var title =
document.createElementNS(NS, “title”); circle.setAttribute(“r”, 16);
circle.setAttribute(“cx”, 16); circle.setAttribute(“cy”, 16);
circle.setAttribute(“stroke-dasharray”, p + ” 100″);
svg.setAttribute(“viewBox”, “0 0 32 32″); title.textContent =
pie.textContent; pie.textContent = ”; svg.appendChild(title);
svg.appendChild(circle); pie.appendChild(svg); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$$(‘.pie’).forEach(function(pie) {
  var p = parseFloat(pie.textContent);
  var NS = "http://www.w3.org/2000/svg";
  var svg = document.createElementNS(NS, "svg");
  var circle = document.createElementNS(NS, "circle");
  var title = document.createElementNS(NS, "title");
  circle.setAttribute("r", 16);
  circle.setAttribute("cx", 16);
  circle.setAttribute("cy", 16);
  circle.setAttribute("stroke-dasharray", p + " 100");
  svg.setAttribute("viewBox", "0 0 32 32");
  title.textContent = pie.textContent;
  pie.textContent = ”;
  svg.appendChild(title);
  svg.appendChild(circle);
  pie.appendChild(svg);
});

就是它了!你大概会觉得CSS方法相比好,因为它的代码相比较不难而且更可相信。然而,SVG方法相比较纯CSS方案照旧有必然的优势的:

  • 可以非凡简单地丰盛第三种颜色:只要求丰盛另二个描边圆,然后利用stroke-dashoffset安装它的描边属性。然后,将它的描边长度添加到下方的圆的描边长度上。要是是前边那些CSS的方案,你要什么给饼图添加第二种颜色吗?
  • 大家不须求考虑打字与印刷的题目,因为SVG元素仿佛<img>要素一样,被暗许为是内容的一部分,打字与印刷完全没有失常态。第①种方案取决于背景,所以不会被打字与印刷。
  • 我们得以应用内联样式改变颜色,也正是说大家得以由此脚本就径直改动颜色(如,依照用户输入改变颜色)。第3种方案依赖于伪元素,除了通过持续,它没有任何格局能够添加内联样式,那很不便宜。

See the Pen oXVBar by Airen
(@airen) on CodePen.

二、语法

从两个简单易行的例证说起

必发88 21

要做出那样的功用,第2步是将图片画出来。徒手敲代码那种事照旧预留图形工具来做,但是,为了更好地决定与创造动作效果,咱至少要成功读懂
SVG 代码。

SVG 的主干格式是使用 <svg> 标签对代码进行包装,可一贯将代码段插入 html
中,也能够保留成 svg 文件之后选用 imgobject 进行引用。

XHTML

<svg width=”100%” height=”100%”> <!– SVG markup here. –>
</svg>

1
2
3
<svg width="100%" height="100%">
<!– SVG markup here. –>
</svg>

出于互相之间动作效果所需,那里仅介绍直接运用 svg 标签的状态。

XHTML

<svg width=”90″ height=”13″ viewBox=”0 0 89.4 12.4″> <line
x1=”0″ y1=”6.2″ x2=”59.6″ y2=”6.2″></line> <line x1=”54.7″
y1=”0.7″ x2=”60.5″ y2=”6.5″></line> <line x1=”54.7″
y1=”11.7″ x2=”60.5″ y2=”5.8″></line> </svg>

1
2
3
4
5
<svg width="90" height="13" viewBox="0 0 89.4 12.4">
<line x1="0" y1="6.2" x2="59.6" y2="6.2"></line>
<line x1="54.7" y1="0.7" x2="60.5" y2="6.5"></line>
<line x1="54.7" y1="11.7" x2="60.5" y2="5.8"></line>
</svg>

那是箭头的代码段,使用了最简便的线条进行绘图。能够看到里边包裹了许多坐标准样品的属性值。有坐标就表示有坐标系。

SVG
的坐标系存在多个概念:视窗、视窗坐标系、用户坐标系。视窗坐标系与用户坐标系属于
SVG 的三种坐标种类,暗中认可意况下那四个坐标系的点是各种对应的。与 web
其余坐标系相同,原点位于视窗的左上角,x 轴水平向右,y 轴垂直向下。

必发88 22

(图片源于:MDN-SVG
Tutorial-Positions)

SVG 的地点、大小与文书档案流中的块级成分相同,都可由 CSS 实行控制。

视窗即为在页面中 SVG 设定的尺码可知部分,私下认可情状下 SVG 超出隐藏。

SVG 能透过 view博克斯 属性就完事图形的运动与缩放。

viewBox属性值的格式为(x0,y0,u_width,u_height),每种值时期用逗号恐怕空格隔断,它们一起明显了视窗显示的区域:视窗左上角坐标设为(x0,y0)、视窗的宽设为
u_width,高为 u_height;这些变换对一切视窗都起功用。

下图呈现了当 viewBox 尺寸与 SVG 尺寸相同、放大学一年级倍、收缩一倍时的呈现:

必发88 23

必发88 24

必发88 25

一句话总括,就是用户坐标系必要以某种情势铺满整个视窗。暗许的艺术是以最短边为准铺满,也正是近似
background-size 中的 cover 值。通过 preserveAspectRatio
属性你能够控制用户坐标系的进行情势与职分,完美满意你的各个必要。

preserveAspectRatio
是一個以對齊為主,然後再選擇要自動填滿還是咖掉的屬性。——引用来源《SVG
研讨之路 (23) – 精晓 viewport 與
viewbox》

属性的语法如下:preserveAspectRatio="[defer] <align> [<meetOrSlice>]"

注意三个参数之间必要运用空格隔开分离。

defer:可选参数,只对 image 元素有效,假设 image 元素中
preserveAspectRatio 属性的值以 defer 开首,则代表 image
成分使用引用图片的缩放比例,借使被引用的图样并未缩放比例,则忽略
defer。全部其余的因素都忽视那一个字符串。

meetOrSlice:可选参数,能够去下列值:

  • meet – 暗许值,统一缩放图形,让图形全体显得在 viewport 中。
  • slice – 统一缩放图形,让图形充满 viewport,超出的有的被剪开掉。

——引用来源《突袭 HTML5 之 SVG 2D 入门6 –
坐标与转换》

align:必选参数。由多个名词组成。

這兩個名詞分別代表 viewbox 與 viewport 的 x 方向對齊方式,以及 y
方向的對齊形式,換句話說,可以想成:「水平置中 +
垂直靠上對齊」的這種感覺,不過在這個 align
的表現手法倒是很空虚,能够用下方的报表看出端倪:

必发88 26

也为此笔者們要做一個「水平置中 + 垂直靠上對齊」的 viewbox
設定,就必須寫成:xMidYMin,做一個「水平靠右對齊 + 垂直靠下對齊」的
viewbox
設定,就必須寫成:x马克斯Y马克斯,不過這裡有個細節請特別注意,「Y」是大寫呀!真是不清楚為什麼會這樣設計,小编想或許跟命名規則有關吧!

——引用来源《SVG 研究之路 (23) – 领会 viewport 與
viewbox》

下图诠释了各个填充的功能:

必发88 27

(图片来源:7 Coordinate Systems, Transformations and
Units)

在这一范畴处理好图形的呈现之后,剩下的有着变换,无论是 translate、rotate
依旧 opacity,大家都得以全权交给 CSS
来处理,并且能够将图纸细化到造型大概路径的范围举行更换。

可是实际上景况是,刚才的那段代码,放进codepen之后是何等也看不见的,原因就在于那几个途径的绘图既没有填写颜色也从没描边。

Step三 、绘制眼睛

XHTML

<circle cx=“40″ cy=”60″ r=”2.5″ style=”fill: #fff;” /> <circle
cx=”60″ cy=”60″ r=”2.5″ style=”fill: #fff;” />

1
2
<circle cx=“40" cy="60" r="2.5" style="fill: #fff;" />
<circle cx="60" cy="60" r="2.5" style="fill: #fff;" />

利用基础形状,画七个个小圆点。五个属性分别是岗位坐标、半径和填充颜色。
必发88 28

连带财富


  • CSS Transforms
  • CSS Image Values
  • CSS Backgrounds & Borders
  • Scalable Vector Graphics
  • CSS Image Values Level 4

2.1<svg>标签

SVG 代码都位于顶层标签<svg>“之中。下面是3个例证。

<svg width=”100%” height=”100%”> <circle id=”mycircle” cx=”50″
cy=”50″ r=”50″ /> </svg>

1
2
3
<svg width="100%" height="100%">
  <circle id="mycircle" cx="50" cy="50" r="50" />
</svg>

<svg>的width属性和height特性,钦命了 SVG 图像在 HTML
成分中所占据的拉长率和中度。除了相对单位,也足以运用相对单位(单位:像素)。假设不点名那些性子,SVG
图像暗中认可大小是300像素(宽) x 150像素(高)。

假如只想体现 SVG 图像的一某个,就要钦命viewBox属性。

<svg width=”100″ height=”100″ viewBox=”50 50 50 50″> <circle
id=”mycircle” cx=”50″ cy=”50″ r=”50″ /> </svg>

1
2
3
<svg width="100" height="100" viewBox="50 50 50 50">
  <circle id="mycircle" cx="50" cy="50" r="50" />
</svg>

<viewBox>特性的值有八个数字,分别是左上角的横坐标和纵坐标、视口的宽度和冲天。上面代码中,SVG
图像是100像素宽 x
100像素高,viewBox属性内定视口从(50, 50)其一点起来。所以,实际看到的是右下角的四分一圆。

在意,视口必须适配所在的长空。上边代码中,视口的高低是 50 x 50,由于 SVG
图像的轻重缓急是 100 x 100,所以视口会推广去适配 SVG
图像的分寸,即松开了四倍。

假使不点名width属性和height属性,只指定viewBox质量,则一定于只给定
SVG 图像的长度宽度比。那时,SVG 图像的暗中同意大小将等于所在的 HTML 成分的尺寸。

填充——fill

fill 属性用于给形状填充颜色。

CSS

svg line { fill: #000; /* 填充石青 */ }

1
2
3
svg line {
fill: #000; /* 填充黑色 */
}

填充色的光滑度通过 fill-opacity 设置。

fill-rule 用于安装填充格局,算法较为抽象,除了 inherit
那一个取值,还可取以下二种值:

nonzero:这一个值选拔的算法是:从必要看清的点向任意方向发射线,然后总括图形与线条交点的处的走向;总计结果从0开头,每有1个交点处的线条是从左到右的,就加1;每有一个交点处的线条是从右到左的,就减1;这样计算完全数交点后,借使这一个总结的结果不等于0,则该点在图片内,供给填写;假使该值等于0,则在图片外,不要求填写。看上边包车型客车以身作则:

必发88 29

evenodd:这几个值采纳的算法是:从要求看清的点向任意方向发射线,然后总计图形与线条交点的个数,个数为奇数则改点在图纸内,必要填写;个数为偶数则点在图纸外,不须求填写。看下图的言传身教:

必发88 30

——引用来源《突袭 HTML5 之 SVG 2D 入门4 –
笔画与填充》

唯独我们发现,大家的箭头即便填写了颜色,依然怎么也看不见,难点就出在我们绘制的时候使用了并未面积的
line 标签。这么些时候,就须要出动描边了。

Step④ 、绘制嘴巴

XHTML

<circle cx=”50″ cy=”70″ r=”15″ style=”fill: none; stroke: #fff;
stroke-width: 5; stroke-linecap: round;transform: rotate(280deg);
transform-origin: 50% 50%; stroke-dashoffset: -23; stroke-dasharray: 42,
95;”>

1
<circle cx="50" cy="70" r="15" style="fill: none; stroke: #fff; stroke-width: 5; stroke-linecap: round;transform: rotate(280deg); transform-origin: 50% 50%; stroke-dashoffset: -23; stroke-dasharray: 42, 95;”>

嘴巴是一段圆弧,笔者绘制了一个圆,然后描边了当中的一段,并且做了四个转悠,来让它的角度处刘恒确的岗位。

  • stroke-linecap:用来定义开放路线的甘休,可选round|butt|square
  • stroke-dasharray:用来创制虚线
  • stroke-dashoffset:设置虚线地点的初叶偏移值,在下一步骤里,它会和stroke-dasharray一起用来贯彻动效。

必发88 31

明日的饼图


椭圆形渐变在此间也得以拾叁分有帮扶。它只要求多个圆形成分,以及带有五个色标的锥形渐变即可做出饼图。例如,图5中表示百分之四十的饼图能够这么形成:

必发88 32

CSS

.pie { width: 100px; height: 100px; border-radius: 50%; background:
conic-gradient(#655 40%, yellowgreen 0); }

1
2
3
4
5
.pie {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: conic-gradient(#655 40%, yellowgreen 0);
}

还有,一旦CSS Values Level
3中定义的attr()函数更新后被广泛应用,你就能够用简短的HTML属性来控制百分比了:

CSS

background: conic-gradient(#655 attr(data-value %), yellowgreen 0);

1
background: conic-gradient(#655 attr(data-value %), yellowgreen 0);

要添加第两种颜色也相当容易。例如,对于地点展现的饼图,大家只须要再充实七个色标:

CSS

background: conic-gradient(deeppink 20%, #fb3 0, #fb3 30%, yellowgreen
0);

1
background: conic-gradient(deeppink 20%, #fb3 0, #fb3 30%, yellowgreen 0);

:多亏了Lea的锥形渐变polyfill,我们今后才方可采用锥形渐变,在他的SmashingConf演说截至不久以往揭橥的。那也许正是您今后用CSS来统一筹划饼图的措施!那里的二种形式您会利用什么哪个种类,以及为何那样做?或许您曾经想到了三个通通差别的缓解方案?请在说长话短中留言~

1 赞 2 收藏
评论

必发88 33

2.2 <circle>标签

<circle>标签代表圆形。

<svg width=”300″ height=”180″> <circle cx=”30″ cy=”50″ r=”25″
/> <circle cx=”90″ cy=”50″ r=”25″ class=”red” /> <circle
cx=”150″ cy=”50″ r=”25″ class=”fancy” /> </svg>

1
2
3
4
5
<svg width="300" height="180">
  <circle cx="30"  cy="50" r="25" />
  <circle cx="90"  cy="50" r="25" class="red" />
  <circle cx="150" cy="50" r="25" class="fancy" />
</svg>

地点的代码定义了多少个圆。<circle>标签的cxcyr属性分别为横坐标、纵坐标和半径,单位为像素。坐标都是争持于<svg>画布的左上角原点。

class属性用来钦定相应的 CSS 类。

CSS

.red { fill: red; } .fancy { fill: none; stroke: black; stroke-width:
3pt; }

1
2
3
4
5
6
7
8
9
.red {
  fill: red;
}
 
.fancy {
  fill: none;
  stroke: black;
  stroke-width: 3pt;
}

SVG 的 CSS 属性与网页元素有所区别。

  • fill:填充色
  • stroke:描边色
  • stroke-width:边框宽度

描边——stroke

这个 stroke 可得洋洋万言,因为光是那么些 stroke
就能解决十分之八的描线动作效果。

平素通过 stroke 设置描边色,大家就能即时看出刚才的箭头了。通过
stroke-width 则能够对描边的粗细举行修改。

CSS

svg line { stroke: #000; stroke-width: 1px; }

1
2
3
4
svg line {
stroke: #000;
stroke-width: 1px;
}

必发88 34

Step伍 、给嘴巴部分添加动作效果

CSS

@keyframes mouth { 0% { transform: rotate(-80deg); stroke-dasharray: 60,
95; stroke-dashoffset: 0; } 40% { transform: rotate(280deg);
stroke-dasharray: 60, 95; stroke-dashoffset: 0; } 70%, 100% { transform:
rotate(280deg); stroke-dashoffset: -23; stroke-dasharray: 42, 95; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@keyframes mouth {
  0% {
    transform: rotate(-80deg);
    stroke-dasharray: 60, 95;
    stroke-dashoffset: 0;
  }
  40% {
    transform: rotate(280deg);
    stroke-dasharray: 60, 95;
    stroke-dashoffset: 0;
  }
  70%, 100% {
    transform: rotate(280deg);
    stroke-dashoffset: -23;
    stroke-dasharray: 42, 95;
  }
}

动画片分为多少个部分:

  1. 圆弧旋转
  2. 旋转之后裁减变形

在二个巡回里,最终留有百分之三十的时光维系三个停留。

必发88 35

2.3 <line>标签

<line>标签用来绘制直线。

<svg width=”300″ height=”180″> <line x1=”0″ y1=”0″ x2=”200″
y2=”0″ style=”stroke:rgb(0,0,0);stroke-width:5″ /> </svg>

1
2
3
<svg width="300" height="180">
  <line x1="0" y1="0" x2="200" y2="0" style="stroke:rgb(0,0,0);stroke-width:5" />
</svg>

上面代码中,<line>`标签的x1属性和y1属性,表示线段起点的横坐标和纵坐标;x2属性和y2属性,表示线段终点的横坐标和纵坐标;style`属性表示线段的样式。

线的底子:stroke-dasharray

(敲黑板)金牌属性出现辣!
其一本性的属性值是1到 n 个数字,四个数字由逗号隔离,CSS
中的定义则由空格分开,每一种数字定义了实线段的长度,分别是遵循绘制、不绘制那一个顺序循环下去。

下边是设置了二个、1个、二个数字时虚线的描写意况相比:

必发88 36

Step陆 、给眼睛添加动画

五只眼睛都以顺着圆弧运动 ,例如左眼,首先用三个路子来分明它的移动轨迹:

XHTML

<path id=”eyeright” d=”M 40 60 A 15 15 180 0 1 60 60″ style=”fill:
none; stroke-width: 0;” />

1
<path id="eyeright"  d="M 40 60 A 15 15 180 0 1 60 60" style="fill: none; stroke-width: 0;" />

接下来选拔animateMotion来安装动画:

XHTML

<circle class=”eye” cx=”” cy=”” r=”2.5″ style=”fill: #fff;”>
<animateMotion dur=”0.8s” repeatCount=”indefinite”
keyPoints=”0;0;1;1″ keyTimes=”0;0.3;0.9;1″ calcMode=”linear”>
<mpath xlink:href=”#eyeleft”/> </animateMotion>
</circle>

1
2
3
4
5
6
7
8
9
10
<circle class="eye" cx="" cy="" r="2.5" style="fill: #fff;">
  <animateMotion
    dur="0.8s"
    repeatCount="indefinite"
    keyPoints="0;0;1;1"
    keyTimes="0;0.3;0.9;1"
    calcMode="linear">
    <mpath xlink:href="#eyeleft"/>
  </animateMotion>
</circle>
  • dur:动画的岁月
  • repeatCount:重复次数
  • keyPoints:运动路径的关键点
  • timePoints:时间的关键点
  • calcMode:控制动画的活动速率的变动,discrete | linear | paced |
    spline八个本性可选
  • mpath:钦赐二个外部定义的不二法门

必发88 37

2.4 <polyline>标签

<polyline>标签用于绘制一根折线。

<svg width=”300″ height=”180″> <polyline points=”3,3 30,28
3,53″ fill=”none” stroke=”black” /> </svg>

1
2
3
<svg width="300" height="180">
  <polyline points="3,3 30,28 3,53" fill="none" stroke="black" />
</svg>

``<polyline>points质量钦赐了各样端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点时期用空格分隔。

stroke-dashoffset

(敲黑板)这么些也是人命关天属性!
当我们将描边虚实设置成实线部分与图片描边长度相同时,我们是看不到空白段的部分的。这时形状的描边仿佛完全描绘出来了扳平。这时大家选拔这些天性,将虚线开首的岗位某个做一下平移,无论是往前移依旧将来移,大家都能观望图片描边出现了一段空白,当以此活动形成2个总是的动作时,描线动作效果就好像此不上心的出现了(蓦然回首)。

CSS

svg line { stroke-dasharray: 60; stroke-dashoffset: 60; transition:
stroke-dashoffset ease-in .5s; }   svg:hover line {
stroke-dashoffset: 0; }

1
2
3
4
5
6
7
8
9
svg line {
stroke-dasharray: 60;
stroke-dashoffset: 60;
transition: stroke-dashoffset ease-in .5s;
}
&nbsp;
svg:hover line {
stroke-dashoffset: 0;
}

必发88 38

再对尾部做个延时处理,修改一下虚线移动的来头,动作效果看起来会更美艳一些。这么些时候,SVG
能够分路径编辑的优势就反映出来了。对每种 line
添加二个类,大家就能对每条路径进行差别化处理(Codepen)。

XHTML

<svg width=”360″ height=”52″ viewBox=”0 0 89.4 12.4″> <line
class=”arrow-line” x1=”0″ y1=”6.2″ x2=”59.6″ y2=”6.2″></line>
<line class=”arrow-head” x1=”54.7″ y1=”0.7″ x2=”60.5″
y2=”6.5″></line> <line class=”arrow-head” x1=”54.7″
y1=”11.7″ x2=”60.5″ y2=”5.8″></line> </svg>

1
2
3
4
5
<svg width="360" height="52" viewBox="0 0 89.4 12.4">
<line class="arrow-line" x1="0" y1="6.2" x2="59.6" y2="6.2"></line>
<line class="arrow-head" x1="54.7" y1="0.7" x2="60.5" y2="6.5"></line>
<line class="arrow-head" x1="54.7" y1="11.7" x2="60.5" y2="5.8"></line>
</svg>

CSS

svg line { fill: #000; stroke: #000; stroke-width: 1px; } .arrow-line
{ stroke-dasharray: 60; stroke-dashoffset: 60; transition:
stroke-dashoffset ease-in .5s .2s; } .arrow-head { stroke-dasharray: 9;
stroke-dashoffset: -9; transition: stroke-dashoffset ease-in .2s; }
svg:hover line { stroke-dashoffset: 0; } svg:hover .arrow-line {
transition: stroke-dashoffset ease-in .5s; } svg:hover .arrow-head {
transition: stroke-dashoffset ease-in .2s .5s; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
svg line {
fill: #000;
stroke: #000;
stroke-width: 1px;
}
.arrow-line {
stroke-dasharray: 60;
stroke-dashoffset: 60;
transition: stroke-dashoffset ease-in .5s .2s;
}
.arrow-head {
stroke-dasharray: 9;
stroke-dashoffset: -9;
transition: stroke-dashoffset ease-in .2s;
}
svg:hover line {
stroke-dashoffset: 0;
}
svg:hover .arrow-line {
transition: stroke-dashoffset ease-in .5s;
}
svg:hover .arrow-head {
transition: stroke-dashoffset ease-in .2s .5s;
}

必发88 39

询问了那多个根本属性,动作效果剩下的三座大山,就落在了 dasharray 与 dashoffset
值的计算上了。这么些手续或者从未什么捷径,简单的直线、弧线之类的或许还可以够口算口算,别的的歇斯底里图形也就唯有多试那条傻路可走,要是您是图形高手就当自己没说。

别的多个描边属性:stroke-linecapstroke-linejoinstroke-miterlimit
由于暂且用不上惨遭抛弃,具体可参考MDN-SVG Tutorial-Fills and
Strokes,stroke-miterlimit
详解SVG 切磋之路(16)-
Stroke-miterlimit。

Step七 、将区别部位的卡通片组成到一道

  • 肉眼的卡通片是从嘴巴旋转完毕起来,到嘴巴变形实现收尾,因而和嘴巴的卡通一样,笔者设置了八个照应的重庆大学时间点。
  • 为了让衔接更顺畅,眼睛的卡通片初始比嘴巴变形初叶有个别提前了一小点。

必发88 40

参考:

  • MDN-SVG文档
  • 《SVG精髓》- 人民邮政和邮电通讯出版社

    1 赞 2 收藏
    评论

必发88 41

图形绘制

箭头的绘图只用到了路线中最简单易行的直线路径 line,SVG 中还有矩形
rect、圆形 circle、椭圆 ellipse、折线 polyline、多边形 polygon
以及万能的路径
path。之所以将一部分规整的图纸单独出标签,是为着代码的可读性更强些,毕竟SVG 的可读性已经没那么强了……

整理图形的属性较好通晓(具体可参看MDN-SVG
Tutorial-Path),这里深远讲解一下怎么样阅读路径
path 的代码。

2.5 <rect>标签

<rect>标签用于绘制矩形。

<svg width=”300″ height=”180″> <rect x=”0″ y=”0″ height=”100″
width=”200″ style=”stroke: #70d5dd; fill: #dd524b” /> </svg>

1
2
3
<svg width="300" height="180">
  <rect x="0" y="0" height="100" width="200" style="stroke: #70d5dd; fill: #dd524b" />
</svg>

<rect>x属性和y属性,钦命了矩形左上角端点的横坐标和纵坐标;width属性和height属性内定了矩形的宽窄和惊人(单位像素)。

纯属坐标绘制指令

这组命令的参数代表的是纯属坐标。要是当前画笔所在的职位为(x0,y0),则上边包车型客车相对坐标指令代表的含义如下所示:

必发88 42

一举手一投足画笔指令 M,画直线指令:LHV,闭合指令 Z
都比较简单;上面重点看看绘制曲线的多少个指令。

2.6 <ellipse>标签

<ellipse>标签用于绘制椭圆。

<svg width=”300″ height=”180″> <ellipse cx=”60″ cy=”60″ ry=”40″
rx=”20″ stroke=”black” stroke-width=”5″ fill=”silver”/> </svg>

1
2
3
<svg width="300" height="180">
  <ellipse cx="60" cy="60" ry="40" rx="20" stroke="black" stroke-width="5" fill="silver"/>
</svg>

<ellipse>cx属性和cy属性,内定了椭圆中央的横坐标和纵坐标(单位像素);rx属性和ry属性,钦命了椭圆横向轴和纵向轴的半径(单位像素)。

绘图圆弧指令:A rx ry x-axis-rotation large-arc-flag sweep-flag x y

用圆弧连接3个点比较复杂,情状也很多,所以那么些命令有8个参数,分别控制曲线的的依次属性。上边解释一下数值的意思:
rx,ry 是弧所在的椭圆的半长轴、半短轴长度,rx 为 x 轴上的轴长,ry 为 y
轴上的周长。
x-axis-rotation 是此段弧的顺时针旋转角度,负数代表逆时针转动的角度。
large-arc-flag
两个值:101表示大角度弧线,0意味着小角度弧线。
sweep-flag
两个值:101代表从起源到终点弧线绕中央顺时针方向,0代表逆时针方向。
x,y 是弧终端坐标。

为了更好的知道圆弧的绘图,大家来试试手动画一下 MDN
上的范例:

XHTML

<svg width=”320px” height=”320px” viewBox=”0 0 320 320″> <path
d=”M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55 152.45 A 30 50
-45 0 1 215.1 109.9 L 315 10″ stroke=”black” fill=”green”
stroke-width=”2″ fill-opacity=”0.5″/> </svg>

1
2
3
4
5
6
7
8
<svg width="320px" height="320px" viewBox="0 0 320 320">
<path d="M10 315
L 110 215
A 30 50 0 0 1 162.55 162.45
L 172.55 152.45
A 30 50 -45 0 1 215.1 109.9
L 315 10" stroke="black" fill="green" stroke-width="2" fill-opacity="0.5"/>
</svg>

必发88 43

首先是 ML 指令:

必发88 44

然后是 A 指令的绘图,在这一步能够看来 large-arc-flag(大小弧)与
sweep-flag(弧度方向)值的震慑。

在本例中,弧度标记值为0,意味着选取小弧;弧度方向标记值为1,意味着选拔起点到终端为顺时针方向的那条弧(别眨眼):

必发88 45

接下去大家简要掉 L
指令的绘图,来看望下三个圆弧。这些圆弧的团团转角度(x-axis-rotation)发生了变化,体会一下差距:

必发88 46

看了这么久,是还是不是挺纳闷这么难看的事物怎么一定要读懂?其实也不是强迫各位看官能变成脑补
SVG
图形的天才,只是大略读懂这么些难看的数字,在做动画的时候才会心里有底手上有劲点,至少差不离知道那条东西洋画出来是什么样,而后再指向它写写动作效果。所以,大家后续看看图形界的万金油——贝塞尔曲线吧~!

……贝塞尔曲线被周边地在处理器图形中用来为平滑曲线建模。贝塞尔曲线是矢量图形文件和对应软件(如
PostScript、PDF
等)能够处理的唯一曲线,用于光滑地类似别的曲线。三遍和一次贝塞尔曲线最为常用。
引用来源:维基百科——贝塞尔曲线——应用

维基上有详实的贝塞尔曲线绘制公式与动图展示,那里就不做展开。

path 中的贝塞尔曲线指令共有多少个:CSQT。SVG
只提供了最高阶到三次的贝塞尔曲线绘制指令,事实上海大学部分制图软件也是那般。

2.7 <polygon>标签

<polygon>标签用于绘制多边形。

<svg width=”300″ height=”180″> <polygon fill=”green”
stroke=”orange” stroke-width=”1″ points=”0,0 100,0 100,100 0,100
0,0″/> </svg>

1
2
3
<svg width="300" height="180">
  <polygon fill="green" stroke="orange" stroke-width="1" points="0,0 100,0 100,100 0,100 0,0"/>
</svg>

<polygon>points属性钦定了种种端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点期间用空格分隔。

3回贝塞尔曲线:C x1 y1, x2 y2, x y (或者 c dx1, dy1, dx2, dy2, dx dy)

三遍贝塞尔曲线有七个控制点,正是(x1,y1)和(x2,y2),最前边(x,y)代表曲线的极限。

其如今候依然上动图相比较方便。以下边的代码段为例:

1
2
3
<svg width=“300” height=“100” viewBox=“0 0 60 30”>
<path d=“M10 10 C 20 20, 40 20, 50 10” stroke=“#000” fill=“transparent”></path>
</svg>

绘图进程如下:

必发88 47

(手残,顺滑绘制进度请依旧参考维基君。)

凭借 PS 中的钢笔工具依据协理线能便捷画出路径,能够防去那抽象的乘除过程。

必发88 48

2.8 <path>标签

<path>标签用于制路径。

<svg width=”300″ height=”180″> <path d=” M 18,3 L 46,3 L 46,40
L 61,40 L 32,68 L 3,40 L 18,40 Z “></path> </svg>

1
2
3
4
5
6
7
8
9
10
11
12
<svg width="300" height="180">
<path d="
  M 18,3
  L 46,3
  L 46,40
  L 61,40
  L 32,68
  L 3,40
  L 18,40
  Z
"></path>
</svg>

<path>d本性表示绘制顺序,它的值是三个长字符串,每种字母代表叁个绘制动作,后边跟着坐标。

  • M:移动到(moveto)
  • L:画直线到(lineto)
  • Z:闭合路径
简化版二次贝塞尔曲线:S x2 y2, x y (或者 s dx2 dy2, dx dy)

诸多时候,曲线不止一个弧,为了平滑对接,第一个曲线的控制点常常是第一个曲线控制点在曲线其它一方面包车型地铁映射点。这么些时候能够动用那几个简化版本。

那里要留意的是,如若 S 指令前边没有任何的 S 指令或 C
指令,这么些时候会认为四个控制点是千篇一律的,退化成一次贝塞尔曲线的金科玉律;假如
S 指令是用在此外三个 S 指令只怕 C 指令前边,那些时候背后这么些 S
指令的率先个控制点会暗中同意设置为最近的那么些曲线的第②个控制点的二个映射点。——《突袭
HTML5 之 SVG 2D 入门2 –
图形绘制》

此间关键讲解一下 S 指令中每种点对应的岗位。同样借用 MDN 上的言传身教:

XHTML

<svg width=”190″ height=”160″> <path d=”M10 80 C 40 10, 65 10,
95 80 S 150 150, 180 80″ stroke=”black” fill=”transparent”/>
</svg>

1
2
3
<svg width="190" height="160">
<path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="black" fill="transparent"/>
</svg>

必发88 49

2.9 <text>标签

<text>标签用于绘制文本。

<svg width=”300″ height=”180″> <text x=”50″ y=”25″>Hello
World</text> </svg>

1
2
3
<svg width="300" height="180">
  <text x="50" y="25">Hello World</text>
</svg>

<text>x属性和y质量,表示文本区块基线(baseline)起源的横坐标和纵坐标。文字的样式能够用classstyle属性钦点。

二次贝塞尔曲线:Q x1 y1, x y (或者 q dx1 dy1, dx dy)

经历了二遍贝塞尔曲线的洗礼,一次贝塞尔曲线看起来真是亲切。

XHTML

<svg width=”190″ height=”160″> <path d=”M10 80 Q 95 10, 180 80″
stroke=”black” fill=”transparent”/> </svg>

1
2
3
<svg width="190" height="160">
<path d="M10 80 Q 95 10, 180 80" stroke="black" fill="transparent"/>
</svg>

必发88 50

注:PS
中的钢笔工具绘制二遍贝塞尔曲线只好通过叁回贝塞尔曲线实行模拟,可能1遍贝塞尔曲线最标准的绘图方法正是由此代码了啊。这里有2个可视化
Canvas 绘制贝塞尔曲线的网站——Canvas Quadratic Curve
Example,完成格局比
SVG 还复杂[抠鼻]。

2.10 <use>标签

<use>标签用于复制多个形状。

<svg viewBox=”0 0 30 10″ xmlns=”;
<circle id=”myCircle” cx=”5″ cy=”5″ r=”4″/> <use
href=”#myCircle” x=”10″ y=”0″ fill=”blue” /> <use
href=”#myCircle” x=”20″ y=”0″ fill=”white” stroke=”blue” />
</svg>

1
2
3
4
5
6
<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
  <circle id="myCircle" cx="5" cy="5" r="4"/>
 
  <use href="#myCircle" x="10" y="0" fill="blue" />
  <use href="#myCircle" x="20" y="0" fill="white" stroke="blue" />
</svg>

<use>href品质钦命所要复制的节点,x属性和y属性是<use>左上角的坐标。别的,还足以钦命widthheight坐标。

简化版1回贝塞尔曲线:T x y(或者 t dx dy)

S 指令类似,为了更顺滑的多弧曲线,T
指令直接内定曲线终点,控制点自动测算。

同时,如果 T 指令只在上三个限令为 Q 或者 T
指令的图景下有效,不然当作 L 指令执行。

算是把贝塞尔讲完了……

2.11 <g>标签

<g>标签用于将七个造型组成二个组(group),方便复用。

<svg width=”300″ height=”100″> <g id=”myCircle”> <text
x=”25″ y=”20″>圆形</text> <circle cx=”50″ cy=”50″
r=”20″/> </g> <use href=”#myCircle” x=”100″ y=”0″
fill=”blue” /> <use href=”#myCircle” x=”200″ y=”0″ fill=”white”
stroke=”blue” /> </svg>

1
2
3
4
5
6
7
8
9
<svg width="300" height="100">
  <g id="myCircle">
    <text x="25" y="20">圆形</text>
    <circle cx="50" cy="50" r="20"/>
  </g>
 
  <use href="#myCircle" x="100" y="0" fill="blue" />
  <use href="#myCircle" x="200" y="0" fill="white" stroke="blue" />
</svg>

第一个神奇的动作效果

偷偷用2个箭头把 SVG 的填色、描边、路径都给讲完了,然则,SVG
能用到的还不止这一个。开玩笑,Web 界的猪——浑身都以宝——可不是吹的。

必发88 51

第壹,大家阅览一下以此播放键的布局的落到实处况势(Codepen)(注:为了能直观地来看功用,笔者将
.play-icon-blend
的填写与描边改为了中绿,原例子中为橄榄黄):

XHTML

<svg class=”play-icon-vector” x=”0″ y=”0″ width=”50″ height=”50″
viewBox=”0 0 50 50″> <defs> <circle
id=”play-circle-template” cx=”25″ cy=”25″ r=”25″></circle>
</defs>   <use class=”play-icon-blend”
xlink:href=”#play-circle-template” fill=”#000″ stroke=”#000″
stroke-width=”4px”></use> <use class=”play-icon-circle”
xlink:href=”#play-circle-template” fill=”#fff” stroke=”#fff”
stroke-width=”2px”></use> <path class=”play-icon-polygon”
d=”M31.49,24.31a0.73,0.73,0,0,1,0,1.38l-8.27,5.64A0.74,0.74,0,0,1,22,30.64V19.36a0.74,0.74,0,0,1,1.22-.69Z”
fill=”#fff”></path> </svg>

1
2
3
4
5
6
7
8
9
<svg class="play-icon-vector" x="0" y="0" width="50" height="50" viewBox="0 0 50 50">
<defs>
<circle id="play-circle-template" cx="25" cy="25" r="25"></circle>
</defs>
 
<use class="play-icon-blend" xlink:href="#play-circle-template" fill="#000" stroke="#000" stroke-width="4px"></use>
<use class="play-icon-circle" xlink:href="#play-circle-template" fill="#fff" stroke="#fff" stroke-width="2px"></use>
<path class="play-icon-polygon" d="M31.49,24.31a0.73,0.73,0,0,1,0,1.38l-8.27,5.64A0.74,0.74,0,0,1,22,30.64V19.36a0.74,0.74,0,0,1,1.22-.69Z" fill="#fff"></path>
</svg>

CSS

.play-icon-vector { overflow: visible; } .play-icon-circle ,
.play-icon-polygon { mix-blend-mode: exclusion; transition: opacity .3s
cubic-bezier(.08,.03,.22,.87); } .play-icon-blend { transform-origin:
center; transform: scale(0); transition: transform .25s
cubic-bezier(.08,.03,.22,.87); } .play-icon-vector:hover
.play-icon-blend { transform: scale(1.1); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.play-icon-vector {
overflow: visible;
}
.play-icon-circle ,
.play-icon-polygon {
mix-blend-mode: exclusion;
transition: opacity .3s cubic-bezier(.08,.03,.22,.87);
}
.play-icon-blend {
transform-origin: center;
transform: scale(0);
transition: transform .25s cubic-bezier(.08,.03,.22,.87);
}
.play-icon-vector:hover .play-icon-blend {
transform: scale(1.1);
}

这里顺带用了眨眼之间间下 CSS3
的滤镜
mix-blend-mode(SVG
也有滤镜作用,那里不做牵线,感兴趣的能够移动《突袭 HTML5 之 SVG 2D
入门10 –
滤镜》)。那里运用的值
exclusion
的成效,是在叠加区域只呈现亮色,上面是运用了同样滤镜的图形与寻常图片的自己检查自纠图,感受一下:

必发88 52

图片源于:CSS-Tricks-mix-blend-mode

能够看到代码里还冒出了一部分了不可的竹签——
<defs><use>。接下来,我们就来打探一下它们。

第③我们知道,通过中间圆圈的缩放,再加上国外国语高校围圆圈与大旨三角的增大效应,完毕了这些hover 效果。也就象征,圆圈在那里用到三遍。这几个时候就足以采纳 SVG
里路径的选定与引用功能。

2.12 <defs>标签

<defs>标签用于自定义形状,它个中的代码不会显得,仅供引用。

<svg width=”300″ height=”100″> <defs> <g
id=”myCircle”> <text x=”25″ y=”20″>圆形</text> <circle
cx=”50″ cy=”50″ r=”20″/> </g> </defs> <use
href=”#myCircle” x=”0″ y=”0″ /> <use href=”#myCircle” x=”100″
y=”0″ fill=”blue” /> <use href=”#myCircle” x=”200″ y=”0″
fill=”white” stroke=”blue” /> </svg>

1
2
3
4
5
6
7
8
9
10
11
12
<svg width="300" height="100">
  <defs>
    <g id="myCircle">
      <text x="25" y="20">圆形</text>
      <circle cx="50" cy="50" r="20"/>
    </g>
  </defs>
 
  <use href="#myCircle" x="0" y="0" />
  <use href="#myCircle" x="100" y="0" fill="blue" />
  <use href="#myCircle" x="200" y="0" fill="white" stroke="blue" />
</svg>

SVG 的录用与引用

二种集合标签:<g><symbol><defs>,都以用于将零散的图样组合成2个完好无损。不同在于:

  • <g>:组合标签。添加 id 属性来作为引用的钩,可在 <g>
    标签上设置那组成分的有关属性(填色、描边等等)。
  • <symbol>:模板标签。与 <g> 标签一样,通过 id
    举行引用。区别点在于,symbol 成分本人不会被渲染;symbol
    成分拥有属性 viewBoxpreserveAspectRatio,这么些允许 symbol
    缩放图形。
  • <defs>:定义标签。不仅仅是图片对象的合集,还足以是渐变效果、蒙版、滤镜等等,设置好
    id,在相应的习性(例如渐变正是 fill、蒙版就是 mask、滤镜就是
    filter)中引用即可,引用格式为“url(#id)”。具体育赛事例参看《SVG
    研讨之路 (18) – 再談
    defs》。

更详细的分歧见《突袭 HTML5 之 SVG 2D 入门7 –
重用与引用》。

上述三种集合的引用统一行使 <use> 标签。xlink:href 属性钦赐引用的
id

use 成分的效益进程就相当于把被引述的对象深拷贝一份到独门的非公开的
DOM 树中;这棵树的父节点是 use
成分。尽管是非公开的DOM节点,然则精神上可能 DOM
节点,所以被引述对象的富有属性值、动画、事件、 CSS
的相关安装等都会拷贝多来并都如故会起效果,而且这个节点也会继承 use
元素和 use
祖先的有关属性(注意引用成分是深拷贝,那么些拷贝过来的因素与原来的因素已经无关系了,所以那里不会继续被引述成分祖先节点的习性),即使那一个节点自己有连带(CSS)属性,还会覆盖继承来的属性,那些与常见的DOM节点是一模一样的,所以对use成分使用“visibility:hidden”时要小心,并不一定会起效果。不过由于那有的节点是非公开的,在
DOM 操作中,也只可以见到 use 成分,所以也只能操作到 use 元素。

在 SVG Sprite 中,<use> 的使用比较猖狂(《拥抱 Web 设计新取向:SVG
Sprites
实践应用》,同时也论及了
SVG 的匹配情形),而当 SVG
图形代码与引用部分分离开时,想针对图形中的某一某个进行拍卖就会来得尤其费劲(只可以看到
use 结点),那一个时候,打开 shadow DOM
的展示,包你一览无余(具体操作方法见《神奇的 Shadow
DOM》)。

必发88 53

打开了 shadow DOM 显示的 use 标签

下边就来看2个非图形引用的事例。在前头我们精通了,如若要描边动作效果,那修改
stroke-dashoffset 就能够达到效果。然则那种办法本人正是使用了虚线的
hack,假如大家想要做三个虚线的描线动作效果呢?比如:

必发88 54

其暂时候 stroke-dasharraystroke-offset
的同盟是无力回天做到的,因为她们动起来本身正是虚线在移动。所以大家须要换个思路,描线动画照旧十二分描线动画,只是虚线的绘图必要运用另一个hack —— 蒙版。

2.13 <pattern>标签

<pattern>标签用于自定义2个样子,该造型能够被引用来平铺四个区域。

JavaScript

<svg width=”500″ height=”500″> <defs> <pattern id=”dots”
x=”0″ y=”0″ width=”100″ height=”100″ patternUnits=”userSpaceOnUse”>
<circle fill=”#bee9e8″ cx=”50″ cy=”50″ r=”35″ /> </pattern>
</defs> <rect x=”0″ y=”0″ width=”100%” height=”100%”
fill=”url(#dots)” /> </svg>

1
2
3
4
5
6
7
8
<svg width="500" height="500">
  <defs>
    <pattern id="dots" x="0" y="0" width="100" height="100" patternUnits="userSpaceOnUse">
      <circle fill="#bee9e8" cx="50" cy="50" r="35" />
    </pattern>
  </defs>
  <rect x="0" y="0" width="100%" height="100%" fill="url(#dots)" />
</svg>

上边代码中,<pattern>标签将1个圆形定义为dots模式。patternUnits="userSpaceOnUse"表示<pattern>的增长幅度和尺寸是实际上的像素值。然后,钦赐那么些形式去填充上面包车型客车矩形。

蒙版

SVG 中的蒙版有三种——剪裁cliping <clipPath> 与遮罩mask
<mask>,都要求在 <defs> 中定义,然后通过相应的性质进行引用。

XHTML

<svg> <defs> <!– 剪裁的定义 –> <clipPath
id=”cliping”>…</clipPath> <!– 遮罩的定义 –> <mask
id=”mask”>…</mask> </defs>   <!– 剪裁的引用 –>
<circle clip-path=”url(#cliping)”></circle> <!–
遮罩的引用 –> <circle clip-path=”url(#mask)”></circle>
</svg>

1
2
3
4
5
6
7
8
9
10
11
12
13
<svg>
<defs>
<!– 剪裁的定义 –>
<clipPath id="cliping">…</clipPath>
<!– 遮罩的定义 –>
<mask id="mask">…</mask>
</defs>
 
<!– 剪裁的引用 –>
<circle clip-path="url(#cliping)"></circle>
<!– 遮罩的引用 –>
<circle clip-path="url(#mask)"></circle>
</svg>

注:以上代码为了直观反映两者的采纳方法,已去除其他不相干代码,不可直接运营。

剪裁与遮罩的区分在于,剪裁是遵照定义的形制界限泾渭分明地开展图像的来得与隐藏:

而遮罩相较于剪裁,多了渐变展现图像的效能,只要在 <mask>
中封装渐变的概念即可。遮罩的显得策略是:

越黑越透明,越白越不透明,而遮色片(注:即遮罩)唯有黑到白的灰階分布,所以假若作為遮色片的顏色是灰階以外的顏色,都會被轉換為灰階。——引用来源《SVG
切磋之路 (9) – Clipping and
Masking》

由此遮罩的效益实在是包蕴剪裁的,当遮罩使用的是纯黑的图像时,效用雷同剪裁。

必发88 55

虚线的描线动作效果结合剪裁可能遮罩即能够形成(Codepen):

XHTML

<svg width=”300″ height=”100″ viewBox=”0 0 300 100″> <defs>
<clipPath id=”dash” class=”dash”> <rect x=”0″ y=”20″ width=”10″
height=”34″></rect> <rect x=”20″ y=”20″ width=”10″
height=”34″></rect> <rect x=”40″ y=”20″ width=”10″
height=”34″></rect> <rect x=”60″ y=”20″ width=”10″
height=”34″></rect> <rect x=”80″ y=”20″ width=”10″
height=”34″></rect> </clipPath> <mask id=”mask-dash”
class=”mask_dash”> <rect x=”0″ y=”20″ width=”10″
height=”34″></rect> <rect x=”20″ y=”20″ width=”10″
height=”34″></rect> <rect x=”40″ y=”20″ width=”10″
height=”34″></rect> <rect x=”60″ y=”20″ width=”10″
height=”34″></rect> <rect x=”80″ y=”20″ width=”10″
height=”34″></rect> </mask> </defs>   <g
clip-path=”url(#dash)”> <line class=”line” x1=”0″ y1=”28″
x2=”100″ y2=”28″></line> </g> <g
mask=”url(#mask-dash)”> <rect x=”0″ y=”36″ width=”100″ height=”8″
fill=”#eee”></rect> <line class=”line” x1=”0″ y1=”40″
x2=”100″ y2=”40″></line> </g> </svg>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<svg width="300" height="100" viewBox="0 0 300 100">
<defs>
<clipPath id="dash" class="dash">
<rect x="0" y="20" width="10" height="34"></rect>
<rect x="20" y="20" width="10" height="34"></rect>
<rect x="40" y="20" width="10" height="34"></rect>
<rect x="60" y="20" width="10" height="34"></rect>
<rect x="80" y="20" width="10" height="34"></rect>
</clipPath>
<mask id="mask-dash" class="mask_dash">
<rect x="0" y="20" width="10" height="34"></rect>
<rect x="20" y="20" width="10" height="34"></rect>
<rect x="40" y="20" width="10" height="34"></rect>
<rect x="60" y="20" width="10" height="34"></rect>
<rect x="80" y="20" width="10" height="34"></rect>
</mask>
</defs>
 
<g clip-path="url(#dash)">
<line class="line" x1="0" y1="28" x2="100" y2="28"></line>
</g>
<g mask="url(#mask-dash)">
<rect x="0" y="36" width="100" height="8" fill="#eee"></rect>
<line class="line" x1="0" y1="40" x2="100" y2="40"></line>
</g>
</svg>

CSS

.mask_dash rect{ fill: #fff; } .line { stroke: #000; stroke-width:
8px; stroke-dasharray: 100; stroke-dashoffset: 100; transition:
stroke-dashoffset ease-in .5s; } svg:hover .line { stroke-dashoffset: 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
.mask_dash rect{
fill: #fff;
}
.line {
stroke: #000;
stroke-width: 8px;
stroke-dasharray: 100;
stroke-dashoffset: 100;
transition: stroke-dashoffset ease-in .5s;
}
svg:hover .line {
stroke-dashoffset: 0;
}

瞩目到上面使用了遮罩的集合里多了2个方形图像,是因为遮罩对于图片尺寸的渴求更为严俊,line
在它的眼底不是东西,不提供任何作用协理,可是假若加个方形垫背,line
就被接受了[翻白眼]。所以涉及到切割的蒙版,请尽大概接纳 clipPath

2.14 <image>标签

<image>标签用于插入图片文件。

<svg viewBox=”0 0 100 100″ width=”100″ height=”100″> <image
xlink:href=”path/to/image.jpg” width=”50%” height=”50%”/>
</svg>

1
2
3
4
<svg viewBox="0 0 100 100" width="100" height="100">
  <image xlink:href="path/to/image.jpg"
    width="50%" height="50%"/>
</svg>

下面代码中,<image>xlink:href个性表示图像的源于。

总结

写到那里,阿婆主气数已尽,SVG
是个深坑,那里也只可以借着八个例子扯扯若干特点,等下回心境好了,阿婆主再拎多少个出来说说(也是私自,人的
SVG 笔记都是1性子子一篇的)。上边我们来给那篇凌乱的篇章做个梳理:

  • 今天大家贯彻了五个动作效果——
    • 箭头描线动效
    • 播放按钮滤镜动作效果
    • 虚线描线动作效果
  • 动作效果来源于 WLS-Adobe
  • 聊到了 SVG 的多少个标签
    • <path>
    • <g>
    • <symbol>
    • <defs>
    • <use>
    • <clipPath>
    • <mask>
  • 以及质量
    • viewBox
    • preserveAspectRatio
    • fill
    • stroke
    • stroke-dasharray
    • stroke-dashoffset
    • d
    • clip-path
    • mask
  • 动作效果实现对应的关键点
    • 箭头——stroke-dasharraystroke-dashoffset
    • 播放按钮——<defs><use>
    • 虚线——<clipPath><mask>clip-pathmaskstroke-dasharraystroke-dashoffset

文中引用到的材料(前方高能预先警告):

  • 《突袭 HTML5 之 SVG 2D
    入门》,沙场秋点兵

    • 2.图形绘制
    • 4.笔画与填充
    • 6.坐标与转移
    • 7.重用与引用
    • 9.蒙板
    • 10.滤镜
  • 《SVG 商量之路》,Oxxo Studio
    • 9.Clipping and
      Masking
    • 16.Stroke-miterlimit
    • 18.再談
      defs
    • 23.理解 viewport 與
      viewbox
  • SVG
    Tutorial,MDN

    • Positions
    • Fills and
      Strokes
    • Path
  • 贝塞尔曲线,维基百科
  • mix-blend-mode,Robin
    Rendle,CSS-Tricks
  • 《拥抱 Web 设计新取向:SVG Pepsi-Colas
    实践应用》,高大师,坑坑洼洼实验室
  • 《神奇的 Shadow
    DOM》,暖暖,坑坑洼洼实验室

    1 赞 6 收藏 1
    评论

必发88 56

2.15 <animate>标签

<animate>标签用于产生动画效果。

<svg width=”500px” height=”500px”> <rect x=”0″ y=”0″
width=”100″ height=”100″ fill=”#feac5e”> <animate
attributeName=”x” from=”0″ to=”500″ dur=”2s” repeatCount=”indefinite”
/> </rect> </svg>

1
2
3
4
5
<svg width="500px" height="500px">
  <rect x="0" y="0" width="100" height="100" fill="#feac5e">
    <animate attributeName="x" from="0" to="500" dur="2s" repeatCount="indefinite" />
  </rect>
</svg>

上边代码中,矩形会频频移动,爆发动画效果。

<animate>的天性含义如下。

  • attributeName:爆发动画效果的属性名。
  • from:单次动画的起初值。
  • to:单次动画的收尾值。
  • dur:单次动画的持续时间。
  • repeatCount:动画的大循环形式。

能够在八个属性上边定义动画。

<animate attributeName=”x” from=”0″ to=”500″ dur=”2s”
repeatCount=”indefinite” /> <animate attributeName=”width”
to=”500″ dur=”2s” repeatCount=”indefinite” />

1
2
<animate attributeName="x" from="0" to="500" dur="2s" repeatCount="indefinite" />
<animate attributeName="width" to="500" dur="2s" repeatCount="indefinite" />

2.16 <animateTransform>标签

<animate>标签对 CSS
transform质量不起效率,假如急需变形,就要动用<animateTransform>标签。

<svg width=”500px” height=”500px”> <rect x=”250″ y=”250″
width=”50″ height=”50″ fill=”#4bc0c8″> <animateTransform
attributeName=”transform” type=”rotate” begin=”0s” dur=”10s” from=”0 200
200″ to=”360 400 400″ repeatCount=”indefinite” /> </rect>
</svg>

1
2
3
4
5
<svg width="500px" height="500px">
  <rect x="250" y="250" width="50" height="50" fill="#4bc0c8">
    <animateTransform attributeName="transform" type="rotate" begin="0s" dur="10s" from="0 200 200" to="360 400 400" repeatCount="indefinite" />
  </rect>
</svg>

地点代码中,<animateTransform>的机能为旋转(rotate),这时fromto属性值有多少个数字,第二个数字是角度值,第三个值和第5个值是旋转中央的坐标。from="0 200 200"代表开端时,角度为0,围绕(200, 200)始发旋转;to="360 400 400"意味着甘休时,角度为360,围绕(400, 400)旋转。

三、JavaScript 操作

3.1 DOM 操作

假诺 SVG 代码直接写在 HTML 网页之中,它就改成网页 DOM
的一部分,能够平素用 DOM 操作。

<svg id=”mysvg” xmlns=”” viewBox=”0 0 800
600″ preserveAspectRatio=”xMidYMid meet” > <circle id=”mycircle”
cx=”400″ cy=”300″ r=”50″ /> <svg>

1
2
3
4
5
6
7
8
<svg
  id="mysvg"
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 800 600"
  preserveAspectRatio="xMidYMid meet"
>
  <circle id="mycircle" cx="400" cy="300" r="50" />
<svg>

上边代码插入网页之后,就足以用 CSS 定制样式。

CSS

circle { stroke-width: 5; stroke: #f00; fill: #ff0; } circle:hover {
stroke: #090; fill: #fff; }

1
2
3
4
5
6
7
8
9
10
circle {
  stroke-width: 5;
  stroke: #f00;
  fill: #ff0;
}
 
circle:hover {
  stroke: #090;
  fill: #fff;
}

接下来,能够用 JavaScript 代码操作 SVG。

var mycircle = document.getElementById(‘mycircle’);
mycircle.addEventListener(‘click’, function(e) { console.log(‘circle
clicked – enlarging’); mycircle.setAttribute(‘r’, 60); }, false);

1
2
3
4
5
6
var mycircle = document.getElementById(‘mycircle’);
 
mycircle.addEventListener(‘click’, function(e) {
  console.log(‘circle clicked – enlarging’);
  mycircle.setAttribute(‘r’, 60);
}, false);

上面代码钦定,假诺点击图片,就改写circle元素的r属性。

3.2 获取 SVG DOM

使用<object><iframe><embed>标签插入 SVG 文件,能够赢得 SVG
DOM。

var svgObject = document.getElementById(‘object’).contentDocument; var
svgIframe = document.getElementById(‘iframe’).contentDocument; var
svgEmbed = document.getElementById(’embed’).getSVGDocument();

1
2
3
var svgObject = document.getElementById(‘object’).contentDocument;
var svgIframe = document.getElementById(‘iframe’).contentDocument;
var svgEmbed = document.getElementById(’embed’).getSVGDocument();

专注,假设运用<img>标签插入 SVG 文件,就不可能赢得 SVG DOM。

3.3 读取 SVG 源码

由于 SVG 文件正是一段 XML 文本,因而得以经过读取 XML 代码的法子,读取
SVG 源码。

<div id=”svg-container”> <svg
xmlns=””
xmlns:xlink=”” xml:space=”preserve”
width=”500″ height=”440″ > <!– svg code –> </svg>
</div>

1
2
3
4
5
6
7
8
9
<div id="svg-container">
  <svg
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xml:space="preserve" width="500" height="440"
  >
    <!– svg code –>
  </svg>
</div>

使用XMLSerializer实例的serializeToString()主意,获取 SVG
成分的代码。

var svgString = new XMLSerializer()
.serializeToString(document.querySelector(‘svg’));

1
2
var svgString = new XMLSerializer()
  .serializeToString(document.querySelector(‘svg’));

3.4 SVG 图像转为 Canvas 图像

首先,须求新建一个Image指标,将 SVG
图像钦点到该Image对象的src属性。

JavaScript

var img = new Image(); var svg = new Blob([必发88,svgString], {type:
“image/svg+xml;charset=utf-8”}); var DOMURL = self.URL || self.webkitURL
|| self; var url = DOMURL.createObjectURL(svg); img.src = url;

1
2
3
4
5
6
7
var img = new Image();
var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
 
var DOMURL = self.URL || self.webkitURL || self;
var url = DOMURL.createObjectURL(svg);
 
img.src = url;

然后,当图像加载成功后,再将它绘制到<canvas>元素。

JavaScript

img.onload = function () { var canvas =
document.getElementById(‘canvas’); var ctx = canvas.getContext(‘2d’);
ctx.drawImage(img, 0, 0); };

1
2
3
4
5
img.onload = function () {
  var canvas = document.getElementById(‘canvas’);
  var ctx = canvas.getContext(‘2d’);
  ctx.drawImage(img, 0, 0);
};

四、实例:折线图

下边将一张数据表格画成折线图。

Date |Amount —–|—— 2014-01-01 | $10 2014-02-01 | $20 2014-03-01 |
$40 2014-04-01 | $80

1
2
3
4
5
6
Date |Amount
—–|——
2014-01-01 | $10
2014-02-01 | $20
2014-03-01 | $40
2014-04-01 | $80

上边的图片,能够画成3个坐标系,Date用作横轴,Amount作为纵轴,四行数据画成2个数据点。

<svg width=”350″ height=”160″> <g class=”layer”
transform=”translate(60,10)”> <circle r=”5″ cx=”0″ cy=”105″ />
<circle r=”5″ cx=”90″ cy=”90″ /> <circle r=”5″ cx=”180″ cy=”60″
/> <circle r=”5″ cx=”270″ cy=”0″ /> <g class=”y axis”>
<line x1=”0″ y1=”0″ x2=”0″ y2=”120″ /> <text x=”-40″ y=”105″
dy=”5″>$10</text> <text x=”-40″ y=”0″
dy=”5″>$80</text> </g> <g class=”x axis”
transform=”translate(0, 120)”> <line x1=”0″ y1=”0″ x2=”270″ y2=”0″
/> <text x=”-30″ y=”20″>January 2014</text> <text
x=”240″ y=”20″>April</text> </g> </g> </svg>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<svg width="350" height="160">
  <g class="layer" transform="translate(60,10)">
    <circle r="5" cx="0"   cy="105" />
    <circle r="5" cx="90"  cy="90"  />
    <circle r="5" cx="180" cy="60"  />
    <circle r="5" cx="270" cy="0"   />
 
    <g class="y axis">
      <line x1="0" y1="0" x2="0" y2="120" />
      <text x="-40" y="105" dy="5">$10</text>
      <text x="-40" y="0"   dy="5">$80</text>
    </g>
    <g class="x axis" transform="translate(0, 120)">
      <line x1="0" y1="0" x2="270" y2="0" />
      <text x="-30"   y="20">January 2014</text>
      <text x="240" y="20">April</text>
    </g>
  </g>
</svg>

5、参考链接

  • Jon McPartland, An introduction to SVG
    animation
  • Alexander Goedde, SVG – Super Vector
    Graphics
  • Joseph Wegner, Learning
    SVG
  • biovisualize, Direct svg to canvas to png
    conversion
  • Tyler Sticka, Cropping Image Thumbnails with
    SVG
  • Adi Purdila, How to Create a Loader Icon With SVG
    Animations

(完)

1 赞 收藏
评论

必发88 57

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图