【CSS】SVG实战入门,svg画曲线,svg简单动画上手入门
创始人
2024-06-03 13:20:09
0

之前我写过一篇【canvas绘画折线段】,其实实际使用中,svg绘画简单的曲线是最方便的。
比如大屏中使用,或者其他小特效使用

点赞 + 关注 + 收藏 = 学会了

一、什么是svg?

在学习 SVG 之前,首先要了解 位图矢量图 的区别。
简单来说:

  • 位图:放大会失真图像边缘有锯齿;是由像素点组成;前端的 Canvas 就是位图效果,png、jpg等图片也是位图。
  • 矢量图:放大不会失真;使用 XML 描述图形。

svg

那么 SVG 是什么呢?SVG 意为可缩放矢量图形(Scalable Vector Graphics)。它是矢量图的其中一种格式。它是用 XML 来描述图形的。

对于初学 SVG 的前端来说,可以简单的理解为 “SVG 是一套新标签”。

所以可以使用 CSS 来设置样式,也可以使用 JSSVG 进行操作。

二、SVG标签基本结构

如下所示,是一个 SVG 文档结构:

测试这是一个描述svg测试文本

  • 根元素以像素为单位定义了整个图像的 width 和 height,还通过 xmlns 属性定义了 SVG 的命名空间,
  • version 属性可定义所使用的 SVG 版本,
  • </code> 元素的内容可以被阅读器显示在标题栏上或者是作为鼠标指针指向图像时的提示,</li><li><code><desc></code> 元素允许咱们为图像定义完整的描述信息,</li><li><code><rect></code>标签 用来创建一个矩形,通过 <code>fill</code> 属性 把背景颜色设为黄色。</li><li><code><circle></code>标签 用来创建一个圆。<code>cx</code> 和 <code>cy</code> 属性定义圆中心的 x 和 y 坐标。如果忽略这两个属性,那么圆点会被设置为 (0, 0),r 属性定义圆的半径。 一个半径 80px 的绿色圆圈 <code><circle></code> 绘制在红色矩形的正中央 (向右偏移 150px,向下偏移115px)。</li><li><code>stroke</code> 和 <code>stroke-width</code> 属性控制如何显示形状的轮廓。我们把圆的轮廓设置为 4px 宽,红色边框。</li><li><code>fill</code> 属性设置形状内的颜色。我们把填充颜色设置为红色。</li></ul> <p><strong>注意</strong>:所有的开启标签必须有关闭标签!</p> <p>运行效果:<br /> <img src="https://img.pic99.top/hhfamen/202406/1b10a48bac7ccb8.png" alt="在这里插入图片描述" /></p> <h1>三、svg坐标系</h1> <p>SVG 网格坐标系统的特点如下所示:</p> <ul><li>以左上角为坐标系的原点,即 (0,0)。</li><li>(向右)横向延伸为 X 轴正方向, x 坐标逐渐增大。</li><li>(向下)纵向为 Y 轴正方向,y 坐标逐渐增大。</li><li>坐标以像素 px 为单位。</li></ul> <p><img src="https://img.pic99.top/hhfamen/202406/82d59e95511eb68.png" alt="svg坐标系" /></p> <h1>四、常见标签使用</h1> <h2>1. 矩形 rect</h2> <p><code><rect></code>标签可用来创建矩形,以及矩形的变种:</p> <p><strong>矩形:</strong></p> <pre><code class="prism language-xml"><svg><rect width="300" height="100"stroke="red" stroke-width="4" fill="yellow" /> </svg> </code></pre> <p><strong>圆角矩形:</strong></p> <pre><code class="prism language-xml"><svg><rect x="50" y="20" rx="20" ry="20" width="150" height="150" style="fill:red;stroke:black;stroke-width:5;opacity:0.5"/> </svg> </code></pre> <h2>2. 圆形 circle</h2> <pre><code class="prism language-xml"><svg><circle cx="100" cy="50" r="40" stroke="black"stroke-width="2" fill="red"/> </svg> </code></pre> <h2>3. 椭圆形 ellipse</h2> <pre><code class="prism language-xml"><svg><ellipse cx="300" cy="80" rx="100" ry="50"style="fill:yellow;stroke:purple;stroke-width:2"/> </svg> </code></pre> <h2>4. 直线 line</h2> <pre><code class="prism language-xml"><svg><line x1="0" y1="0"x2="200" y2="200"style="stroke:rgb(255,0,0);stroke-width:2"/> </svg> </code></pre> <h2>5. 多边形 polygon</h2> <p><code><polygon></code> 标签用来创建含有不少于三个边的图形。</p> <p>多边形是由直线组成,其形状是"封闭"的(所有的线条 连接起来)。</p> <p><code>polygon</code>来自希腊。 “Poly” 意味 “many” , “gon” 意味 “angle”.</p> <p>如下代码可以生成一个三角形:</p> <pre><code class="prism language-xml"><svg height="400" width="400"><polygon points="0,0 200,200 0,400"style="fill:lime;stroke:purple;stroke-width:1"/> </svg> </code></pre> <h2>6. 折线 polyline</h2> <p>注意需把fill设成none</p> <pre><code class="prism language-xml"><svg><polyline points="20,20 40,25 60,40 80,120 120,140 200,180"style="fill:none;stroke:black;stroke-width:3" /> </svg> </code></pre> <h2>7. 路径 path</h2> <p><code><path></code> 标签用于定义一个路径。</p> <p>下面的命令可用于路径数据:</p> <ul><li>M = moveto</li><li>L = lineto</li><li>H = horizontal lineto</li><li>V = vertical lineto</li><li>C = curveto</li><li>S = smooth curveto</li><li>Q = quadratic Bézier curve</li><li>T = smooth quadratic Bézier curveto</li><li>A = elliptical Arc</li><li>Z = closepath 关闭路径</li></ul> <p><strong>注意</strong>:以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。</p> <p>如下例子定义了一条路径,它开始于位置150 0,到达位置75 200,然后从那里开始到225 200,最后在150 0关闭路径。(黑色三角形)</p> <pre><code class="prism language-xml"><svg><path d="M150 0 L75 200 L225 200 Z" /> </svg> </code></pre> <h2>8. 文本 text</h2> <pre><code class="prism language-xml"><svg><text x="0" y="15" fill="red" transform="rotate(30 20,40)">I love SVG</text> </svg> </code></pre> <h2>9. Stroke 属性</h2> <p>所有stroke属性,可应用于任何种类的线条</p> <ul><li>stroke 定义文本或元素轮廓颜色</li><li>stroke-width 定义文本或元素轮廓厚度</li><li>stroke-linecap 定义不同类型的开放路径的终结(线段终点的样式)</li><li>stroke-dasharray 用于创建虚线</li></ul> <h1>四、实践入门</h1> <h2>弧线运动</h2> <p>如下代码定义了一个弧线运动:点击后触发小方块沿着曲线无限循环运动</p> <pre><code class="prism language-xml"><svg width="800" height="800"><path d="M0 0 c0 300 300 300 300 0" stroke="red" stroke-width="2" fill="none"></path><rect x="0" y="0" width="40" height="40" fill="lightgreen"><animateMotion path="M0 0 c0 300 300 300 300 0" dur="3" begin="click" retate="auto" dur="3" repeatCount="indefinite" restart="auto"><animateMotion/></rect> </svg> </code></pre> <p>效果如下<br /> <img src="https://img.pic99.top/hhfamen/202406/b264748f54cdfc3.png" alt="在这里插入图片描述" /></p> <p>未完待续…下次研究详细的动画,这次稍微入个门</p> <blockquote> <p>https://www.jc2182.com/svg/svg-examples.html<br /> https://blog.csdn.net/sunxiaobai1/article/details/122862625</p> </blockquote> <p><img src="https://img.pic99.top/hhfamen/202406/62123d96113515c.gif" alt="在这里插入图片描述" /></p><link href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/markdown_views-0407448025.css" rel="stylesheet"><link href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/style-bb308a51ed.css" rel="stylesheet"> <!--end::Text--> </div> <!--end::Description--> <div class="mt-5"> <!--关键词搜索--> <a href="/index.php?s=news&c=search&keyword=%E8%AF%8D%E5%BA%93%E5%8A%A0%E8%BD%BD%E9%94%99%E8%AF%AF%3A%E6%9C%AA%E8%83%BD%E6%89%BE%E5%88%B0%E6%96%87%E4%BB%B6%E2%80%9CE%3A%5Chighferrum_mysql%5CConfiguration%5CDict_Stopwords.txt%E2%80%9D%E3%80%82" class="badge badge-light-primary fw-bold my-2" target="_blank">词库加载错误:未能找到文件“E:\highferrum_mysql\Configuration\Dict_Stopwords.txt”。</a> </div> <div class="mt-5"> <p class="fc-show-prev-next"> <strong>上一篇:</strong><a href="/keji/33668.html">C语言数据结构七:二叉树非递归遍历</a><br> </p> <p class="fc-show-prev-next"> <strong>下一篇:</strong><a href="/keji/33670.html">MATLAB | 这些花里胡哨的热图怎么画</a> </p> </div> <!--begin::Block--> <div class="d-flex flex-stack mb-2 mt-10"> <!--begin::Title--> <h3 class="text-dark fs-5 fw-bold text-gray-800">相关内容</h3> <!--end::Title--> </div> <div class="separator separator-dashed mb-9"></div> <!--end::Block--> <div class="row g-10"> </div> </div> <!--end::Table widget 14--> </div> <!--end::Col--> <!--begin::Col--> <div class="col-xl-4 mt-0"> <!--begin::Chart Widget 35--> <div class="card card-flush h-md-100"> <!--begin::Header--> <div class="card-header pt-5 "> <!--begin::Title--> <h3 class="card-title align-items-start flex-column"> <!--begin::Statistics--> <div class="d-flex align-items-center mb-2"> <!--begin::Currency--> <span class="fs-5 fw-bold text-gray-800 ">热门资讯</span> <!--end::Currency--> </div> <!--end::Statistics--> </h3> <!--end::Title--> </div> <!--end::Header--> <!--begin::Body--> <div class="card-body pt-3"> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202406/78b0249c98149a3.jpeg')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/33665.html" class="text-dark fw-bold text-hover-primary fs-6">监控摄像头接入GB28181平...</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202402/b7fd57091ce17d7.png')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/952.html" class="text-dark fw-bold text-hover-primary fs-6">Windows10添加群晖磁盘...</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202406/793e3f6ce04ed0b.png')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/33802.html" class="text-dark fw-bold text-hover-primary fs-6">protocol buffer...</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202403/98c3f25f21a67b3.png')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/7709.html" class="text-dark fw-bold text-hover-primary fs-6">在Word、WPS中插入AxM...</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202406/635b8ed7ba7c4e2.png')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/33708.html" class="text-dark fw-bold text-hover-primary fs-6">Fluent中创建监测点</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202405/9a5663f39d0d86.png')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/26657.html" class="text-dark fw-bold text-hover-primary fs-6">educoder数据结构与算法...</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">                                                  ...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202403/50b5d39a4edb96e.png')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/14338.html" class="text-dark fw-bold text-hover-primary fs-6">MySQL下载和安装(Wind...</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202403/9079391fc319.gif')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/9298.html" class="text-dark fw-bold text-hover-primary fs-6">MFC文件操作</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7"> MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('/static/assets/images/nopic.gif')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/33745.html" class="text-dark fw-bold text-hover-primary fs-6">有效的括号</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">一、题目 给定一个只包括 '(',')','{','}'...</span> </div> <!--end::Title--> </div> <!--begin::Item--> <div class="d-flex flex-stack mb-7"> <!--begin::Symbol--> <div class="symbol symbol-60px symbol-2by3 me-4"> <div class="symbol-label" style="background-image: url('https://img.pic99.top/hhfamen/202404/0a28a5fa0a16d86.png')"></div> </div> <!--end::Symbol--> <!--begin::Title--> <div class="m-0"> <a href="/keji/25416.html" class="text-dark fw-bold text-hover-primary fs-6">【Ctfer训练计划】——(三...</a> <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...</span> </div> <!--end::Title--> </div> </div> <!--end::Body--> </div> <!--end::Chart Widget 35--> </div> <!--end::Col--> </div> </div> <!--end::Content container--> </div> <!--end::Content--> </div> <!--end::Content wrapper--> <!--begin::Footer--> <div id="kt_app_footer" class="app-footer"> <!--begin::Footer container--> <div class="app-container container-xxl d-flex flex-column flex-md-row flex-center flex-md-stack py-3"> <!--begin::Copyright--> <div class="text-dark order-2 order-md-1"> <span class="text-muted fw-semibold me-1">2025 ©</span> <a href="/" target="_blank" class="text-gray-800 text-hover-primary">发门网</a> <a href="https://beian.miit.gov.cn/" target="_blank" class="text-gray-800 text-hover-primary"></a> <a href="http://www.bitekongjian.com">比特空间</a><a href="http://www.zzszq.net">深知网</a><a href="http://www.hysmm.com/">行业商贸网</a><a href="http://www.981608.com/">一路旅游网</a> </div> <!--end::Copyright--> <!--begin::Menu--> <ul class="menu menu-gray-600 menu-hover-primary fw-semibold order-1"> <li class="menu-item"> <a href="/news/" target="_blank" class="menu-link px-2">资讯</a> </li> <li class="menu-item"> <a href="/shenghuo/" target="_blank" class="menu-link px-2">生活</a> </li> <li class="menu-item"> <a href="/keji/" target="_blank" class="menu-link px-2">科技</a> </li> <li class="menu-item"> <a href="/sitemap.xml" target="_blank" class="menu-link px-2">sitemap</a> </li> </ul> <!--end::Menu--> </div> <!--end::Footer container--> </div> <!--end::Footer--> </div> <!--end:::Main--> </div> <!--end::Wrapper--> </div> <!--end::Page--> </div> <!--end::App--> <div id="kt_scrolltop" class="scrolltop" data-kt-scrolltop="true"> <!--begin::Svg Icon | path: icons/duotune/arrows/arr066.svg--> <span class="svg-icon"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <rect opacity="0.5" x="13" y="6" width="13" height="2" rx="1" transform="rotate(90 13 6)" fill="currentColor"></rect> <path d="M12.5657 8.56569L16.75 12.75C17.1642 13.1642 17.8358 13.1642 18.25 12.75C18.6642 12.3358 18.6642 11.6642 18.25 11.25L12.7071 5.70711C12.3166 5.31658 11.6834 5.31658 11.2929 5.70711L5.75 11.25C5.33579 11.6642 5.33579 12.3358 5.75 12.75C6.16421 13.1642 6.83579 13.1642 7.25 12.75L11.4343 8.56569C11.7467 8.25327 12.2533 8.25327 12.5657 8.56569Z" fill="currentColor"></path> </svg> </span> <!--end::Svg Icon--> </div> <!--begin::Javascript--> <script>var hostUrl = "/static/default/pc/";</script> <!--begin::Global Javascript Bundle(mandatory for all pages)--> <script src="/static/default/pc/plugins/global/plugins.bundle.js"></script> <script src="/static/default/pc/js/scripts.bundle.js"></script> <!--end::Global Javascript Bundle--> <!--end::Javascript--> </body> <!--end::Body--> </html>