¿Cómo dibujar un solo perro en SVG? Ven a este artículo para contarte

prefacio

Este artículo documenta el aprendizaje sobre los conceptos básicos de SVG. Sobre el papel, es superficial, y si quieres saber esto, tienes que hacerlo. Ven, vela conmigo (§ •_•) §.

¿Qué es SVG?

svg es la abreviatura de Scalable Vector Graphics. El nombre completo es Scalable Vector Graphics. Es un formato gráfico en el que las formas se especifican en XML. Luego, el visor SVG procesa el XML.

Clasificación de gráficos en computadoras

Generalmente se puede dividir en dos categorías: mapas de bits, gráficos vectoriales. El mapa de bits (bitmap), también conocido como imagen de mapa de bits o imagen de trama, se compone de un solo punto llamado píxel (elemento de imagen). Por lo general, una foto es un mapa de bits. Se compone de puntos de píxeles. El diagrama vectorial es más como el relleno de posición de punto a punto, no hay concepto de resolución y la imagen se puede ampliar o reducir a voluntad sin distorsión.

ventajas de svg

[1] Se puede estirar infinitamente y la pantalla de impresión no se distorsiona

[2] Puede controlar svg como escribir código todos los días, casi sin costo de uso

[3] La huella es extremadamente pequeña (en relación con los mapas de bits) y se puede comprimir con gzip para comprimir aún más su tamaño

[4] SVG se representa mediante xml, y la esencia es dom

compatibilidad con svg

1.png

dibujo

[1] Método de referencia básico SVG

La visualización de SVG en navegadores web (como Chrome, Firefox e Internet Explorer) se puede realizar dirigiendo el navegador a la URL del archivo SVG, incrustando el SVG en una página HTML, usando elementos iframe, usando elementos img, etc. , hay cuatro formas de lograr la referencia 1: Usar el elemento iframe

<iframe :src="require('@/assets/data-show/banner/bt-image-09.png')" >
复制代码

2: Usar elemento img

<img class="s-left" :src="require('@/assets/data-show/banner/bt-image-09.png')" />
复制代码

3: Usar incrustar

<embed :src="require('@/assets/data-show/banner/bt-image-09.png')" pluginspage="http://www.adobe.com/svg/viewer/install/" />
复制代码

4: incrustar html directamente

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
</body>
</html>
复制代码

Cuál de los diversos métodos de cita elegir depende completamente de sus propias necesidades, y cada uno tiene sus propios méritos.

característica SVG en línea objeto/incrustar/iframe imagen
Puede interactuar con los usuarios.
Animación de soporte
Puede ejecutar scripts js
Se puede programar externamente

[2] Atributos de línea SVG

Atributos describir
llenar Establecer el color de relleno de la forma
opacidad de relleno Establecer la opacidad de relleno de la forma
carrera Establece el color del trazo (línea) utilizado para dibujar el contorno de esta forma
anchura del trazo Establece el ancho del trazo (línea) utilizado para dibujar el contorno de esta forma
trazo-dasharray Establece el trazo (discontinuo) utilizado para delinear esta forma
trazo-opacidad 设置用于绘制此形状轮廓的笔触(直线)不透明度

【3】svg基本图形元素介绍

矩形:SVG <rect>

<rect x="10" y="10" height="100" width="100" style="stroke:#006600; fill: #00cc00"/>
复制代码

圆形:SVG <circle>

<circle cx="40" cy="40" r="24" style="stroke:#006600; fill:#00cc00"/>
复制代码

椭圆形:SVG <ellipse>

<ellipse cx="40" cy="40" rx="30" ry="15" style="stroke:#006600; fill:#00cc00"/>
复制代码

线段:SVG <line>

<line x1="0" y1="10" x2="0" y2="100" style="stroke:#006600;"></line>
复制代码

折线:SVG <polyline>

<polyline fill="none" stroke="black"  points="20,100 40,60 70,80 100,20"/>
复制代码

多边形:SVG <polygon>

<polygon points="10,0  60,0  35,50" style="stroke:#660000; fill:#cc3333;"/>
复制代码

【4】创建svg坐标系统并构建完整图案

我们创建一个一个二维的坐标系统用 x 代表横轴,y 代表纵轴,单位默认像素(px)。x增加位置右移,y增加位置下移。这和我们认知的笛卡尔坐标系相反。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>SVG</title>
    <style type="text/css">
        html, body {
            height: 100%;
            width: 100%;
            background: #e9e9e9;
        }
        body {
            margin: 0;
            text-align: center;
        }
        .grid {
            width: 500px;
            height: 500px;
            margin: 0 auto;
            padding-top: 100px;
            padding-left: 100px;
            background-image: url('grid.png');
            position: relative;
        }
        .grid::before {
            content: "";
            border-left: 1px solid #7c7cea;
            position: absolute;
            top: 0;
            left: 100px;
            width: 50px;
            height: 600px;
        }
        .grid::after {
            content: "";
            border-top: 1px solid #7c7cea;
            position: absolute;
            top: 100px;
            left: 0;
            width: 600px;
            height: 500px;
        }
        .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
    </style>
