SVG 学习之 g,defs,symbol 元素详解

前言

在 SVG 实际应用中,可能需要多次使用一个相同的图形。遇到这种情况每次都重新绘制一个全新的图形,不是最好的解决方法

好在 SVG 可以通过 <g><defs><symbol> 等标签定义可重复使用的图形,然后通过 <use> 标签去引用

<g>

g 是 group(分组)的缩写,该元素通常用来对相关图形元素进行分组,以便统一操作,比如旋转,缩放或者添加相关样式等

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>svg test</title>
<style>
svg {
  border:1px solid red;
}
</style>
</head>
<body>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <g id="group" transform="rotate(20)" fill="red">
      <rect x="60" y="-20" width="80" height="80"/>
      <rect x="180" y="-20" width="80" height="80"/>
    </g>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <use id="one" xlink:href="#group"/>
  </svg>
</body>
</html>

上面代码对 <g> 进行旋转操作,注意是对分组的整体旋转,而不是分组内元素单独旋转(下图是浏览器渲染结果)

从上面的渲染结果可以看出 <g> 元素定义后会显示在浏览器中,因此渲染结果有两组 SVG 图像

<defs>

<g> 分组定义的内容直接会显示,而 <defs> 却不会

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>svg test</title>
<style>
svg {
  border:1px solid red;
}
</style>
</head>
<body>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
      <rect id="defs" x="100" y="0" width="100" height="100"/>
    </defs>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <use id="ant" transform="rotate(10 0 0)" fill="red" xlink:href="#defs"/>
  </svg>
</body>
</html>

渲染结果如下:

<g> 一个明显的区别是,<use> 引用的是内部元素的 id,另外 <defs> 定义的内容不会直接显示,所以渲染结果中有一组 SVG 中的图像不可见

<symbol>

<symbol> 兼具 <g> 的分组功能和 <defs> 初始不可见的特性

此外 <symbol> 能够创建自己的视窗,所以能够应用 viewBox 和 preserveAspectRatio 属性

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>svg test</title>
<style>
svg {
  border:1px solid red;
}
</style>
</head>
<body>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <symbol id="symbol1">
      <rect x="50" width="100" height="100"/>
    </symbol>
    <symbol id="symbol2" viewBox="0 0 250 250">
      <rect x="180" y="0" width="100" height="100"/>
    </symbol>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <use id="ant" transform="rotate(10 0 0)" fill="red" xlink:href="#symbol1"/>
    <use id="ant" transform="rotate(10 0 0)" fill="red" xlink:href="#symbol2"/>
  </svg>
</body>
</html>

渲染结果如下:

由于 <symbol> 初始不可见,所以第一组定义的两个 <symbol> 不会显示

另外,注意一下两个方块的区别,由于定义的第二个 <symbol> 修改了 viewBox 属性,所以第二个方块看起来小很多

除特殊说明外本人博客均属原创,转载请注明出处:http://blog.johnhan.cn/blog_1082.html
京ICP备19044523号-1