什么是svg?
SVG 意为 可缩放矢量图形 (Scalable Vector Graphics)。
SVG 是一种 用于描述二维图形的 XML 标记语言 ,与位图图像不同,SVG 图像以文本形式存储,并且可以缩放到任意大小而不会失真,因为它们 基于数学描述而不是像素 。
SVG 图形是可伸缩的,无需分辨率依赖,这意味着它们可以在不失真的情况下被放大或缩小。
SVG 广泛应用于网页设计、图标制作、数据可视化和其他图形相关的领域。
特点
- 矢量图形: SVG 使用基于路径的矢量图形,这意味着图形可以无限放大而不失真。
- 可伸缩性: SVG 文件可以在不同的分辨率下保持清晰,适合用于响应式设计。
- 互动性: SVG 可以与 JavaScript 结合,实现动画和交云效果。
- 集成性: SVG 可以直接嵌入 HTML5 中,无需使用外部文件。
- 兼容性: 大多数现代浏览器都支持 SVG。
应用场景
- 网页图标: 由于 SVG 的可伸缩性,它非常适合用来制作网页图标。
- 数据可视化: SVG 常用于图表和图形的创建,如条形图、饼图等。
- 动画: SVG 可以与 CSS 和 JavaScript 结合,创建复杂的动画效果。
- 游戏开发: 在某些情况下,SVG 也被用于创建简单的游戏图形。
- 设计原型: 设计师可以使用 SVG 来创建可交互的设计原型。
基本语法
SVG 文档由一个或多个 SVG 元素组成,它们定义了图形的内容和属性。
<svg
width="200" <!-- 指定SVG画布的宽度 -->
height="200" <!-- 指定SVG画布的高度 -->
xmlns="http://www.w3.org/2000/svg"> <!-- 指定SVG命名空间 -->
<!-- SVG图形内容 -->
</svg>
绘制的基本图形
<rect>:绘制矩形<circle>:绘制圆形<ellipse>:绘制椭圆<line>:绘制直线<polyline>:绘制折线<polygon>:绘制多边形<path>:绘制路径
矩形(Rectangles): 使用 <rect> 元素绘制矩形,可以指定矩形的位置、大小、圆角等属性。
<rect x="50" y="50" width="100" height="50" rx="10" ry="10" fill="blue" />
圆形(Circles) :使用 <circle> 元素绘制圆形,可以指定圆心坐标和半径。
<circle cx="100" cy="100" r="50" fill="red" />
椭圆(Ellipses): 使用 <ellipse> 元素绘制椭圆,可以指定椭圆的中心坐标和长短轴的半径。
<ellipse cx="100" cy="100" rx="80" ry="50" fill="green" />
直线(Lines): 使用 <line> 元素绘制直线,需要指定起点和终点坐标。
<line x1="50" y1="50" x2="150" y2="150" stroke="black" stroke-width="2" />
多边形(Polygons): 使用 <polygon> 元素绘制多边形,需要指定多个顶点的坐标。
<polygon points="100,50 150,150 50,150" fill="orange" />
折线(Polylines): 使用 <polyline> 元素绘制折线,需要指定多个点的坐标。
<polyline points="100,50 150,150 50,150" fill="none" stroke="blue" stroke-width="2" />
路径(Paths): 使用 <path> 元素绘制路径,可以通过指定一系列的路径命令来绘制各种形状。
<path d="M10 10 L90 10 L90 90 Z" fill="none" stroke="black" stroke-width="2" />
渐变和填充:
- 使用
<linearGradient>或<radialGradient>定义渐变。 - 使用
fill和stroke属性指定填充和描边样式。
文本和字体:
- 使用
<text>元素插入文本。 - 使用
font-family、font-size等属性控制文本样式。
动画和交互:
- 使用
CSS或JavaScript创建动画效果。 - 添加事件处理器实现交互功能,如鼠标点击、悬停等。
SVG 元素属性:
<circle
cx="100" <!-- 圆心的x坐标 -->
cy="100" <!-- 圆心的y坐标 -->
r="50" <!-- 圆的半径 -->
fill="red" <!-- 填充颜色 -->
stroke="black" <!-- 描边颜色 -->
stroke-width="2" <!-- 描边宽度 -->
/>
嵌套和分组:
SVG 元素可以嵌套和分组,以便更好地组织和管理图形元素。
<g id="group1"> <!-- 定义一个分组 -->
<!-- 分组内的图形元素 -->
<rect x="10" y="10" width="50" height="50" />
<circle cx="100" cy="100" r="30" />
</g>
<g>元素用于创建一个分组。id属性用于为分组指定一个唯一的标识符。
html中使用svg
SVG 文件可通过以下标签嵌入 HTML 文档:<img>、<object> 或者 <iframe>。
SVG 的代码可以直接嵌入到 HTML 页面中,或您可以直接链接到 SVG 文件。
<!-- src 属性指定 SVG 文件的路径 -->
<img src="example.svg" alt="SVG Image" width="200" height="200">
<!-- data 属性指定 SVG 文件的路径,type 属性指定资源的 MIME 类型 -->
<object data="example.svg" type="image/svg+xml" width="200" height="200">
Your browser does not support SVG
</object>
<!-- src 属性指定 SVG 文件的路径 -->
<iframe src="example.svg" width="200" height="200"></iframe>
使用 CSS 背景图
通过 CSS 的 background-image 属性,可以将 SVG 图像作为背景图嵌入到 HTML 元素中。这种方法适用于需要在 CSS 中控制背景图样式的情况。
.svg-bg {
width: 200px;
height: 200px;
background-image: url('circle1.svg');
background-size: cover;
}
基本图形
<rect>:绘制矩形<circle>:绘制圆形<ellipse>:绘制椭圆<line>:绘制直线<polyline>:绘制折线<polygon>:绘制多边形<path>:绘制路径
path 讲解
SVG 中的 <path> 元素用于创建路径,它是 SVG 中最强大和最灵活的基本形状之一。
使用 <path> 元素可以绘制直线、曲线、弧线等各种复杂的图形,并且可以通过设置路径命令来控制路径的形状和样式。
<path
d="path-data" <!-- 定义路径的路径数据 -->
fill="fill-color" <!-- 路径的填充颜色 -->
stroke="stroke-color" <!-- 路径的描边颜色 -->
stroke-width="width" <!-- 路径的描边宽度 -->
/>
重点就是这个属性 d。
d属性定义了路径的路径数据,即路径命令序列。路径数据由一系列的路径命令组成,每个路径命令以字母开头,后面跟随一组数字参数。常用的路径命令包括:M(移动到)、L(直线到)、H(水平线到)、V(垂直线到)、C(三次贝塞尔曲线)、S(光滑曲线)、Q(二次贝塞尔曲线)、T(光滑二次贝塞尔曲线)、A(圆弧)、Z(闭合路径) 等。
另外 svg 支持 滤镜、模糊、阴影、渐变-线性、渐变-放射 等。
拓展
我们如何实现将DOM节点转化为图片。这里我们参考了包括 html2canvas等在内的库之后发现,原理也是基于svg的实现。
- 利用
SVG的foreignObject元素能嵌入html元素的特性,将要导出的DOM节点嵌入到SVG中; - 通过
img元素渲染svg; - 通过
canvas绘制img,调用导出方法导出为blob或data:url数据; - 通过
a标签下载到本地;
首先来一段简单的DOM结构作为要导出的节点:
<div
id="el"
style="border: 1px solid lightcoral;
padding: 10px;
width: 250px;
height: 250px;
background-color: #fff;">
<h1>foreignObject</h1>
<p>
SVG中的<span style="font-weight: bold; color: lightblue">foreignObject</span>
元素允许包含来自不同的 XML 命名空间的元素。在浏览器的上下文中,很可能是
<span style="background-color: lightseagreen; color: #fff">
XHTML / HTML
</span>。
</p>
</div>
然后我们将这个节点克隆一下,并拼接成SVG字符串:
const el = document.getElementById('el')
// 获取节点大小
const rect = el.getBoundingClientRect()
// 克隆一份
const clone = el.cloneNode(true)
// 添加xhtml命名空间
clone.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')
// 拼接svg字符串
const svgStr = `<svg xmlns="http://www.w3.org/2000/svg" width="${rect.width}" height="${rect.height}">
<foreignObject width="${rect.width}" height="${rect.height}">${clone.outerHTML}</foreignObject>
</svg>`
首先获取了一下要导出节点的大小,然后设置到svg节点上,接下来我们还给克隆的节点添加了命名空间的属性,这个是必要的,否则最后导出将是空白的,最后我们将被导出的DOM节点的html字符串拼接到foreignObject标签中即可。
接下来使用Blob对象将svg字符串转换为blob数据,然后我们通过FileReader对象读取。因为img标签并不能直接渲染blob数据,所以我们还要把blob转换为data:url数据:
const blob = new Blob([svgStr], {
type: 'image/svg+xml'
})
const reader = new FileReader()
reader.onload = evt => {
// evt.target.result
}
reader.readAsDataURL(blob)
const img = new Image()
img.onload = () => {
ctx.drawImage(img, 0, 0)
}
img.src = svgUrl