</head>
<body>
<div class="grid">
    <svg version="1.1"
         width="500" height="500"
         xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink">
        <polyline class="right-ear" style="stroke:#583504; stroke-width: 3; fill:#fddb55" points="120,80 250,180 120,180 120,80"/>
        <polyline class="left-ear" style="stroke:#583504; stroke-width: 3; fill:#fddb55" points="370,80 250,180 370,180 370,80"/>
        <circle cx="250" cy="250" r="150" style="stroke:#583504; stroke-width: 3; fill:#fddb55"/>
        <circle cx="183" cy="178" r="16" style="fill:#FFFFFF"/>
        <circle cx="273" cy="180" r="18" style="fill:#FFFFFF"/>
        <g class="right-eye">
            <ellipse cx="170" cy="215" rx="45" ry="20" style="stroke:#583504; stroke-width: 3; fill:#FFFFFF"/>
            <circle cx="185" cy="215" r="18" style="stroke:#583504; stroke-width: 1; fill:#583504"/>
        </g>
        <g class="left-eye">
            <ellipse cx="300" cy="215" rx="45" ry="20" style="stroke:#583504; stroke-width: 3; fill:#FFFFFF"/>
            <circle cx="315" cy="215" r="18" style="stroke:#583504; stroke-width: 1; fill:#583504"/>
        </g>
        <g class="nose">
            <path id="路径" transform='translate(117 235) scale(1.6)' class="st0" d="M39.9,12.9c2.5-7.5,9.3-11.6,20.4-12.3S80.1,3,86.4,10c6.7-5.6,15.7-8.7,26.9-9.4s20.5,2.5,28,9.4
		c13.3,14.8,13.3,32.5,0,53.1c-16.7,22.1-38.5,33.1-65.3,33c-15.7-0.4-31.9-6.7-48.6-19.1C9.4,63.9,0.3,49.6,0.2,34.4
		c0.3-9.8,4.6-17,13-21.5S30.5,8.3,39.9,12.9z"/>
            <ellipse cx="225" cy="285" rx="30" ry="18" style="stroke:#583504; stroke-width: 3; fill:#583504"/>
            <line x1="225"  y1="295" x2="225"   y2="325" style="stroke:#583504; stroke-width: 5;"></line>
            <line x1="190"  y1="325" x2="275"   y2="325" style="stroke:#583504; stroke-width: 5;"></line>
        </g>

    </svg>
</div>
</body>
</html>
复制代码

以上代码运行结果

4.png

svg代码复用问题

我们所知道的是svg的代码块都是极其庞大且复杂的,但是为了尽量的节约代码,svg也出现了代码复用的解决方案(即类似组件化的思路来复用基础组件来组合复杂图案)。

【1】<g>元素

<g>元素会将所有子元素作为一个组合。通常组合还会有一个唯一的id作为名称。同时元素所指定的样式还将应用于所有子元素,除非其单独设置。

 <svg version="1.1"
         width="500" height="500"
         xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink">
        <!-- g#house嵌套了g#man和g#woman -->
        <g id="house" style="fill:none;stroke:black;" width="240px" height="240px">
            <title>house</title>
            <desc>House width door</desc>
            <rect x="6" y="50" width="60" height="60"></rect>
            <polyline points="6 50,36 9,66 50"></polyline>
            <polyline points="35 110,36 80,50 80,50 110" />
        </g>
        <g id="man" style="fill:none;stroke:black;">
            <title>man</title>
            <desc>Male human</desc>
            <circle cx="85" cy="56" r="10" />
            <line x1="85" y1="66" x2="85" y2="80" />
            <polyline points="76 104,85 80,94 104" />
            <polyline points="76 70,85 76,94 70" />
        </g>
        <g id="woman" style="fill:none;stroke:black;">
            <title>woman</title>
            <desc>Female human</desc>
            <circle cx="110" cy="56" r="10" />
            <polyline points="110 66,110 80,100 90,120 90,110 80" />
            <line x1="104" y1="104" x2="108" y2="90" />
            <line x1="112" y1="90" x2="116" y2="104" />
            <polyline points="101 70,110 76,119 80" />
        </g>
    </svg>
复制代码

【2】<use>元素

复杂的图形中经常会出现重复元素,svg使用<use>元素为定义在<g>元素内的组合或者任意独立图形元素提供了类似复杂黏贴的能力; 定义了一组<g>图形对象后,使用<use>标签再次显示它们。要指定想要的重用的组合就给xlink:href属性指定URI即可,同时还要指定xy的位置以表示组合应该移动到的位置。

<use xlink:href="#house" x="70" y="100"></use> // house模块
<use xlink:href="#man" x="-55" y="100"></use> // man模块
<use xlink:href="#woman" x="-50" y="100"></use> // woman模块
复制代码

【3】<defs>元素

<defs>元素可以做为容器来容纳所有可复用的元素,并且不显示它们,只把她们做为模版来使用

