如何使用 SVG 进行缩放和平移

本主题演示了如何使用可缩放的向量图形 (SVG) 进行缩放和平移,并在结尾处提供了一个可进行缩放和平移的复杂组织结构图示例。假定你掌握了基本的 HTML 和 JavaScript 知识,并能访问可在 HTML5 中呈现内联 SVG 的浏览器(如 Windows Internet Explorer 9)。

简介

在本主题中,我们首先讨论的是如何使用详细的 SVG 测试图在 SVG 中进行缩放和平移。然后,我们将描述如何使用 Microsoft Excel 和 Microsoft Visio 2010 创建复杂的 SVG 组织 (org) 结构图,该图可由支持 SVG 的浏览器显示。

创建 SVG 测试图

SVG 的一个主要功能是可“无限”放大详图。为了突出显示此功能,我们需要创建一个适合进行缩放和平移的足够详细的 SVG 测试图。在用户放大该图的某个特定功能并希望通过滚动浏览该功能的临近区域时,平移就会变得很重要。

适合进行缩放和平移的可接受的 SVG 测试图可能与下图类似。

如何使用 SVG 进行缩放和平移_第1张图片

此图形是使用以下示例创建的:HTML5 内联 SVG 测试图形

注意 对于 Internet Explorer 9,若要查看该示例的标记,请右键单击呈现的页面并单击“查看源”

来自 HTML5 内联 SVG 测试图形示例的以下(不完整)代码段举例说明了如何创建之前的图形。

<!-- Define an SVG graphic which will be reduced in size and reused multiple times. -->

<g id="parentGraphic" style="stroke: blue; fill: blue;">
  <rect x="5%" y="5%" width="90%" height="90%" rx="10" ry="10" 
        style="fill: none; stroke-width: 2px;"/>
  <text x="50%" y="97.2%" style="text-anchor: middle;">
    This text is going to get extremely small.
  </text>
  <text x="95.4%" y="50%" style="writing-mode: tb; text-anchor: middle;">
    The <tspan style="stroke: red;">red</tspan> center dot is to the left.
  </text>
  <text x="3.3%" y="50%" style="writing-mode: tb; text-anchor: middle;">
    The <tspan style="stroke: red; fill: red;">red</tspan> center dot is to the right.
  </text>
</g>


HTML5 内联 SVG 测试图形示例中,这个组合的 SVG 图形 (<g id="parentGraphic" ...>) 减小了尺寸并且多次重复使用以通过多次调用use 元素创建之前显示的测试图形。例如:

<use href="#parentGraphic" … />

use 元素创建了引用元素的副本(以及该元素中包含的所有子元素)。

另请注意,SVG text-anchor: middle 样式可轻松将文本居中显示,而 writing-mode: tb 可按垂直方式显示文本。

与最新的 CSS 转换一样,SVG 始终支持相同的概念,包括转换、缩放和旋转。要围绕某个中心点按给定因子缩放图形,可以使用以下伪代码:

transform="translate( -centerX*(factor-1), -centerY*(factor-1) ) scale(factor)"

在此伪代码中,(centerX, centerY) 表示中心点的 (x, y) 坐标,而 factor 是所需的比例因子。

在此示例中,SVG 视区为 800 x 600 像素,视区的中心位于 (400, 300)。要将 parentGraphic 缩小 10%(即比例因子为 0.9),可以使用(在伪代码中):

transform="translate( -400*(0.9-1), -300*(0.9-1) ) scale(0.9)"

这将简化为下面的非伪代码:

transform="translate(40, 30) scale(0.9)"

然后,可将其直接应用于 use 元素来获得所需效果:

<use href="#parentGraphic" transform="translate(40, 30) scale(0.9)"/>

此技术用于减少和集中其余 10 个版本的 parentGraphic

现在,我们将使用这个测试图形来演示如何采用两种方法在 SVG 中进行缩放和平移:基于浏览器和基于脚本。

基于浏览器的 SVG 缩放和平移

对 SVG 图进行缩放和平移的最简单方法是使用浏览器自带的缩放和滚动功能。在 Internet Explorer 9 中,下表描述了与缩放相关的鼠标和键盘快捷方式。

