4

SVG 新司机开车指南

 2 years ago
source link: https://zhuanlan.zhihu.com/p/25016633
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

SVG 新司机开车指南

阿里巴巴 前端工程师

此文来自Tw93知乎专栏,欢迎交流。

TL,TR

SVG其相关特性远比想象中要强,本文首先介绍下SVG的相关定义、特点和Demo,接下来会介绍它的相关语法和动画,最后告诉大家如何使用和优化SVG。

确保大家一小时内可以开车上路..... 来不及解释了,快学车.....

v2-afeda25bcf594512ba420f6ec4297556_720w.png

定义

SVG(Scalable Vector Graphics)是可缩放矢量图形的缩写,基于可扩展标记语言XML来描述二维矢量图形的一种图形格式,由W3C制定,是一个开放标准。

特点

现在我们可以使用PNG、JPG来展示静态的图片,使用CSS3、JS或者挫一点的GIF来表示动画,厉害一点我们可以使用Canvas来绘图,那么为什么还要使用SVG呢?

  • 和PNG、GIF比较起来,文件体积更小,且可压缩性强;
  • 由于采用XML描述,可以轻易的被读取和修改,描述性更强;
  • 在放大或改变尺寸的情况下其图形质量不会有所损失,与分辨率无关,是可伸缩的;
  • SVG是面向未来 (W3C 标准)的,同时浏览器兼容性好;
  • 使用CSS 和 JS能很方便的进行控制,同时可以很轻易地描述路径动画;

和Canvas相比,Canvas基于像素,提供2D绘制函数,是一种HTML元素类型,依赖于HTML,只能通过脚本来绘制图形,Canvas提供的功能比较原始,适合像素处理,动态渲染和大数据量绘制的应用场景;
SVG为矢量,提供一系列图形元素(Rect, Path, Circle, Line …),还有完整的动画,事件机制,本身可以独立使用,也可以嵌入到HTML中,SVG很早就成为了国际标准,功能更完善,适合静态图片展示,高保真文档查看和打印的应用场景。

Demo