<svg version="1.1"
         width="500" height="500"
         xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink">
        <defs>
	        <g id="house" style="fill:none;stroke:red;" width="240px" height="240px">
	            <title>house</title>
	            <desc>House width door</desc>
	            <rect x="6" y="50" width="60" height="60"></rect>
	            <polyline points="6 50,36 9,66 50"></polyline>
	            <polyline points="35 110,36 80,50 80,50 110" />
	        </g>
	        <g id="man" style="fill:none;stroke:black;">
	            <title>man</title>
	            <desc>Male human</desc>
	            <circle cx="85" cy="56" r="10" />
	            <line x1="85" y1="66" x2="85" y2="80" />
	            <polyline points="76 104,85 80,94 104" />
	            <polyline points="76 70,85 76,94 70" />
	        </g>
	        <g id="woman" style="fill:none;stroke:black;">
	            <title>woman</title>
	            <desc>Female human</desc>
	            <circle cx="110" cy="56" r="10" />
	            <polyline points="110 66,110 80,100 90,120 90,110 80" />
	            <line x1="104" y1="104" x2="108" y2="90" />
	            <line x1="112" y1="90" x2="116" y2="104" />
	            <polyline points="101 70,110 76,119 80" />
	        </g>
        </defs>
        <use xlink:href="#house" x="70" y="100"></use>
        <use xlink:href="#man" x="-55" y="100"></use>
        <use xlink:href="#woman" x="-50" y="100"></use>
    </svg>
复制代码

【4】<symbol>元素

<symbol>元素本质也是容器,可以放置组合构建复杂图案。此外<symbol>元素与<g>元素不同的是可以指定viewBoxpreserveAspectRatio属性,通过给<use>元素添加width和height属性就可以让symbol适配视口大小。这边就简单的介绍一下viewPortviewBoxpreserveAspectRatio

viewPort:简单而言就是所要显示的区域的大小即屏幕大小。如果有设置具体大小则以设置的为准(支持单位混合但不推荐) 3.png

viewBox:viewBox拥有四个参数( min-x, min-y, width, height )。 其中 min-x:左上角横坐标,min-y:左上角纵坐标,width:宽度,height:高度。 原点默认位于左上角,x 轴水平向右,y 轴垂直向下

2.jpg

本质上viewBox是改变了坐标系与单位,将区域图像变成用户坐标和用户单位 那么这些事如何得到的?下面是一个例子

<svg width="500" height="200" viewBox="0 0 50 20" >
    <rect x="20" y="10" width="10" height="5"
          style="stroke: #000000; fill:none;"/>
</svg>
复制代码

本示例创建<svg>一个宽度为500像素,高度为200 的元素。的viewBox属性<svg>包含四个坐标。这些坐标定义了<svg>元素的视图框(ViewBox)。坐标是x y width height视图框(ViewBox)的坐标。在这种情况下,视图框(ViewBox)从处开始0,0并且50宽而20高。也就是说,500 x 200像素<svg>元素在内部使用从0,0 到的坐标系50,20。换句话说,用于内部形状的坐标中的每1个单位<svg>对应于宽度500/50 = 10像素,高度对应200/20 = 10像素。这就是为什么x位置为20,y位置为10的矩形真正位于的原因200,100,并且其宽度(10)和高度(5)分别对应于100个像素和50个像素。

在这里插入图片描述

如果图像超出?

在这里插入图片描述

在前面的例子中我们的viewBox的宽高比是相同的(500/200 = 50/20)但是在实际应用中不一定比例一定相同,那么或造成三种结果 1: 按较小尺寸等比缩放图形,以完全填充 2: 按较大尺寸等比缩放图形,超出部分进行切割 3: 拉伸或者压缩图形以使其完全是配视口(意思就是完全不保留宽高比,适应视口为第一要务)

preserveAspectRatio:该属性允许我们指定被缩放的图像相对与视口的对齐方式,以及是希望它适配边缘还是要剪裁。 这一模型preserveAspectRatio= "( align [meet/Slice/none] )"

align值 描述
xMin 按视口的左侧边缘对齐
xMid 按视口的水平中心对齐
xMax 按视口的右侧边缘对齐
YMin 按视口的顶部边缘对齐
YMid 按视口的垂直中心对齐
YMax 按视口的底部边缘对齐
[meet/Slice/none]值 描述
meet 保留宽高比并缩放视图框(ViewBox)以适合视口(Viewport)。
slice 保留宽高比并切掉不适合视口(Viewport)内部的图像任何部分。
none 不保留宽高比。缩放图像以使视图框(ViewBox)完全适合视口(Viewport)。比例会失真。
使用:preserveAspectRatio="xMidYMid meet"/preserveAspectRatio="xMinYMin slice"

总结

svg给了我们绘图的新的想象空间。虽然有弊端,但是这并不足以否定其地位。何况svg技术已经是W3C所推荐的标准。其在地图、高精度图形、可移植图形,由数据驱动的响应式图形领域的广泛应用也触及我们普通人的日常生活。同时在印刷领域也可通过svg提供高质量的输出文件,在跨平台的一致性上也可以做到极佳控制。正是由于这诸多优点,svg的学习与使用都能产生更多价值,也许很多有趣的应用场景也等待我们去发现扩展。

推荐好文

参考

Supongo que te gusta

Origin juejin.im/post/7085980049039425543
Recomendado
Clasificación