用户操作 键盘快捷键 鼠标快捷键
放大 Ctrl + 加号 Ctrl + <向前滚动滚轮>
缩小 Ctrl + 减号 Ctrl + <向后滚动滚轮>
返回默认缩放级别 Ctrl + 0 不适用

使用浏览器的滚动条可在缩放图中轻松进行平移。

基于 JavaScript 的 SVG 缩放和平移

由于针对缩放和/或平移的用户界面可能随浏览器的不同而不同(或出于其他原因),因此实现你自己的基于 JavaScript 的缩放和平移功能很有用。下面提供了针对这两种情况的示例。

JavaScript 缩放

该示例使用两个按钮和鼠标滚轮啦放大和缩小测试图像:当前比例 SVG 缩放

尽管通过注释很好地记录了此示例,但仍需注意以下几点:

  • 用于调整测试图大小(或缩放级别)的技术是 svg 元素的 currentScale 特性。
  • mousewheel 事件已与 window 元素挂接(与 svgbody 元素相对),这样一来,无论缩放级别如何,鼠标滚轮在整个网页上都是活动的。
  • 需要 svg 元素的 viewBox 属性以避免与缩放有关的呈现问题(在没有 viewBox 属性的情况下进行尝试即可观察该问题)。

JavaScript 平移

在放大某个特定 SVG 图后,能够移动(平移)图形以查看各种放大功能会很有用。以下示例使用箭头键来平移一个简单的 SVG 图像(蓝色圆圈):SVG 平移

在此示例中,平移(和下一个示例中的缩放)是通过操作 svg 元素的 viewBox 特性的值来实现的。viewBox 属性的值(一个包含四个数字的字符串)在用户空间中指定了一个矩形,该矩形将映射到视区边界(由svg 元素建立)。通过使用有助于教学的非标准词汇,可按如下方式描述 viewBox 语法:

viewBox="ULCx ULCy UUwidth UUheight"

注意 ULCxULCy 分别表示“左上角 x”和“左上角 y”。UUwidthUUheight 分别表示“用户单位宽度”和“用户单位高度”。

通常,会相对于此用户空间/在此用户空间(即用户坐标系统)内绘制 SVG 图形对象。对于利用相对静态图形进行缩放和平移,SVG 图形对象通常决不会在其用户坐标系统内移动;相反,将在 SVG 视区内/相对于 SVG 视区移动用户坐标系统(及其所有“已附带”图形)。因此,从视区的角度来看,已移动图形对象。换言之,通常你可以移动或转换“已附带”图形对象的用户坐标系统,而非图形对象本身。