使用SVG可以做出什么比较好玩的东西呢?( GIF、SVG都不支持展示知乎??。。

上周团队(??臭不要脸插个很硬的广告,阿里飞猪前端团队在招人啦,详细:飞猪寻觅前端同学)有一个小的hackthon,就是通过代码来画这个Loading GIF,然后就边学边用SVG写了一个相同的loadng,体积从之前GIF的33KB变成了864B的SVG,详细见codepen代码

另外一些有趣的SVG可以查看30 Awesome SVG Animation For Your Inspiration这里。

二、坐标定位

学习SVG语法之前,我们可以来了解下SVG的坐标定位,这种坐标系统和我们小时候学习的绘图坐标是相反的,但是在HTML中都是用如下方式定位。即以页面的左上角为(0,0)坐标点,坐标以像素为单位,x轴正方向是向右,y轴正方向是向下

基础形状

SVG中提供了很多基础元素可以用来绘制基础的形状,譬如矩形、圆形、椭圆、多边形、折线、线条、路径等,同时可以将这些基础形状组合绘制出复杂的图像。

以上基础形状的展示效果可以通过这些代码表示出来:(强烈推荐使用codepen来看此演示,可以自己随意修改,地址请点击SVG Basic_Shapes)

<?xml version="1.0" standalone="no"?>
<svg width="600" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <!--矩形-->
  <rect x="10" y="10" width="30" height="60" stroke="#9B7B56" fill="transparent" stroke-width="10"/>
  <!--圆角矩形-->
  <rect x="60" y="10" rx="10" ry="10" width="60" height="40" stroke="#FF9090" fill="transparent" stroke-width="5"/> 
  <!--圆形-->
  <circle cx="180" cy="50" r="40" stroke="green" fill="#C3413D" stroke-width="5"/>  
   <!--椭圆-->
  <ellipse cx="320" cy="28" rx="80" ry="20" stroke="#FFC302" fill="transparent" stroke-width="5"/> 
  <!--直线-->
  <line x1="10" x2="50" y1="110" y2="150" stroke="orange" fill="transparent" stroke-width="5"/>
  <!--折线-->
  <polyline points="60 110 65 120 70115 75 130 80 125 85140 90 135 95 150 100 145" stroke="#9B7B56" fill="transparent" stroke-width="5"/>
  <!--多边形-->
  <polygon points="50 160 55 180 70180 60 190 65 205 50195 35 205 40 190 30 180 45 180" stroke="#FFC302" fill="transparent" stroke-width="5"/>
  <!--路径 -->
  <path d="M20,230 Q40,205 50,230 T90,230" fill="none" stroke="#9B7B56" stroke-width="5"/>
</svg>

最终展示是如下这样:

其他重要元素

  • <svg>:SVG的根元素,并且可以相互嵌套;
  • <g>:用来将SVG中的元素进行分组操作,分组后可以看成一个单独的形状,统一进行转换,同时g元素的样式可以被子元素继承,但是它没有X,Y属性,不过可以通过transform来移动它;
  • <def>:用于定义在SVG中可重用的元素,def元素不会直接展示出来,可以通过use元素来引用;
  • <use>:通过它来复用def元素,也包括<g>、<symbol>元素,使用<use xlink: href="#id"/>即可调用;
  • <text>:可以用它来实现word中的那种“艺术字”,很神奇的一个功能;
  • <image>:用它可以在SVG中嵌套对应的图片,并可以在图片上和周围做对应的处理。

可以类比于在切页面过程中,我们需要将我们画好的框框进行描边、填色、有时候还要加入渐变效果、转换、裁剪、等效果。

轮廓 stroke

stroke用于设置绘制对象线条的颜色,同时stroke有如下属性:

  • stroke-width:设置轮廓的宽度;
  • stroke-linecap:设置轮廓结尾处的渲染方式,value有butt(直接一刀切断)、square(保留一点切断)、round(圆弧切断) 3个设置值;
  • stroke-linejoin:用于设置两条线之间的连接方式,value有miter(尖角连接)、round(圆弧连接)、bevel(切断连接) 3个设置值;
  • stroke-opacity:用于设置描边的不透明度;
  • stroke-dasharray + stroke-dashoffset:stroke-dasharray用于使用虚线呈现SVG形状的描边,需要提供一个数值数组来描述,定义破折号和空格的长度;stroke-dashoffset用于设置虚线模式中的开始点;

填充 fill

fill用来描述SVG对象内部的颜色,除此还有如下两个属性:

  • fill-opacity:用于设置填充颜色的不透明度;
  • fill-rule:用于设置填充的方式,value有nonzero、evenodd 两个值
    • nonzero:从一个点往任何方向上绘制一条射线,形状中的路径每次穿过此射线时,如果路径从左到右穿过射线,则计数器加1,如果路径从右到左穿过射线,则计数器减1。计数器总数为0时候,则该点被认为在路径外。如果计数器非0,则该点被认为在路径内。
    • evenodd:从一个点往任何方向上绘制一条射线。每次路径穿过射线,计数器加1。如果总数是偶数,则点在外部。如果总计数为奇数,点在形状内。

变换 transform

此属性和css3中的transform相类似,有translate、rotate、scale、skew(skewX和skew函数使x轴和y轴倾斜)、matrix(矩阵变换,请联想大学线性代数 ???)这些变换,同时可以将它们组合进行变换。

此外还有渐变、遮罩、裁剪等属性,详细请参考:linearGradientmaskclipPath

在SVG中动画元素主要分成如下4类,同时也可以自由组合。

  • <set>:用于设置延迟,譬如设置5s后元素位置颜色变化,但是此元素没有动画效果;
  • <animate>:基础动画属性,用于实现单属性的动画过度效果;
  • <animateTransform>:实现transform变换动画效果,可以类比CSS3中的transform;
  • <animateMotion>:实现路径动画效果,让元素沿着对于path运动;

有了元素以后还需要有对应的属性用来表示动画的特征,譬如:要动画的元素属性名称、起始值、结束值、变化值、开始时间、结束时间、重复次数、动画速度曲线函数等等。

动画有很多地方都很新鲜,大家可以多多尝试,可以进入新建的SVG animationcodepen进行随意折腾,可以看到如下的效果。

六、使用方式

我们可以使用如下4种常用的方式来加载我们的SVG,此处可以将svg转换成base64的方式。

通过Img标签

<img src="tw93.svg" alt="Hello SVG" height="65" width="68">

通过CSS background:

.logo {
  background: url("data:image/svg+xml;base64,[data]");
}

通过object:

<object type="image/svg+xml" data="data:image/svg+xml;base64,[data]">
  fallback
</object>

直接内置到Html中

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65">
  <path fill="#1A374D" d="M42 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v21l12 15-7 15.7c14.5 13.9 35 2.8 35-13.7 0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/>
  <path d="M14 27v-20c0-3.7-3.3-7-7-7s-7 3.3-7 7v41c0 8.2 9.2 17 20 17s20-9.2 20-20c0-13.3-13.4-21.8-26-18zm6 25c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/>
</svg>

前三种方式常用于SVG图片已经定型,并且改动很少的情况,通过独立的SVG文件更好进行管理,同时可以减少HTML元素;内置的方式常用于SVG需要常修改或者还没有确定的情况,更加变化修改和维护。

七、优化和工具

svgo

SVG Optimizer is a Nodejs-based tool for optimizing SVG vector graphics files.

svgo一个比较厉害的压缩优化SVG的工具,可以将我们编写的SVG中的无用信息,同时对代码进行压缩,项目地址:https://github.com/svg/svgo

SVGOMG

SVGOMG是svgo的可视化界面工具,操作起来很方便,同时还提供了一些其他有用的功能,展示地址:SVGOMG - SVGO's Missing GUI

Snap.svg

The JavaScript SVG library for the modern web.

Snap.svg 是一个可以使你操纵 SVG 资源和 jQuery 操作 DOM 一样简单的类库,可以写出更加复杂的SVG效果,同时文档超级齐全,推荐给想深入了解的同学,项目地址:Snap.svg - Home,下图就是使用snapsvg来实现的。

Convert image to the SVG format

我们可以通过这个转换平台,将普通图片转成SVG的格式,但是此处转换可能结果不是我们想要的,但是可以将其当做初成品,在此基础上在进行调整优化,最终实现SVG的转换。平台地址:http://image.online-convert.com/convert-to-svg

以上,欢迎大家指教和讨论。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK