-
是什么?
SVG(Scalable Vector Graphics)是可缩放矢量图形的缩写,基于可扩展标记语言XML来描述二维矢量图形的一种图形格式,由W3C制定,是一个开放标准。 -
特点
和Canvas相比,Canvas基于像素,提供2D绘制函数,是一种HTML元素类型,依赖于HTML,只能通过脚本来绘制图形,Canvas提供的功能比较原始,适合像素处理,动态渲染和大数据量绘制的应用场景;
SVG为矢量,提供一系列图形元素(Rect, Path, Circle, Line …),还有完整的动画,事件机制,本身可以独立使用,也可以嵌入到HTML中,SVG很早就成为了国际标准,功能更完善,适合静态图片展示,高保真文档查看和打印的应用场景本质上是文本文件,体积较小,且不管放大多少倍都不会失真
-
坐标定位
以页面的左上角为(0,0)坐标点,坐标以像素为单位,x轴正方向是向右,y轴正方向是向下
-
基本形状
<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>
-
样式
-
轮廓stroke
用于设置绘制对象线条的颜色,同时stroke有如下属性:- stroke-width:设置轮廓的宽度
- stroke-linecap:设置轮廓结尾处的渲染方式,value有butt(直接一刀切断)、square(保留一点切断)、round(圆弧切断) 3个设置值
- stroke-linejoin:设置两条线之间的连接方式,value有miter(尖角连接)、round(圆弧连接)、bevel(切断连接) 3个设置值
- stroke-opacity:设置描边的不透明度
- stroke-dasharray:使用虚线呈现SVG形状的描边,需要提供一个数值数组来描述,定义破折号和空格的长度
- stroke-dashoffset:设置虚线模式中的开始点
-
填充fill
用来描述SVG对象内部的颜色,除此还有如下两个属性:
-
fill-opacity:用于设置填充颜色的不透明度;
-
fill-rule:用于设置填充的方式,value有nonzero、evenodd 两个值
-
nonzero:从一个点往任何方向上绘制一条射线,形状中的路径每次穿过此射线时,如果路径从左到右穿过射线,则计数器加1,如果路径从右到左穿过射线,则计数器减1。计数器总数为0时候,则该点被认为在路径外。如果计数器非0,则该点被认为在路径内。
-
evenodd:从一个点往任何方向上绘制一条射线。每次路径穿过射线,计数器加1。如果总数是偶数,则点在外部。如果总计数为奇数,点在形状内。
-
-
变换transform
此属性和css3中的transform相类似,有translate、rotate、scale、skew -
还有其他的渐变linearGradient、遮罩mask、裁剪clipPath等属性
-
-
动画
-
使用方式
-
通过img标签
新建svg文件,写入内容:<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"/> </svg> //在html中引入 <img src="./1.svg" style="width: 120px;height: 120px;">
-
内置在HTML中
<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="#909090" fill="transparent" stroke-width="10"/> </svg>
-
通过css background(svg转为base64)
.logo { background: url("data:image/svg+xml;base64,[data]"); }
-
通过object(svg转为base64)
<object type="image/svg+xml" data="data:image/svg+xml;base64,[data]"> fallback </object>
-
c,d中的data来自:encodeURIComponent('<svg version="1.1" ...')
-
-
应用
-
iconfont
//HTML <p>1.iconfont</p> <div> <img src="./add-iconfont.svg" alt=""> <img src="./radio.svg" style="width: 120px;height: 120px;"/> </div> //add-iconfont.svg <svg width="120" height="120" version="1.1" xmlns="http://www.w3.org/2000/svg"> <!-- 横线 --> <line x1="20" x2="90" y1="55" y2="55" stroke="#ccc" fill="#ccc" stroke-width="5" /> <!-- 竖线 --> <line x1="55" x2="55" y1="20" y2="90" stroke="#ccc" fill="#ccc" stroke-width="5" /> <circle cx="54" cy="54" r="50" stroke="#ccc" fill-opacity="0" stroke-width="5" /> </svg> //radio.svg 使用adobe lllustrator(AI)工具生成的svg文件 <?xml version="1.0" encoding="utf-8"?><!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --><svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve"><style type="text/css"> .st0{fill:#CCCCCC;} .st1{fill:none;stroke:#CCCCCC;stroke-width:5;stroke-miterlimit:10;}</style><g> <path class="st0" d="M60,15c24.81,0,45,20.19,45,45s-20.19,45-45,45S15,84.81,15,60S35.19,15,60,15 M60,10c-27.61,0-50,22.39-50,50 s22.39,50,50,50s50-22.39,50-50S87.61,10,60,10L60,10z"/></g><line class="st1" x1="47" y1="84" x2="47" y2="34"/><line class="st1" x1="87" y1="60" x2="47" y2="82"/><line class="st1" x1="48.5" y1="36" x2="88.5" y2="61"/></svg>
-
loading动画
//HTML <p>2.loading动画</p> <div> <svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg"> <g> <circle cx="50" cy="60" r="40" stroke="#ccc" stroke-width="10" /> <circle id="circle" cx="50" cy="60" r="40" stroke="orange" stroke-width="10" /> </g> </svg> </div> //css circle { fill: transparent; } #circle { stroke-dasharray: 250; stroke-dashoffset: 250; /* pi*r*2 大约是250 */ animation: round 3s linear infinite; } /* stroke-dasharray为一个参数时: 其实是表示虚线长度和每段虚线之间的间距 如:stroke-dasharray = '10' 表示:虚线长10,间距10,然后重复 虚线长10,间距10 stroke-dashoffset: offset:偏移的意思 这个属性是相对于起始点的偏移,正数偏移x值的时候,相当于往左移动了x个长度单位,负数偏移x的时候,相当于往右移动了x个长度单位。 需要注意的是,不管偏移的方向是哪边,dasharray 是循环的,也就是 虚线-间隔-虚线-间隔。 */ @keyframes round { to { stroke-dashoffset: 0; } }
-
HUOLALA线条动画
//HTML <p>3.线性动画</p> <!-- 设置了不同的stroke-dasharray和stroke-dashoffset动画参数,从而实现了这种效果 --> <div> <svg width="500" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg"> <symbol id="text"> <text x="10" y="130" class="text" font-size="90">HUOLALA</text> </symbol> <g> <!-- SVG <use>元素可以重用SVG文档中其他位置(包括 <g>元素和 <symbol>元素)的SVG形状 --> <use xlink:href="#text" id="text1" class="text"></use> </g> </svg> </div> //css #text1{ stroke: red; fill:#fff; stroke-dashoffset: 4; stroke-dasharray: 0 35%; font-size: 20px; animation: animationText 5s linear infinite forwards; } @keyframes animationText { 0% { stroke-dasharray: 0, 378; } 40% { stroke-dasharray: 378, 378; fill: rgba(0, 0, 0, 0); opacity: 1; } 100% { stroke-dasharray: 378, 378; fill: red; opacity: 0; } }
-
页面水印
涉及MutationObserver API,可以查看另一篇观察元素博文
juejin.cn/post/685512…(function () { // svg 实现 watermark function __svgWM({ container = document.body, content = 'Rachel.yu', width = '120px', height = '120px', opacity = '0.1', fontSize = '15px', zIndex = 1, } = {}) { const args = arguments[0] const svgStr = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"> <text x="30" y="30" dy="12px" text-anchor="middle" stroke="orange" stroke-width="1" stroke-opacity="${opacity}" fill="#f4f5f7" transform="rotate(-45, 20 20)" style="font-size: ${fontSize};"> ${content} </text> </svg>` const base64Url = `data:image/svg+xml;base64,${window.btoa( unescape(encodeURIComponent(svgStr)) )}` const __wm = document.querySelector('.__wm') const watermarkDiv = __wm || document.createElement('div') const styleStr = ` position:absolute; top:0; left:0; width:100%; height:100%; z-index:${zIndex}; pointer-events:none; background-repeat:repeat; background-image:url('${base64Url}')` watermarkDiv.setAttribute('style', styleStr) watermarkDiv.classList.add('__wm') if (!__wm) { container.style.position = 'relative' container.insertBefore(watermarkDiv, container.firstChild) } const MutationObserver = window.MutationObserver || window.WebKitMutationObserver if (MutationObserver) { let mo = new MutationObserver(function () { const __wm = document.querySelector('.__wm') // 只在__wm元素变动才重新调用 __svgWM if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm) { // 避免一直触发 mo.disconnect() mo = null __svgWM(JSON.parse(JSON.stringify(args))) } }) mo.observe(container, { attributes: true, subtree: true, childList: true, }) } } if (typeof module != 'undefined' && module.exports) { //CMD module.exports = __svgWM } else if (typeof define == 'function' && define.amd) { // AMD define(function () { return __svgWM }) } else { window.__svgWM = __svgWM } })(); __svgWM()
-
关于工具AI(adobe lllustrator)应用于出版、多媒体和在线图像的工业标准矢量插画的软件
可以结合使用AI生成复杂矢量图,导出后使用
示例代码地址:gitee.com/wisdom_QQ/l…
-