SVG基础知识

SVG比较底层,只做了解

SVG
一.基础知识
1.概述
SVG 是基于XML语法的图像格式,意为可缩放矢量图(Scalable Vector Graphics)。
SVG 图像是基于像素处理的,放大或改变尺寸的情况下其图形质量不会有所损失。
SVG本质上是也给文件,体积较小
2.svg的优势
        与其他图像格式相比(比如JPEG 和 GIF),使用 SVG 的优势在于 :
SVG 图像可通过文本编辑器来创建和修改;
SVG 图像可被搜索、索引、脚本化或压缩;
       SVG 是可伸缩的;
       SVG  图像可在任何的分辨率下被高质量地打印;
       SVG 可在图像质量不下降地情况下被放大;
       SVG 图像中的文本时可选的,同时也是可搜索的(很适合制作地图)
       SVG 是可以与 Java 技术一起运行
       SVG 是开放的标准
SVG 文件时纯粹的 XML  
3.使用
(1)可以直接在HTML中嵌入SVG代码
<body>
    <svg  style="height: 300px; width: 500px">
        <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
    </svg>
</body>
xmlns是命名空间,不了解XML的可能不知道是什么意思,无所谓,这个参数是固定的
(2)单独建一个SVG文件,并在HTML中引入
建一个example1.svg文件,内容如下:
<svg  baseProfile="full"  width="300" height="200" >
      <rect width="100%" height="100%" stroke="black" stroke-width="4" fill="grey" />
      <text x="150" y="115" font-size="20" text-anchor="middle" fill="red">SVG NB</text>
</svg>
 然后在HTML通过标签引入:
<iframe src="example1.svg" style="width: 350px; height: 250px"></iframe>可以操作
<embed src="example2.svg" type="image/svg+xml" />可以操作
<object data="example3.svg" type="image/svg+xml"></object>可以操作
这些标签都适用于HTML5标准,并且目前大部分浏览器都是支持的。
(3)Css中可以使用SVG文件
.log{
background:url(icon.svg)
}
(4)SVG可以转为BASE64编码,然后作为DataURL写入网页
<img src='example3.svg'>
不可以对里面元素进行操作


二.标签的运用
0.SVG
<svg width='100' height='100' viewBox='50 50 50 50'>
width图片宽度,默认px
height图片高度,默认px
viewBox只展示图片的一部分,前两个参数代表窗口的位置,后两个代表宽高,由于视口必须适配所在的空间,所以相当于放大了图片
1.矩形 <rect>
<rect x='0' y='0' width="300" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)"/>
x,y 矩形左上角的X轴Y轴位置 值:数字
height 高 值:数字
        width 宽 值:数字
        fill 填充 值:颜色
        stroke 描边 值:颜色
        stroke-width 描边 宽度 值:颜色
stroke-opacity 透明度 值:数字0-1           
2.圆形 <circle>
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
       (cx, cy)圆心 , r 圆半径,省略 cx 和 cy,圆的中心会被设置为 (0, 0)
fill 填充 值:颜色
       stroke-width 描边宽度
       stroke 描边颜色
3.椭圆 <ellipse>
<ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow"/>
        (cx,cy)椭圆中心坐标 
        rx 横轴半径
        rx 纵轴半径
4.线 <line>
<line x1="0" y1="0" x2="200" y2="200"/>
两点确定一条直线,从(x1,y1)到(x2,y2)
fill 填充 值:颜色
stroke-width 描边宽度
stroke 描边颜色
5.折线 <polyline>
<polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160"/>
points点的集合,每组点之间用空格隔开而不是分号。
fill 填充 值:颜色
stroke-width 描边宽度
stroke 描边颜色
6.多边形 <polygon>
<polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;" />
多边形稍微复杂一点点,它跟折线很像,也是定义一些点,只不过最后一个点会和第一个点连起来,形成一个封闭图形。
        points 属性定义多边形每个角的 x 和 y 坐标
fill-rule属性,该属性用来如何判断画布上的某区域是否属于该图形“内部”(内部区域将被填充)
默认是nonzero,它的规则就是要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点情况。
另一个值是evenodd,也是做射线,但是做完之后数和图形路径的交点个数,奇数就认为是在内部,偶数就认为在外部
7.路径 <path>
<path d="M 0 350 q 150 -300 300 0" stroke="blue" stroke-width="5" fill="none" />
       参数如下:可以用小写字母,但是含义不一样,大写表示绝对绝对定位,而小写表示相对定位。
