当前位置: 首页 > news >正文

web开发对于svg的简单应用

web开发对于svg的简单应用

@jarringslee

文章目录

  • web开发对于svg的简单应用
    • 认识svg
    • SVG绘制图形
      • 基本形状绘制
      • text 绘制文本
      • path 绘制路径
      • g 公共属性标签
      • 小案例: 绘制二次贝塞尔曲线模拟静态图
    • SVG描边属性
      • 模糊和阴影效果
      • 线性渐变和径向渐变
      • clip-path 裁剪
    • JS操作SVG:简单的DOM操作和事件绑定
      • 获取并设定属性
      • 设置常规样式
      • 绑定事件
      • 小案例:控制矩形的缩放和移动
      • 小案例:环形进度条

认识svg

SVG,可缩放矢量图,是解决网站图标问题的最佳方案,是基于XML语法的一种图像格式

平常使用的图片或者图标一般是基于像素处理的,放大会失真,而SVG是对图片的一种形状描述,本质上是一种文本文件,体积较小,也不会失真。

svg的表现属性(fill、font-size等)可以利用css选择器进行修改,但是几何属性(x、y、cx、cy、rotate等)不能通过css修改,只能写死在svg标签中或利用js获取DOM节点进行修改。

请添加图片描述

我们不仅利用svg来绘制图标,还用它来创造出更复杂的装饰或图案。

请添加图片描述

来自于 unDraw - Open source illustrations for any idea 首页

SVG在html的基本格式是:

<svg ......><图形元素a></图形元素a><图形元素b/>......
</svg>

在svg标签中,我们可能会添加到以下常用属性:

属性说明是否必须常用取值示例
xmlns声明默认命名空间,告诉浏览器“这是 SVG 文档”必须(文件独立时)xmlns="http://www.w3.org/2000/svg"
xmlns:xlink声明 xlink 前缀命名空间,后面可用 <use xlink:href="">用到 xlink 时加xmlns:xlink="http://www.w3.org/1999/xlink"
width / height画布外在尺寸;不写时默认 300×150 pxwidth="200"width="100%"
viewBox逻辑坐标系 “minX minY width height”,实现缩放+居中强烈建议写viewBox="0 0 24 24"
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
</svg>

SVG绘制图形

svg类似于行内块元素,可以设置大小、移动位置、动画等,同时有自己的特殊性样式属性

属性描述取值示例
height width定义画布的高和宽单位可以不带。默认为像素
X Y定义画布距离上级元素左侧 上部的值单位可以不带。默认为像素
fill填充颜色(支持颜色值、渐变、图案)不需要改为nonefill: #foo;
fill-opacity填充颜色的不透明度0(完全透明) ~ 1(完全不透明)
opacity整体图形的不透明度(包括内容和描边)0(完全透明) ~ 1(完全不透明)
rx ry边角的圆度值默认像素
cx cy r定义圆(椭圆)形中心的x、y坐标和半径坐标默认(0,0)单位全都默认像素
rx ry定义椭圆形的水平半径和垂直半径坐标默认(0,0)单位全都默认像素
x1 y1 x2 y2定义直线line的起点坐标和终点坐标单位默认像素
points定义多边形polygon每个角的坐标、多线条polyline每个拐点的坐标横竖坐标用逗号隔开,每组坐标用空格隔开
dx dy元素相对于已确认坐标(x,y)的偏移量默认不偏移,默认单位为像素一般用于直接给某个元素旁边添加元素

基本形状绘制

基本形状全都可以作为单标签使用。例如:

<rect x="20" y="10" width="180" height="80" rx="10" ry="10" fill="#4fc" fill-opacity="0.6" stroke="#333" stroke-width="4" stroke-dasharray="8,4" transform="rotate(15 110 50)" opacity="0.9" class="myRect"/>

其中,所有属性均可挪到css中编辑(html中写的属性权重最高),下面的单标签和形状标签也可以有该属性。

同一个svg标签中写多个图形可以进行堆叠,堆叠顺序由html书写顺序决定(后来者居上)。

svg所有图形坐标都是根据画布(包裹它的svg标签)来确定的,水平向右为x轴正方向,竖直向下为y轴正方向。如(0,0)在画布的左上角。

