svg 初识+了解 + 应用 + 动画
文章目录
- svg
- 补充
- svg应用实例
- HTML部分
- JavaScript部分
- 技术名词解释
svg
一、SVG(可缩放矢量图形)简介
SVG是一种用于描述二维矢量图形的XML(可扩展标记语言)标记语言。它与基于像素的图像格式(如JPEG、PNG)不同,SVG图形在放大或缩小的过程中不会失真,因为它是基于数学公式来描述图形的形状和位置的。这使得SVG在各种不同的屏幕分辨率和设备尺寸下都能提供高质量的图形显示。
二、基础标签
-
<svg>
标签- 这是SVG图形的根标签。它定义了SVG图形的整体范围和一些基本属性。例如:
<svg width="100px" height="100px"><!-- 在这里添加其他SVG元素 --> </svg>
width
和height
属性用于指定SVG图形的尺寸,可以使用像素(px)、百分比等单位。
-
<rect>
标签(矩形)- 用于绘制矩形。例如:
<svg width="200px" height="200px"><rect x="10" y="10" width="100" height="100" fill="blue"/> </svg>
x
和y
属性指定矩形左上角的坐标,width
和height
属性指定矩形的宽度和高度,fill
属性用于指定填充颜色。
-
<circle>
标签(圆)- 用来绘制圆。例如:
<svg width="200px" height="200px"><circle cx="100" cy="100" r="50" stroke="black" stroke - width="2" fill="none"/> </svg>
cx
和cy
属性分别是圆心的x坐标和y坐标,r
属性是圆的半径。stroke
属性指定轮廓颜色,stroke - width
属性指定轮廓宽度,fill
属性指定填充内容,这里设置为none
表示不填充。
-
<line>
标签(直线)- 用于绘制直线。例如:
<svg width="200px" height="200px"><line x1="10" y1="10" x2="100" y2="100" stroke="red" stroke - width="2"/> </svg>
x1
和y1
是直线起点的坐标,x2
和y2
是直线终点的坐标,同样可以通过stroke
和stroke - width
属性设置线条的颜色和宽度。
-
<polygon>
标签(多边形)- 用于绘制多边形。例如:
<svg width="200px" height="200px"><polygon points="50,10 90,10 70,50" fill="green"/> </svg>
points
属性包含一系列用逗号分隔的坐标对,用于定义多边形的顶点位置。
-
<text>
标签(文本)- 用于在SVG中添加文字。例如:
<svg width="200px" height="200px"><text x="50" y="50" font - size="16" fill="black">Hello SVG</text> </svg>
x
和y
属性指定文本的起始位置,font - size
属性指定字体大小,fill
属性指定文字颜色。
三、参数(以<rect>
标签为例)
- 几何参数
x
、y
、width
、height
:如前面所述,用于确定矩形的位置和大小。这些参数可以是具体的数值,也可以是通过JavaScript等动态设置的值。
- 样式参数
fill
:除了使用颜色名称(如red
、blue
等)填充,还可以使用CSS渐变(如线性渐变linear - gradient
、径向渐变radial - gradient
)来填充。例如:
<svg width="200px" height="200px"><rect x="10" y="10" width="100" height="100"><linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop - color="yellow"/><stop offset="100%" stop - color="red"/></linearGradient><rect fill="url(#grad1)"/></rect> </svg>
stroke
和stroke - width
:stroke
还可以设置为虚线等样式,通过stroke - dasharray
属性。例如stroke - dasharray="5,5"
会创建一个由5px长的线段和5px长的间隔组成的虚线。opacity
:用于设置元素的透明度,取值范围从0(完全透明)到1(完全不透明)。
四、应用
-
网页设计中的图标制作
- SVG非常适合制作网页图标。因为它可以方便地通过CSS进行样式修改,并且在不同的屏幕分辨率下都能保持清晰。例如,许多网站的导航栏图标都是用SVG制作的。设计师可以轻松地改变图标的颜色(通过修改
fill
属性)来适应不同的主题。
- SVG非常适合制作网页图标。因为它可以方便地通过CSS进行样式修改,并且在不同的屏幕分辨率下都能保持清晰。例如,许多网站的导航栏图标都是用SVG制作的。设计师可以轻松地改变图标的颜色(通过修改
-
数据可视化
- 在数据可视化领域,SVG可以用于绘制各种图表。例如,使用SVG绘制柱状图、折线图、饼图等。通过JavaScript可以动态地更新图表中的数据,改变图形的形状和位置。与基于像素的图像相比,SVG图表在交互过程中(如放大查看细节)能够提供更好的用户体验。
-
动画制作
- SVG支持通过CSS动画和JavaScript动画来实现图形的动画效果。例如,可以制作一个旋转的圆形动画。在CSS中,可以这样定义动画:
@keyframes rotate {from {transform: rotate(0deg);}to {transform: rotate(360deg);} } circle {animation: rotate 2s infinite linear; }
- 这个动画会让圆形在2秒内无限循环地线性旋转。
-
响应式设计
- 由于SVG图形能够自适应不同的设备尺寸,它在响应式网页设计中非常有用。可以根据屏幕的宽度和高度动态地调整SVG图形的大小和布局,确保图形在桌面浏览器、平板电脑和手机等各种设备上都能呈现出良好的视觉效果。
五、实例
以下是一个简单的数据可视化实例,使用SVG绘制一个柱状图来展示不同产品的销量。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF - 8"><title>SVG柱状图示例</title><style>svg {border: 1px solid gray;}</style>
</head>
<body><svg width="400px" height="300px"><rect x="50" y="250" width="30" height="0" fill="blue" data - value="100"/><rect x="100" y="250" width="30" height="0" fill="green" data - value="150"/><rect x="150" y="250" width="30" height="0" fill="red" data - value="200"/></svg><script>// 获取所有的矩形元素var rects = document.querySelectorAll('svg rect');for (var i = 0; i < rects.length; i++) {var value = parseInt(rects[i].getAttribute('data - value'));var height = value * 2; // 根据数据设置高度rects[i].setAttribute('height', height);}</script>
</body>
</html>
在这个例子中:
- 首先在HTML中创建了一个SVG元素,并在其中添加了三个矩形(代表不同的产品),初始高度都为0,并且通过
data - value
属性存储了每个产品的销量数据。 - 然后通过JavaScript获取所有的矩形元素,读取
data - value
属性的值,根据这个值计算出每个矩形的实际高度,并更新矩形的height
属性,从而生成一个简单的柱状图来展示产品销量。
补充
-
<path>
标签概述<path>
是SVG中最强大的元素之一,它可以用来描述复杂的形状,如不规则多边形、曲线等。它通过一个叫做路径命令(path commands)的特殊语法来定义形状。路径命令是一系列字母和数字的组合,这些组合告诉浏览器如何绘制路径。
-
基本路径命令
- 移动命令(M/m)
M
(绝对坐标)和m
(相对坐标)用于将画笔移动到指定的位置,开始一个新的子路径。例如,M10 20
表示将画笔移动到坐标为(10,20)
的点(绝对坐标),m5 5
表示将画笔从当前位置相对移动(5,5)
的距离。
- 直线命令(L/l、H/h、V/v)
L
(绝对坐标)和l
(相对坐标)用于绘制直线。例如,L30 40
会从当前位置画一条直线到坐标为(30,40)
的点,l10 10
会从当前位置相对地画一条直线,终点相对于起点的偏移量为(10,10)
。H
(绝对水平坐标)和h
(相对水平坐标)用于绘制水平直线。H50
会画一条水平直线到x = 50
的位置(绝对坐标),h10
会从当前位置向右水平移动10个单位(相对坐标)。V
(绝对垂直坐标)和v
(相对垂直坐标)用于绘制垂直直线。V60
会画一条垂直直线到y = 60
的位置(绝对坐标),v - 10
会从当前位置向下垂直移动10个单位(相对坐标)。
- 曲线命令(C/c、S/s、Q/q、T/t)
- 三次贝塞尔曲线(C/c):
C
(绝对坐标)和c
(相对坐标)用于绘制三次贝塞尔曲线。它需要三个控制点和一个终点来定义曲线。例如,C10 20,30 40,50 60
表示从当前位置绘制一条三次贝塞尔曲线,第一个控制点是(10,20)
,第二个控制点是(30,40)
,终点是(50,60)
(绝对坐标)。 - 平滑三次贝塞尔曲线(S/s):
S
(绝对坐标)和s
(相对坐标)用于绘制平滑的三次贝塞尔曲线。它会自动根据前一个曲线的控制点来生成第一个控制点,以保证曲线的平滑过渡。 - 二次贝塞尔曲线(Q/q):
Q
(绝对坐标)和q
(相对坐标)用于绘制二次贝塞尔曲线。它需要一个控制点和一个终点来定义曲线。例如,Q20 30,40 50
(绝对坐标)。 - 平滑二次贝塞尔曲线(T/t):
T
(绝对坐标)和t
(相对坐标)用于绘制平滑的二次贝塞尔曲线,和S
类似,它会利用前一个曲线的信息来保证平滑。
- 三次贝塞尔曲线(C/c):
- 闭合路径命令(Z/z)
Z
或z
用于闭合当前路径。它会将路径的最后一个点和第一个点连接起来,形成一个封闭的形状。例如,绘制一个三角形可以使用M10 10 L30 10 L20 30 Z
。
- 移动命令(M/m)
-
<path>
标签的属性d
属性- 这是
<path>
标签最重要的属性,它包含了路径命令的字符串。例如:
<svg width="200px" height="200px"><path d="M10 10 L50 10 L30 40 Z" fill="blue"/> </svg>
- 这个路径先移动到
(10,10)
,然后画直线到(50,10)
,再画直线到(30,40)
,最后闭合路径,并且填充颜色为蓝色。
- 这是
fill
属性- 用于指定路径的填充颜色。除了颜色名称,还可以是渐变(如线性渐变
linear - gradient
、径向渐变radial - gradient
)或者图案(pattern
)。例如:
<svg width="200px" height="200px"><linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop - color="yellow"/><stop offset="100%" stop - color="red"/></linearGradient><path d="M10 10 L50 10 L30 40 Z" fill="url(#grad1)"/> </svg>
- 用于指定路径的填充颜色。除了颜色名称,还可以是渐变(如线性渐变
stroke
和stroke - width
属性stroke
用于指定路径轮廓的颜色,stroke - width
用于指定轮廓的宽度。例如:
<svg width="200px" height="200px"><path d="M10 10 L50 10 L30 40 Z" stroke="black" stroke - width="2" fill="none"/> </svg>
- 这里路径不填充(
fill="none"
),只绘制一个宽度为2px的黑色轮廓。
-
应用示例
- 绘制复杂形状
- 比如绘制一个爱心形状。爱心可以通过两个半圆和一个三角形组合而成。
<svg width="200px" height="200px"><path d="M100,100 m-50,0 a50,50 0 1 0 100,0 a50,50 0 1 0 -100,0 Z" fill="red"/> </svg>
- 这里的
a
命令是椭圆弧(arc)命令,用于绘制弧线。a50,50 0 1 0 100,0
表示绘制一个以当前点为起点,半径为50的椭圆弧,0 1
是一些标志位,0 100,0
是终点坐标。通过组合两个这样的椭圆弧和一个闭合命令Z
,就可以绘制出一个爱心形状。
- 与JavaScript结合实现动态路径
- 可以通过JavaScript动态地修改
<path>
标签的d
属性来实现动画或者交互效果。例如,下面是一个简单的代码,用于实现一个路径的拉伸效果。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF - 8"><title>SVG Path动态示例</title><style>svg {border: 1px solid gray;}</style> </head> <body><svg width="200px" height="200px"><path id="myPath" d="M10 10 L20 10" stroke="black" stroke - width="2" fill="none"/></svg><button onclick="stretchPath()">拉伸路径</button><script>function stretchPath() {var path = document.getElementById('myPath');var d = path.getAttribute('d');var newD = d.replace('L20 10', 'L50 10');path.setAttribute('d', newD);}</script> </body> </html>
- 当点击按钮时,JavaScript代码获取
<path>
元素的d
属性,修改其中的直线终点坐标,然后更新d
属性,从而实现路径的拉伸效果。
- 可以通过JavaScript动态地修改
- 绘制复杂形状
svg应用实例
使用SVG绘制一条贝塞尔曲线和一个小球,并让小球绕贝塞尔曲线循环往复运动的示例代码:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>SVG贝塞尔曲线与循环运动小球</title><style>svg {border: 1px solid gray;width: 500px;height: 300px;}</style>
</head><body><svg id="bezierSVG"><!-- 绘制贝塞尔曲线 --><path id="bezierPath" d="M50,250 C150,100 300,300 400,250" stroke="blue" stroke-width="2" fill="none" /><!-- 绘制小球 --><circle id="ball" cx="50" cy="250" r="10" fill="red" /></svg><script>window.onload = function () {// 获取SVG元素、贝塞尔曲线路径元素和小球元素var svg = document.getElementById('bezierSVG');var bezierPath = document.getElementById('bezierPath');var ball = document.getElementById('ball');// 获取贝塞尔曲线的总长度var pathLength = bezierPath.getTotalLength();// 小球运动参数var t = 0; // 当前位置在路径上的比例,范围从0到1var speed = 0.01; // 小球运动速度// 用于循环往复运动的标志var forward = true;// 函数用于更新小球的位置function updateBallPosition() {// 根据t的值获取贝塞尔曲线上对应位置的点var point = bezierPath.getPointAtLength(t * pathLength);// 更新小球的位置ball.setAttribute('cx', point.x);ball.setAttribute('cy', point.y);// 根据运动方向更新t的值if (forward) {t += speed;if (t >= 1) {forward = false;t = 1;}} else {t -= speed;if (t <= 0) {forward = true;t = 0;}}// 使用requestAnimationFrame递归调用自身来实现动画效果requestAnimationFrame(updateBallPosition);}// 启动动画requestAnimationFrame(updateBallPosition);};</script>
</body></html>
在上述代码中:
HTML部分
- 在SVG元素内,通过
<path>
元素绘制了一条贝塞尔曲线,其d
属性指定了曲线的路径(这里是一个二次贝塞尔曲线的示例路径),设置了线条颜色为蓝色、宽度为2且不填充。同时,通过<circle>
元素绘制了一个小球,初始位置在曲线的起点(cx="50", cy="250"
),半径为10,填充颜色为红色。
JavaScript部分
- 首先在页面加载完成后(
window.onload
)获取SVG元素、贝塞尔曲线路径元素和小球元素的引用,并获取贝塞尔曲线的总长度。 - 定义了小球运动的相关参数,包括当前位置在路径上的比例
t
(初始为0)、运动速度speed
(这里设置为0.01)以及用于表示运动方向的标志forward
(初始为true
,表示正向运动)。 updateBallPosition
函数用于更新小球的位置。在函数内部,首先通过getPointAtLength
方法根据t
的值获取贝塞尔曲线上对应位置的点的坐标,然后将这些坐标更新到小球的cx
(圆心x坐标)和cy
(圆心y坐标)属性上,实现小球位置的动态变化。接着,根据forward
的值来更新t
的值,如果是正向运动(forward
为true
),则t
增加speed
,当t
大于等于1时,改变运动方向为反向(forward
为false
)并将t
设置为1;如果是反向运动(forward
为false
),则t
减少speed
,当t
小于等于0时,改变运动方向为正向(forward
为true
)并将t
设置为0。最后,通过requestAnimationFrame
递归调用updateBallPosition
函数自身来实现流畅的动画效果,不断更新小球的位置使其绕贝塞尔曲线循环往复运动。- 最后通过
requestAnimationFrame
启动动画,调用updateBallPosition
函数开始让小球进行循环往复的运动。
技术名词解释
getTotalLength
- 介绍:这个属性用于获取SVG路径(
<path>
元素)的总长度。它返回一个表示路径长度的数值,单位是用户坐标系统中的单位(通常是像素)。在实现沿着路径的动画或者需要知道路径的总长度来进行比例计算等场景中非常有用。 - 示例应用:
- 假设我们有一个SVG路径表示一条曲线,并且我们想让一个对象以恒定的速度沿着这条路径移动。我们首先需要知道路径的总长度,就可以使用
getTotalLength
来获取。然后,根据动画的时间进度和总长度,计算出对象在路径上的位置。
<svg width="200px" height="200px"><path id="myPath" d="M10 10 C50 50,100 50,150 10" stroke="black" stroke - width="2" fill="none"/> </svg> <script>window.onload = function () {var path = document.getElementById('myPath');var totalLength = path.getTotalLength();console.log("路径总长度:", totalLength);}; </script>
- 假设我们有一个SVG路径表示一条曲线,并且我们想让一个对象以恒定的速度沿着这条路径移动。我们首先需要知道路径的总长度,就可以使用
- 介绍:这个属性用于获取SVG路径(
getPointAtLength
- 介绍:它用于获取路径上指定长度位置的点的坐标(
x
和y
)。参数是一个表示路径长度的数值,它返回一个对象,包含x
和y
属性,表示在该长度位置的点的坐标。这个方法对于沿着路径移动元素、在路径特定位置添加装饰元素等场景很有用。 - 示例应用:
- 比如要让一个小球沿着路径滚动,就可以使用
getPointAtLength
根据时间进度(转化为路径上的长度)来获取小球在路径上的位置,然后更新小球的坐标。
<svg width="200px" height="200px"><path id="myPath" d="M10 10 C50 50,100 50,150 10" stroke="black" stroke - width="2" fill="none"/><circle id="ball" cx="0" cy="0" r="5" fill="red"/> </svg> <script>window.onload = function () {var path = document.getElementById('myPath');var ball = document.getElementById('ball');var length = path.getTotalLength();var position = length * 0.5; // 假设要获取路径一半位置的点var point = path.getPointAtLength(position);ball.setAttribute('cx', point.x);ball.setAttribute('cy', point.y);}; </script>
- 比如要让一个小球沿着路径滚动,就可以使用
- 介绍:它用于获取路径上指定长度位置的点的坐标(
getBoundingClientRect
(SVG元素层面)- 介绍:虽然不是专门针对路径长度的属性,但它对于SVG元素(包括包含路径的SVG元素)很有用。它返回一个DOMRect对象,包含了元素相对于视口的位置(
left
、top
)和尺寸(width
、height
)等信息。在处理SVG元素的布局、碰撞检测(如果将SVG用于游戏等场景)等方面有应用。 - 示例应用:
- 假设我们有一个SVG图形,并且想要知道它在浏览器视口中的位置和大小,以便进行一些布局调整或者与其他元素的交互计算。
<svg id="mySVG" width="200px" height="200px"><path d="M10 10 C50 50,100 50,150 10" stroke="black" stroke - width="2" fill="none"/> </svg> <script>window.onload = function () {var svg = document.getElementById('mySVG');var rect = svg.getBoundingClientRect();console.log("SVG元素位置 - 左:", rect.left);console.log("SVG元素位置 - 上:", rect.top);console.log("SVG元素宽度:", rect.width);console.log("SVG元素高度:", rect.height);}; </script>
- 介绍:虽然不是专门针对路径长度的属性,但它对于SVG元素(包括包含路径的SVG元素)很有用。它返回一个DOMRect对象,包含了元素相对于视口的位置(
getSVGDocument
(在嵌入SVG场景下)- 介绍:当SVG被嵌入到HTML文档中(例如通过
<object>
、<embed>
或<iframe>
等标签),这个方法可以用于获取SVG文档对象。这对于在外部HTML中操作SVG内部的元素(包括路径相关操作)很重要。它允许开发者访问SVG的文档结构,就好像在直接处理SVG文件一样。 - 示例应用:
- 假设我们有一个HTML页面嵌入了一个SVG文件,并且我们想要在HTML的JavaScript代码中获取SVG中的路径长度相关信息。
<object id="svgObject" data="example.svg" type="image/svg+xml"></object> <script>window.onload = function () {var svgObject = document.getElementById('svgObject');var svgDoc = svgObject.getSVGDocument();if (svgDoc) {var path = svgDoc.getElementById('myPath');var totalLength = path.getTotalLength();console.log("嵌入SVG中路径总长度:", totalLength);}}; </script>
- 介绍:当SVG被嵌入到HTML文档中(例如通过
getCTM
(当前变换矩阵)- 介绍:SVG元素(包括路径)可以通过变换矩阵来进行平移、旋转、缩放等操作。
getCTM
返回一个表示当前变换矩阵(Current Transformation Matrix)的对象。这个矩阵包含了元素在坐标系统中的变换信息。在处理路径的变换后的位置、长度等相关信息时会用到。 - 示例应用:
- 假设我们对一个包含路径的SVG元素进行了旋转和缩放操作,并且想要知道路径在变换后的实际位置和长度等信息,就可以使用
getCTM
来辅助计算。
<svg width="200px" height="200px"><g transform="rotate(45) scale(1.5)"><path id="myPath" d="M10 10 C50 50,100 50,150 10" stroke="black" stroke - width="2" fill="none"/></g> </svg> <script>window.onload = function () {var path = document.getElementById('myPath');var ctm = path.getCTM();// 可以根据ctm进一步计算路径在变换后的位置等信息}; </script>
- 假设我们对一个包含路径的SVG元素进行了旋转和缩放操作,并且想要知道路径在变换后的实际位置和长度等信息,就可以使用
- 介绍:SVG元素(包括路径)可以通过变换矩阵来进行平移、旋转、缩放等操作。