M = moveto 起始
L = lineto 连线
H = horizontal lineto 水平线
V = vertical lineto 垂直线
C = curveto 曲线,三次贝塞尔曲线
S = smooth curveto 也是曲线,三次贝塞尔曲线
Q = quadratic Bézier curve 二次贝塞尔曲线
T = smooth quadratic Bézier curveto 二次贝塞尔曲线
A = elliptical Arc 椭圆弧
Z = closepath 闭合(从最后一个点连直线到起始点)
8.文本标签 <text>
(1)text 文本
<text x="10" y="20" font-size='38' text-anchor='middle' style="fill:rgb(0, 174, 255);">
</text>
        font-size 文本大小 值:数字 单位:rem,em,px,默认px
        x,y 开始绘制文本的X轴与Y轴位置 具体由text-anchor属性决定。
        text-anchor 文本水平对齐方式 值:start 开始位置, middle 中心位置,end 末尾位置
text-shadow阴影
(2)子文本
每个<tspan>和和<text>一样,单独占一行,而且可以有自己的样式。但是必须包在<text>标签内,不能单独用。
<text x="10" y="20" style="fill:rgb(0, 174, 255);">峰兄兄:
    <tspan x="10" y="45">菜鸡程序员</tspan>
    <tspan x="10" y="70">正在努力中</tspan>
</text>​
(3)旋转文字
<text x="10" y="45" transform="rotate(90 20,40)">正在努力中</text>
rotate中的三个参数分别是顺时针旋转的度数、垂直、水平平移的距离(正值表示向上、向右)
(4)文字沿路径
定义一条路径,然后通过textPath标签进行设置即可
<defs>
    <path id="path1" d="M 0 100 q 100 80 200 0" stroke="blue" stroke-width="5" fill="none" />
</defs>
<text x="10" y="100" style="fill:red;">
    <textPath xlink:href="#path1">祝你天天开心,都有好心情</textPath>
</text>
        text 文本
        font-size 文本大小 值:数字 单位:rem,em,px,默认px
        x,y 开始绘制文本的X轴与Y轴位置 具体由text-anchor属性决定。
        text-anchor 文本水平对齐方式 值:start 开始位置, middle 中心位置,end 末尾位置
9.复制标签<use>
<use href='#mycicle' x='20' y='30' fill='white'>
href要复制的节点
10.组标签<g>
多个形状形成一个组,方便复用
<g id='dId'>
<cicle...>
<rect...>
</g>
11.自定义形状标签<defs>
内部的代码不会显示,仅供href引用
<defs>
<g id='dId'>
<cicle...>
<rect...>
</g>
</defs>
:hover无法操作
12.自定义形状标签<pattern>
可以被引用来平铺一个区域
<svg width="100%" height="800">
    <defs>
        <pattern id="myPattern" x="0" y="0" width="100" height="100" patternUnits="userSpaceOnUse">
            <circle cx="20" cy="20" r="10" />
        </pattern>
    </defs>
    <rect x="0" y="150" width="100%" height="100" fill="url(#myPattern)" />
</svg>
13.image标签
<image>标签用于插入图片文件。使用xlink:href 来引入图片
<svg width="100%" height="800">
            <image xlink:href="https://img.alicdn.com/imgextra/i1/1881744325/O1CN01iNKEij1hotb5Di09F_!!1881744325.png" />
</svg>
14.animate 标签
<svg width="100%" height="800">
    <rect x="0" y="0" width="100" height="100" fill="#feac5e">
        <animate attributeName="x" from="0" to="200" dur="2s" repeatCount="indefinite" />
        <animate attributeName="width" to="200" dur="2s" repeatCount="indefinite" />
        <animate attributeName="y" to="200" dur="2s" repeatCount="indefinite" />
        <animate attributeName="height" to="200" dur="2s" repeatCount="indefinite" />
    </rect>
</svg>
attributeName:发生动画效果的属性名。
from:单次动画的初始值。
to:单次动画的结束值。
dur:单次动画的持续时间。
repeatCount:动画的循环模式。
对 transform 不起作用
15.animateTransform标签
在使用 transform 属性的动画
<svg width="100%" height="800">
    <rect x="10" y="100" width="10" height="10" transform="translate(30,40)">
        <animateTransform attributeName="transform"
          attributeType="XML" type="rotate" from="0 60 70" to="360 60 70" dur="10s" repeatCount="indefinite"/>
    </rect>