以下图形的示例代码均默认已被svg标签<svg width="200" height="300"> </svg> 包裹。

  • 矩形 rect <rect width="300" height="100" fill="blue" stroke-width="3" stroke="black" />

  • 圆形circle <circle fill="blue" cx="50" cy="100" r="30" />

  • 椭圆 ellipse 具有水平和垂直两种半径 <ellipse cx="100" cy="80" rx="50" ry="30" fill="yellow" stroke-width="2" />

  • 线条 line fill属性一般情况下无效 <line x1="10" y2="25" x2="60" ry="90" stroke="blue" stroke-width="2" />

  • 多边形 polygon 用于创建至少包含三个边的封闭图形 <polygon points="100,10 40,198 198,78 10,78 160,198" fill="yellow" stroke="blue" stroke-width="2" />

  • 多线条 polyline 创建具有拐点的折线。这里的fill会默认为黑色,填充区域为始终点连线围城的封闭区域 <polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160" fill="none" stroke="blue" stroke-width="4" />

  • 路径 path

text 绘制文本

基本标签:text标签(双标签)

<text x="100" y="100" font-size="30" text-anchor="start">我是一段文本</text>

  • x y:文本定位坐标
  • text-anchor:文本根据坐标的对齐方式(start/middle/end)

相比于p等标签的优点:可以使用svg特有的属性(如旋转)来控制文本。

旋转属性:transform="rotate(旋转角度 旋转点坐标)"

我是一段文本

其中,角度和坐标用空格隔开,坐标间用逗号隔开,旋转点坐标省略默认(0,0)

text标签中可以包含多个相互独立的文本,每个文本用tspan标签包裹,每个tspan标签都可以有独立的属性。

<text><tspan x="10" y="10">111</tspan><tspan x="40" y="50">222</tspan><text>

给text添加超链接属性: 用a标签包裹text标签,链接属性和普通a标签略有不同(因为svg是基于XML的语言),且需要在外层的svg标签添加一个链接。

    <svg width="200" height="200" xmlns:xlink="http://www.w3.org/1999/xlink"><a xlink:href="https://pvp.qq.com" target="_blank"><text x="10" y="30" transform="rotate(30 20,40)"  text-anchor="start">欢迎来到王者荣耀</text></a></svg>
欢迎来到王者荣耀

path 绘制路径

基本属性: <path d="M150 0 l75 200">

其中,d为绘制命令(draw),以下单个字母都是包含在d中的常用命令。

最基础的命令:

  • M:起点坐标(moveto) 大写字母M后接空格隔开的坐标,代表图形绘制的起点坐标
  • L:朝向坐标(lineto) 小写字母l后接空格隔开的坐标,代表上一个结束点(通常是M点)到该点绘制一条直线
  • 字母大小写意义不同大写表示绝对定位(根据画布定位),小写表示相对定位(根据上一个结束点,大小写都可以)
  • 字母和横坐标之间也可以有一个空格

较为高级的常用绘制命令:

path绘制图形相比于polydgon的优点:可以绘制更加复杂的、包含曲线的矢量图形。

  • q:绘制二次贝塞尔曲线 q后跟两组坐标(全部用空格隔开,q和第一个坐标之间也可以有空格)第一个坐标表示控制点,第二个坐标表示终点(起点为上一个结束点)。

    控制点分别和起点、终点相连,可构成绘制曲线的“辅助三角形”:

    1. 曲线始终从起点出发,向控制点方向拉伸,但不会经过控制点(除非退化成直线)。
    2. 曲线在起点处与 起点→控制点 线段相切;在终点处与 控制点→终点 线段相切。
    3. 控制点离曲线越远,曲线被“拉”得越弯;三点共线时,曲线退化成一条直线。

g 公共属性标签

在svg中可以用g标签把一些具有相同属性的标签包裹起来,在g标签上定义公共的属性。

<g><path /><circle /><text> </text>
</g>

g标签只能放置fill、stroke、font-size等属性这些通用属性支持继承,不能放置某些标签特有的属性如偏移量dx、定位属性等。

小案例: 绘制二次贝塞尔曲线模拟静态图

模拟贝塞尔曲线的点位和辅助线

  • 绘制起点、控制点和终点并利用偏移量标注各点字母;
  • 两条线段分别连接起点和控制点、控制点和终点,且两条线段上有一条切线;
  • 根据三点绘制贝塞尔曲线本体。
  <svg width="450" height="400"><!-- 把点位绘制放在最后的原因: 让点不被线段压住 方便观察--><!--4. 绘制AB、BC两条线段  --><g stroke="red" stroke-width="3" fill="none"><path d="M100 350 l150 -300" /><path d="M250 50 l150 300" /></g><!--5. 绘制连接AB与BC的曲线切线  --><path d="M175 200 l150 0" stroke="green" stroke-width="3" fill="none" /><!-- 6. 绘制贝塞尔曲线 --><path d="M100 350 q150 -300 300 0" stroke="blue" stroke-width="5" fill="none" /><!-- 2. 绘制出三个点 --><g fill="darkblue"><circle cx="100" cy="350" r="3" /><circle cx="250" cy="50" r="3" /><circle cx="400" cy="350" r="3" /></g><!-- 3. 利用偏移量绘制三个点的名称 --><g dx="-30" font-size="25"><text x="100" y="350" dx="-30">A</text><text x="250" y="50" dx="-30">B</text><text x="400" y="350" dx="-30">C</text></g></svg>