牢记上述内容,可按如下方式解释 4 个数字(ULCxULCyUUwidthUUheight):

  • ULCxULCy - 移动用户坐标系统(在其中绘制图形对象的区域)的原点,这样点 (ULCx, ULCy) 将出现在定义的 SVG 视区的左上角。也就是说,在视区内以可视方式移动用户坐标系统,这样用户坐标点 (ULCx, ULCy) 将出现在 SVG 视区的左上角。这将停止移动(相对于视区而言)用户坐标系统的原点及其所有“已附带”图形对象。

    在下面的示例中,用户坐标系统等效于隐式视区坐标系统。

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta http-equiv="X-UA-Compatible" content="IE=9"/>  <!-- For intranet rendering only, remove when page is placed in production! -->
      <title>SVG viewBox Attribute Values</title>
    </head>
    
    <body style="padding:0px; margin:0px;">
      <svg currentScale="1" width="300px" height="200px" viewBox="0 0 300 200"> 
        <rect x="0" y="0" width="300" height="200" 
              style="stroke: black; fill: none; stroke-width: 1px;"/>
        <circle cx="50" cy="100" r="25" style="fill: purple;"/>
      </svg>
    </body>
    
    </html>
    
    
    

    可以通过视区上叠加了用户坐标系统的以下屏幕快照了解这一点。

    如何使用 SVG 进行缩放和平移_第2张图片

    在下一个示例中,ULCxULCy 分别为 -50 和 -25。

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta http-equiv="X-UA-Compatible" content="IE=9"/>  <!-- For intranet rendering only, remove when page is placed in production! -->
      <title>SVG viewBox Attribute Values</title>
    </head>
    
    <body style="padding:0px; margin:0px;">
      <svg currentScale="1" width="300px" height="200px" viewBox="-50 -25 300 200"> 
        <rect x="0" y="0" width="300" height="200" 
              style="stroke: black; fill: none; stroke-width: 1px;"/>
        <circle cx="50" cy="100" r="25" style="fill: purple;"/>
      </svg>
    </body>
    
    </html> 
    
    
    

    这将移动用户坐标系统,这样用户坐标点 (-50, -25) 将显示在视区的左上角。

    如何使用 SVG 进行缩放和平移_第3张图片

    此操作的结果是将 SVG 图形向下和向右“平移”。如果 UCLxUCLy 都是正数值,则图形将向上和向左移动(剪切图形的一部分)。

  • UUwidthUUheight - 这两个值可分别确定水平方向和垂直方向上的每个用户单位对应的视区像素数。请考虑以下代码段:

    <svg width="300px" height="200px" viewBox="0 0 300 200">

    在此示例中,水平方向上每 300 个用户单位对应于 300 像素,垂直方向上每 200 个用户单位对应于 200 像素。换句话说,每个用户单位等于 1 像素。但在下面的示例中,水平方向上每 600 个用户单位对应 300 像素(或每个用户单位对应 0.5 像素),垂直方向上每 400 个用户单位对应 200 像素(或每个用户单位对应 0.5 像素)。请注意,此更改会导致所有图形对象的大小减小一半,如下面的示例所示。

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta http-equiv="X-UA-Compatible" content="IE=9"/>  <!-- For intranet rendering only, remove when page is placed in production! -->
      <title>SVG viewBox Attribute Values</title>
    </head>
    
    <body style="padding:0px; margin:0px;">
      <svg currentScale="1" width="300px" height="200px" viewBox="-50 -25 600 400"> 
        <rect x="0" y="0" width="300" height="200" 
              style="stroke: black; fill: none; stroke-width: 1px;"/>
        <circle cx="50" cy="100" r="25" style="fill: purple;"/>
      </svg>
    </body>
    
    </html> 
    
    
    

    此缩放(或调整大小)的效果如下面的屏幕快照所示。

    如何使用 SVG 进行缩放和平移_第4张图片

组织到一起

此示例中使用 viewBox 属性的值(如前所述)来平移和缩放 SVG 测试图:SVG 缩放 & 平移

请记住,与以编程方式修改 svg 元素的 currentScale 特性值相反,此示例通过修改 svg 元素的 viewBox 特性的后两个值(宽度和高度)来实现缩放功能。

创建复杂的 SVG 组织结构图

可将 Excel(或其他应用程序)与 Visio 2010 配合使用来创建复杂而详细的 SVG 组织 (org) 结构图,然后支持 SVG 的浏览器可显示该图。我们会将此过程分为多个组成部分来对其进行描述:

  • 使用 Excel 创建分层组织结构图列表。
  • 使用 Visio 2010 从一个 Excel 列表创建一个 SVG 组织结构图。
  • 在网页中显示独立的 SVG 文件。

使用 Excel 创建组织结构图列表

组织结构图列表的格式很简单。例如,在下面的电子表格段中,虚拟公司的每个员工都列出了其姓名、其上级以及图中要显示的其他有用信息。

名称 报告到 标题 部门 电话
员工姓名 1 VP 行政人员 x5555
员工姓名 2 员工姓名 1 VP 行政人员 x5556
员工姓名 3 员工姓名 1 VP 行政人员 x5557
员工姓名 100 员工姓名 22 单个参与者 咖啡服务 x5654

上表的长度可为所需合理长度,并可包含其他信息(如果需要)。

注意 不需要 Excel 创建组织结构图列表。可使用其他应用程序(包括简单文本文件)定义组织的层次结构。例如,以下链接提供 CSV 版本的 Excel 文件:100 个员工组织结构图列表(CSV 格式)

