为啥要学SVG,背景图不香吗?
SVG
高深莫测,Canvas
讳莫如深,只有background-image
才是永远滴神。相信大多数刚从事前端行业的同学,在遇到CSS+DIV
搞不定的展示效果时,都会选择直接使用切图来直接作为元素背景使用,对于SVG
摸不着头脑的命令和Canvas
晦涩难懂的语法都会选择视而不见。
无疑,切图当做背景是开发效率最高的方案,但是相信我,当你掌握了SVG
和Canvas
的要领之后,在面对一些异型图案和复杂动画场景时,你会更从容再也不会体验到黔驴技穷时的窘迫。毕竟,某些场景下,SVG
和Canvas
就是所有选择中的最优解。
Canvas
暂且不表,今天我们就来扒一扒SVG
看似生人勿进的高冷外衣。
SVG到底是个啥?
关于这个问题,让我们先来看看MDN上的定义:
可缩放矢量图形(
Scalable Vector Graphics,SVG
),是一种用于描述二维的矢量图形,基于 XML 的标记语言。作为一个基于文本的开放网络标准,SVG
能够优雅而简洁地渲染不同大小的图形,并和CSS
,DOM
,JavaScript
和SMIL
等其他网络标准无缝衔接。本质上,SVG
相对于图像,就好比HTML
相对于文本。 和传统的点阵图像模式,像JPEG
和PNG
不同,SVG
格式提供的是矢量图,这意味着它的图像能够被无限放大而不失真或降低质量,并且可以方便地修改内容。
不知道冗长的定义是否把大家绕晕了,简单总结一下就是:
SVG
是可以让图片无限放大都不会失真的一种基于XML的标记语言。
其实,SVG
作为和CSS
同时期的产物,如今并不如CSS
的人尽皆知也是有历史原因的。
在早期的前端领域,CSS+DIV
属于一家独大的统治地位,这主要源于早期的Web
主要以图文展示为主,而更擅长图形展示的SVG
只能偃旗息鼓无人问津。
不过,随着网络的发展、带宽的增加、flash的消亡、屏幕的丰富、审美的提高等等原因,有着正牌血统和标准化规范的SVG
也就顺势崛起,与此同时也顺道开启了丰富多彩百家争鸣的视觉效果大内卷时代。
SVG能做什么?
现在我们知道了SVG
是什么,那么它又能做什么呢?
这是个大问题,要真想讲明白可能真能说上好多,不过,我倒是真的想说上一说,在回答问题之前,不妨让我们把问题适度拆解一下:
带着这个问题的疑问,让我们一点点的走进SVG的世界。
SVG的基础用法
相信我,学习枯燥的语法知识最快的途径就现学现用,今天我们只把SVG
常用标签做为一个图鉴来速览一遍,先建立宏观的知识图谱再回头深究用法和原理,不需要死记硬背多看多体会,如果你能看到这个系列的最后,说不定还能无师自通呢。
矩形 <rect>
<svg width="200" height="100" viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg">
<-- 直角矩形 -->
<rect x="10" y="25" width="100" height="50"/>
<-- 圆角矩形 -->
<rect x="120" y="25" width="100" height="50" rx="15" ry="15"/>
</svg>
圆形 <circle>
<svg width="100" height="100" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<circle cx="60" cy="60" r="50"/>
</svg>
椭圆 <ellipse>
<svg width="200" height="100" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<ellipse cx="60" cy="60" rx="100" ry="50" />
</svg>
多边形 <polygon>
<svg width="200" height="100" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<polygon points="50,10 150,10 190,90 10,90" fill="none" stroke="black"/>
</svg>
多线段 <polyline>
<svg width="200" height="100" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<polyline points="50,10 150,10 190,90 10,90" fill="none" stroke="black"/>
</svg>
注意:与十分相似,只不过形成的是闭合形状,形成的是开放形状.
线段 <line>
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<line x1="0" y1="0" x2="100" y2="100" stroke="black" />
</svg>
路径 <path>
<svg width="100" height="100"viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<path d="M 10,30
A 20,20 0,0,1 50,30
A 20,20 0,0,1 90,30
Q 90,60 50,90
Q 10,60 10,30 z"/>
</svg>
path
这里必须要重点说说,path
可以被称之为SVG
中的最强元素,几乎所有的二维形状(包括上述所有元素形状)都可以通过path
来创建,而且path
中的命令也是所有SVG
元素中最多的。
文字 <text>
<svg width="200" height="100" viewBox="0 0 150 100" xmlns="http://www.w3.org/2000/svg">
<style>
.small { font: italic 13px sans-serif; }
.heavy { font: bold 30px sans-serif; }
.Rrrrr { font: italic 40px serif; fill: red; }
</style>
<text x="20" y="50" class="small">Test</text>
<text x="40" y="50" class="heavy">SVG</text>
<text x="55" y="75" class="small">Text</text>
<text x="65" y="75" class="Rrrrr">Tag</text>
</svg>
裁剪 <clip-path>
<svg width="100" height="100" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<defs>
<clippath id="clipCircle">
<circle cx="50" cy="60" r="50" />
</clippath>
</defs>
<circle cx="75" cy="60" r="50" clip-path="url(#clipCircle)"/>
</svg>
蒙版 <mask>
<svg width="100" height="100" viewBox="-10 -10 120 120">
<mask id="myMask">
<rect x="0" y="0" width="100" height="100" fill="white" />
<path d="M10,35 A20,20,0,0,1,50,35
A20,20,0,0,1,90,35 Q90,65,50,95
Q10,65,10,35 Z" fill="black" />
</mask>
<circle cx="50" cy="50" r="50" mask="url(#myMask)" />
</svg>
注:这里的蒙版与
PS
中的蒙版极其相似,总结一个要领就是白透黑不透,不懂也没关系我们继续。
渐变 <linearGradient> / <radialGradient>
<svg width="200" height="100" viewBox="0 0 200 100">
<defs>
<!-- 线性渐变 -->
<linearGradient id="myLinearGradient">
<stop offset="0%" stop-color="gold" />
<stop offset="100%" stop-color="red" />
</linearGradient>
<!-- 径向渐变 -->
<radialGradient id="myRadialGradient">
<stop offset="0%" stop-color="gold" />
<stop offset="100%" stop-color="red" />
</radialGradient>
</defs>
<circle cx="50" cy="50" r="45" fill="url(#myLinearGradient)" />
<circle cx="150" cy="50" r="45" fill="url(#myRadialGradient)" />
</svg>
滤镜 <filter>
<svg width="200" height="100" viewBox="0 0 200 100">
<filter id="blurMe">
<feGaussianBlur stdDeviation="5"/>
</filter>
<circle cx="50" cy="50" r="45" />
<circle cx="150" cy="50" r="45" filter="url(#blurMe)" />
</svg>
动画 <animate>
<svg width="200" height="200" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="100" height="100">
<animate attributeName="rx" values="0;50;0" dur="10s"
repeatCount="indefinite" />
</rect>
</svg>
纹理 <pattern>
<svg width="200" height="100" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="star" viewBox="0,0,10,10" width="10%" height="10%">
<polygon points="0,0 2,5 0,10 5,8 10,10 8,5 10,0 5,2"/>
</pattern>
</defs>
<circle cx="50" cy="50" r="45" fill="url(#star)"/>
<circle cx="150" cy="50" r="35" fill="none" stroke-width="20" stroke="url(#star)"/>
</svg>
复用 <use>
<svg width="200" height="100" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<circle id="myCircle" cx="30" cy="50" r="29" stroke="inherit" fill="inherit" />
<use href="#myCircle" x="70" fill="black" stroke="red" />
<use href="#myCircle" x="140" fill="transparent" stroke="black"/>
</svg>
好了,至此SVG
中常用的标签已经看了个七七八八了,当然还有很多标签没有涉猎,不过,以上这些标签足以应付大部分需要SVG
出马的场景了,至于剩下的那些只要现学现用就好。
接下来,请容许我隆重介绍一款SVG
开发利器。
你是否经常想不起SVG
的语法而去翻找曾经写过的代码?
你是否经常忘记SVG
的渐变有哪些属性?
你是否经常分不清楚<path>
中A
、C
、S
、Q
、T
这些命令到底有啥区别?
上面讲的常用标签记不住?没关系!
刚才提到的语法命令不会用?没关系!
俗话说脑力不够,插件来凑,笨人有笨人的办法,于是乎,我为自己开发了一个小插件,功能很简单,只是进行一些代码补全,大佬肯定瞧不上眼的,自用是够了,容我演示一下它的功能。
它可以补全SVG
中的常用标签:
还可以补全常用的<defs>
标签:
还有<path>
中的命令语法提示:
当然,也有其他非SVG
的语法补全,例如vue2.0
和vue3.0
的模板,常用CSS(如缩略、渐变】、动画等)
、也有JS中字符串和数组的常用方法
,这些就不一一演示了,感兴趣的小伙伴可以去vscode商店搜索propeller,有插件文档,欢迎下载试用。
如果它真的能让你的开发效率提升那么一丢丢,我会特别特别开心,好了,下一篇,我们来讲讲 SVG擅长些啥?