A B C

SVG描边属性

基本属性:

属性描述取值示例
stroke 笔画属性定义描边颜色(支持颜色值、渐变、图案)stroke:#fo0;
stroke-width 笔画宽度属性描边宽度(支持像素、百分比、px、em等单位)stroke-width: 2px;
stroke-linecap 笔画笔帽属性定义描边线段两边的线头形状butt(无线帽)、round(圆形线帽)、square(方形线帽)
stroke-dasharray虚线模式(实线长度+间隔长度)stroke-dasharray: 10 ;
stroke-dashoffset调整虚线与间隔的起始位置stroke-dashoffset: 100;
stroke-opacity描边颜色的不透明度0(完全透明) ~ 1(完全不透明)

stroke-dasharray 虚线笔画属性可以定义一个或多个数字 调整虚线属性,实现和虚线的间隔值。

  • stroke-dasharray:100; 默认px,实现和虚线间隔都是100

  • stroke-dasharray:100 50; 100px是实线长度,50px是实现间隔(虚线长度)

  • stroke-dasharray:100 50 5 10 10 5; 分别为实线和虚线交替的长度

stroke-dasharray的应用 鼠标经过添加描边动画效果

  1. 使用@keyframes创造动画效果:设置两个(0% 100%)或多个关键帧的不同虚线模式的数值
  2. 使用:hover为svg添加该动画效果。

stroke-dashoffset 用于调整虚线模式的起始偏移量。增大该属性能让虚线模式向路径起点移动,视觉上像线条被擦除。

stroke-dashoffset的应用 鼠标经过添加描边动画效果 做法同上

模糊和阴影效果

SVG效果标签都要包含在defs标签中

给svg添加特殊效果的基本标签:defs嵌套filter 一个filter元素可包含一个或多个效果滤镜

filter有一个必要的id属性用于识别过滤器,图形通过id指向要使用的过滤器

图形中用filter="url(# )"来声明id,id属性的值要保持唯一性

x、y为滤镜的起始点坐标

<defs><filter id="f111" x="" y=""></filter>
</defs><rect filter="url(#f111)"/>

模糊效果: feGaussianblur 高斯模糊效果(单标签),利用stdDeviation属性定义模糊的数值(数值越高模糊效果越明显)

阴影效果: feOffset feBlend 其本质为将图像根据原位置偏移作为阴影

<filter><feOffset dx="" dy="" in="" /><feBlend in="" />
</filter>

feOffset 阴影偏移

  • dx dy 表示根据原位置偏移的量,单位为像素
  • in 表示阴影图像来源,通常有两个值
    • SourceAlpha 原图像的黑色形状作为阴影
    • SourceGraphic 原始图像作为阴影

feBlend 在偏移图像上方混合原始图像

in属性一般为原始图像SourceGraphic

线性渐变和径向渐变

线性渐变 linearGradient 可实现水平渐变、垂直渐变或角度渐变等从某点向另一点的线性渐变。

同样也需要id属性。

<defs><linearGradient x1="" y1="" x2="" y2="" id=""><stop offset="10%" stop-color="yellow"/><stop offset="" stop-color=""/><stop offset="" stop-color=""/></linearGradient>
</defs>
  • x1 y1 x2 y2表示渐变的起点坐标和终点坐标。
    • x1=x2 y1≠y2 产生垂直渐变
    • x1≠x2 y1=y2 产生水平渐变
    • x1≠x2 y1≠y2 产生角度渐变
  • linearGradient标签中需要嵌套一个或多个stop标签来表示u原色
    • offset一般为百分数,表示该颜色所在渐变轨迹中的相对位置(0%为起点处,100%为终点处)
    • stop-color为一个颜色值

径向渐变 radialGradiet 可实现某个点由内向外圆形渐变的效果

<defs><radialGradient id="" cx="" cy="" r="" fx="" fy="">	<stop offset="10%" stop-color="yellow"/><stop offset="" stop-color=""/><stop offset="" stop-color=""/></radialGradient>
</defs>