</svg>
16.animateMotion标签
一个元素沿着运动路径进行移动。
<svg width="100%" height="800">
    <circle r="5" fill="red">
            <animateMotion dur="10s" repeatCount="indefinite" path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
    </circle>
</svg>
三.环形进度条
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>151.SVG 实现拟物态圆环进度条</title>
  </head>
  <link rel="stylesheet" href="../common.css" />
  <style>
    body {
      background: var(--back-bg);
    }
    :root {
      --bg: #edf1f5;
      --back-bg: #c5ccda;
      --back-shadow: #ffffff;
      --ring-color1: #c1dfc4;
      --ring-color2: #3cba92;
      --text-aolor: #497241;
      /* 父容器宽度 */
      --w: 200px;
      /* 父容器gap*/
      --gap: 30px;
      /* 第二层圆形宽度 */
      --inner: calc(var(--w) - var(--gap));
      /* 环形stroke宽度 */
      --stroke: 20px;
      /* svg环形宽度 */
      --circle: calc(var(--inner) - var(--stroke));
      /* 第三层圆形宽度 */
      --center: calc(var(--circle) - var(--stroke));
    }
    .container {
      padding: 30px;
      border-radius: 20px;
      background: var(--bg);
      box-shadow: 0px 20px 30px rgba(100, 131, 177, 0.2);
      border: 1px solid #fff;
    }
    .container-box {
      position: relative;
      width: var(--w);
      height: var(--w);
    }
    .circle-outer {
      position: relative;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      box-shadow: 6px 6px 8px var(--back-bg), -6px -6px 8px var(--back-shadow);
      background: var(--bg);
    }
    .circle-outer::before {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      background: var(--bg);
      width: var(--inner);
      height: var(--inner);
      box-shadow: inset 8px 8px 10px var(--back-bg),
        inset -4px -4px 8px var(--back-shadow);
    }
    .circle-outer::after {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      background: var(--bg);
      width: var(--center);
      height: var(--center);
      box-shadow: 6px 6px 8px var(--back-bg), -2px -2px 8px var(--back-shadow);
    }
    .container-box::after {
      content: attr(data-num);
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      color: var(--text-aolor);
      font-size: 30px;
    }
    svg {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
      transform: rotate(-90deg);
    }
    svg circle {
     position: absolute;
      --z: calc(var(--w) / 2);
      --c: calc(var(--circle) / 2);
      transform: translate(
        calc(var(--z) - var(--c)),
        calc(var(--z) - var(--c))
      );
      cy: calc(var(--circle) / 2);
      cx: calc(var(--circle) / 2);
      r: calc(var(--circle) / 2);
      fill: none;
      stroke-linecap: round;
      /* 设置圆的stroke-dasharray和stroke-dashoffset,为圆的周长 */
      stroke-dasharray: calc(3.14 * var(--circle));
      stroke-dashoffset:calc(3.14 * var(--circle));
      stroke-width: var(--stroke);
    }
  </style>
  <body>
    <div class="container">
      <div class="container-box" data-num="--" id="box">
        <div class="circle-outer"></div>
        <svg>
          <defs>
            <radialGradient
              id="gradient"
              cx="50%"
              cy="50%"
              r="60%"
              fx="50%"
              fy="50%"
            >
              <stop offset="30%" stop-color="var(--ring-color2)" />
              <stop offset="100%" stop-color="var(--ring-color1)" />
            </radialGradient>
          </defs>
          <circle stroke="url(#gradient)" id="circle"></circle>
        </svg>
      </div>
    </div>
  </body>
  <script>
    const getData = () => {
      const circle = document.getElementById("circle");
      const box = document.getElementById("box");
      let perimeter = 3.14 * 150; //这是stroke-dasharray的值
      let i = 0;
      let timer = null;
      const loading = () => {
        if (i < 100) {
          i++;
          box.dataset.num = i + "%";
          let per = perimeter - (perimeter * i) / 100;
          circle.style.strokeDashoffset = per;
        } else {
          clearInterval(timer);
        }
      };
      loading();
      timer = setInterval(loading, 100);
    };
    getData();
  </script>
</html>

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值