有关详细信息,请参阅 Visio 2010 帮助文档的“创建组织结构图”主题中的“使用现有数据源自动创建组织结构图”部分。

创建组织结构图列表后,可将其导入 Visio 2010 中,如下一部分中所述。

使用 Visio 2010 创建组织结构图

导入组织结构图列表相对来说比较简单。在 Visio 2010 中,完成以下步骤:

  1. 单击“文件”选项卡。
  2. 依次单击“新建”、“公司”,然后双击“组织结构图向导”
  3. 在该向导的第一页上,选择“已存储在文件或数据库中的信息”
  4. 单击“下一步”,然后遵循该向导的剩余步骤。

注意 如果你希望你的组织结构图位于一个 Visio 2010 页面上,请在使用该向导时选择“指定每页显示的组织结构内容”

有关详细信息,请参阅 Visio 2010 帮助文档的“创建组织结构图”主题中的“使用现有数据源自动创建组织结构图”部分。

完成该向导后,根据需要调整生成的 Visio 2010 组织结构图布局(可能减小字体),然后通过“另存为”对话框以可伸缩向量图形 (*.svg) 格式保存组织结构图。现在,支持的 Web 浏览器中可显示此 SVG 文件,如下个部分中所述。

在网页中显示独立的 SVG 文件。

应用程序(如 Visio 2010 或 InkScape)生成独立的 SVG 文件之后,你可以采用多种方式在支持的浏览器中显示此 SVG 文件。

显示独立的 SVG 文件的一种最简单的方法是,在支持独立 SVG 的浏览器中打开该文件。例如,单击以下链接可打开已用独立 SVG 格式保存的 100 名员工 Visio 2010 组织结构图(如前所述):orgChart.svg

然后,可以按根据需要使用该浏览器自带的缩放和滚动(平移)功能来浏览此 SVG 图。可以在 Internet Explorer 9 中进行缩放操作,如上表所述。只需移动滚动条(如果存在)即可实现平移。

创建独立的 SVG 文件后,可通过多种方法将该文件嵌入现有网页或新网页中。例如,可使用 iframeembedobjectimg 元素以及 CSS background-image 样式。特别要指出的是,object 元素很有用,因为该元素在用户的浏览器不支持 SVG 时可支持轻松回滚功能。在下面的标记中,通过在 HTML 网页中使用object 元素显示独立组织结构图 SVG 文件。

<!DOCTYPE html>
<html>
<head>  
  <title>100 Employee SVG Org Chart</title>
  <meta http-equiv="X-UA-Compatible" content="IE=9"/>  <!-- For intranet rendering only, remove when page is placed in production! -->
</head>

<body>
  <h1>Embedding SVG in a HTML Document</h1>
  <p>Embedding the file <em>orgChart.svg</em> using the <strong>object</strong> element:</p>
  <object data="orgChart.svg" width="800px" height="600px" type="image/svg+xml">
    <img src="orgChart.png" alt="PNG Image of 100 Employee SVG Org Chart" />
  </object>
</body>

</html>


请注意,如果用户的浏览器不支持 SVG,则显示 SVG 组织结构图的 PNG 图像文件。

以下链接扩展了此 HTML <object> 示例,以包含基于 JavaScript 的缩放和平移(使用前面所述的 viewBox 技术):SVG Org Chart with Zoom & Pan

SVG Org Chart with Zoom & Pan 示例使用前面所述的技术。但是,一个唯一差别是脚本必须访问单独文件orgChart.svg 中包含的 svg 元素。下面的代码段演示如何执行此操作。

var theSvgDocument = document.getElementById('objectElement').getSVGDocument();
theSvgElement = theSvgDocument.documentElement;

换句话说,可通过本地 object 元素访问外部 SVG 文档对象。然后,此 SVG 文档对象提供了对外部 svg 元素的访问权。

摘要

SVG 的向量特性决定了它完全适应需要高度详细的信息的图形,如复杂的组织结构图、体系结构图、地图及其他类似媒体。本主题将帮助你使用 SVG 的核心功能之一(即可缩放的向量图形)。

相关主题

如何向网页添加 SVG
SVG
SVG 参考
SVG 规范

你可能感兴趣的:(svg)