其中,cx cy r属性定义了外层圆的基本特征,fx fy定义了内层圆的基本特征。

clip-path 裁剪

创建复杂的裁剪形状,使元素仅显示被裁剪区域内的部分

语法: clip-path: 内置几何形

内置几何形如: circle()、polygon()等

.circle {clip-path:circle(40% at 50% 50%)
}

可视化工具: https://tools.jb51.net/static/api/css3path/index.h

相关图性参数在里面查阅:选中并调节好所需图形,粘贴下面的代码到目标盒子的选择器即可。

JS操作SVG:简单的DOM操作和事件绑定

获取并设定属性

对于常用的svg标签,基本的svg属性都会写死在html标签中,一般不会用css选择器进行操作,此时若想要设置或修改svg属性,就需要用到js来获取DOM节点并调用。

获取DOM节点

一般我们给svg标签设置 classid或**自定义id **来方便我们使用js调用。均使用常规的文档对象调用方式 document.querySelector 即可。

我们想操作下面矩形的svg属性:

<svg width="350" height="300"><rect x="50" y="50" width="100" height="75" class="rect" id="r111" data-ljlid="myrect" stroke="red" fill="none"></rect>
</svg>

只需通过以上任一方式获取该矩形svg的DOM节点即可:

  1. class属性

    var rect1 = document.querySelector('.rect')
    
  2. id属性

    var rect1 = document.querySelector('#r111')
    
  3. 自定义id属性

    var rect1 = document.querySelector('[data-ljlid = "myrect"]')
    

设置属性

我们利用 getAttribute 来获取标签内的属性。获取到的数据一般为字符串形式,所以在获取数字类型的值时,需要提前加上 parseFloat

var width = parseFloat(rect.getAttribute("width"))
var height = parseFloat(rect.getAttribute("height"))

我们获取到了矩形的DOM节点和想要操作的属性值后,可以直接使用 setAttribute 来修改该属性的值。

节点名.setAttribute("属性名", 属性值)

对于属性值,如果时数字类型变量则需添加引号,纯使用已声明的变量进行算术运算则不用。此外,也支持字符串拼接、反引号等操作。

rect.setAttribute("width", width *= 1.1)
var red = 200
var green = 50
var blue =0
rect.setAttribute('fill', `rgb(${red}, ${green}, ${blue})`)

设置常规样式

不仅css可以调用的font-size、display、visibility等基本属性还有以下svg样式属性也可以利用 节点名.style. 直接调用

  • fill
  • opacity
  • stroke

注意一些属性名有连接符的,在调用时应该改成驼峰命名法。

  • strokeWidth strokeLinecap
  • fillOpacity fillRule

像 transform x y rx ry points 等几何属性则只能用 setAttribute 读写。

rect.style.fill = "aqua"

绑定事件

对于svg的一些简单页面交互,只需绑定相应事件即可。

如最常见的设置按钮并绑定点击事件:

   <button class="btn1">我是按钮</button><script>var btn1 = document.querySelector('.btn1')btn1.onclick = function (){// 添加svg操作}</script>

onclick 写法简单,但换成 addEventListener('click', ...) 更通用,可多次绑定。

另外,也可以在其他函数如计时函数中操作svg属性:

var move = setInterval(function () {// 添加svg操作// 也可设置清除计时器函数if (......) {clearInterval(move)}}, 20)}

我们经常利用 setInterval 每一定毫秒执行像素级别移动、收缩等svg任务的特性来创造动画效果。

后面可用 requestAnimationFrame 替代 setInterval,刷新率同步,动画更顺滑。

小案例:控制矩形的缩放和移动

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>svg {overflow: visible;outline: 1px dashed gray;}</style>
</head><body><svg width="350" height="300"><rect x="50" y="50" width="100" height="75" class="rect" fill="aqua"></rect></svg><br><button class="btn1">放大矩形</button><button class="btn2">移动矩形</button><button class="btn3">动画移动</button><script>var btn1 = document.querySelector('.btn1')var btn2 = document.querySelector('.btn2')var btn3 = document.querySelector('.btn3')var rect = document.querySelector('.rect')btn1.onclick = function () {console.log(rect)var width = parseFloat(rect.getAttribute("width"))var height = parseFloat(rect.getAttribute("height"))rect.style.fill = "orange"if (width > 400) {width = 100, height = 75rect.style.fill = "aqua"}rect.setAttribute("width", width *= 1.1)rect.setAttribute("height", height *= 1.1)}btn2.onclick = function () {console.log(rect)var x = parseFloat(rect.getAttribute("x"))var y = parseFloat(rect.getAttribute("y"))rect.style.fill = "pink"if (x > 230) {x = 5, y = 5rect.style.fill = "aqua"}rect.setAttribute("x", x += 10)rect.setAttribute("y", y += 10)}btn3.onclick = function () {console.log(rect)var x = parseFloat(rect.getAttribute("x"))var y = parseFloat(rect.getAttribute("y"))// var position = 2var move = setInterval(function () {// position += 2;rect.setAttribute("x", x++)rect.setAttribute("y", y++)if (x > 250) {clearInterval(move)rect.setAttribute("x", 50)rect.setAttribute("y", 50)}}, 20)}</script>
</body></html>

小案例:环形进度条

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>循环进度条</title><style>.text {/* 文字水平居中 */text-anchor: middle;dominant-baseline: middle;}body {text-align: center;}</style>
</head><body><svg xmlns="http://www.w3.org/2000/svg" height="700" width="700"><!-- 设置底色圆环 --><circle cx="350" cy="350" r="300" fill="none" stroke="grey" stroke-width="40" stroke-linecup="round"></circle><!-- 设置进度条 transform旋转:让圆环起点在正上方--><circle class="progress" transform="rotate(-90, 350, 350)" cx="350" cy="350" r="300" fill="none" stroke="blue"stroke-width="40" stroke-linecap="round" stroke-dasharray="0,10000" /><!-- 设置文本 --><text class="text" x="350" y="350" font-size="200" fill="red">36</text></svg><script>// 获取进度圆环对象var progressDom = document.querySelector('.progress')// 获取文本对象var textDom = document.querySelector('.text')function rotateCircle(persent) {// 获取圆环总长:通过半径计算var circleLength = Math.floor(2 * Math.PI * parseFloat(progressDom.getAttribute("r")))// 按照百分比算出圆环当前长度var value = persent * circleLength / 100// 配置颜色变化// 红色rgb:255,0,0// 蓝色rgb:0,191,255var red = 255 + parseInt((0 - 255) / 100 * persent)var green = 0 + parseInt((191 - 0) / 100 * persent)var blue = 0 + parseInt((255 - 0) / 100 * persent)// 设置dark-dasharray和路径颜色progressDom.setAttribute("stroke-dasharray", value + ', 10000')progressDom.setAttribute("stroke", `rgb(${red}, ${green}, ${blue})`)// 填充文本并设置颜色textDom.innerHTML = persent + '%'textDom.setAttribute('fill', `rgb(${red}, ${green}, ${blue})`)}// 设置动画:每间隔30ms百分比+1let num = 0setInterval(() => {num++if (num > 100) {num = 0}rotateCircle(num)}, 60)</script>
</body></html>
http://www.dtcms.com/a/517434.html

相关文章:

  • photoshop+做网站logo有谁认识做微网站的
  • xss-labs pass-09
  • 每日两题day20
  • 第二章的时间服务
  • 台州网站建设咨询做快三网站
  • 规划网站站点需要遵循哪些原则免费qq注册入口
  • 深入浅出:详解内存模组U-DIMM与R-DIMM,并厘清与eMMC/Flash的区别
  • 网站设计内容包括明光网站
  • 免费论坛网站大全网站域名如何影响seo
  • Android Crash分析和解决方法总结
  • 常德市做公司网站的公司网络工程师证书报名
  • 上传到网站的根目录中湘潭网站建设方案案例
  • 权重网站建设八大员继续教育入口
  • html做音乐网站网站建设项目实施计划书
  • 从零学算法71
  • 河南企业网站优化外包中低端网站建设客户网
  • Windows Subsystem for Linux 2 (WSL2):Windows 10 11 完全教程(更新至2025年)
  • Python函数进阶秘籍:闭包、装饰器与作用域全解析(通俗版)
  • 软件设计师知识点总结:数据结构与算法(超级详细)
  • 企业网站带手机源码中国最贵的域名交易
  • 做代刷网站赚钱不问政烟台网站
  • 出口贸易公司网站怎么做小程序appid在哪里找
  • 来年做哪个网站能致富建设银行沈阳分行网站
  • 网络攻防技术:网络防御概述
  • 黄页88网站推广怎么样怎样建设凡科网站
  • C#:数组不能使用Const修饰符
  • 个人网站建设 实验报告8080端口wordpress
  • 如何做网站地图最新军事消息
  • 网站半年了 没有流量网站空间的价格
  • 兴义做网站的公司住房和城乡建设部网站注册进度