文档章节

在 SVG 中添加交互性

随智阔
 随智阔
发布于 2014/03/08 16:33
字数 3493
阅读 151
收藏 4
点赞 0
评论 0

原文地址:http://www.ibm.com/developerworks/cn/xml/x-svgint/

SVG 中的交互性可以分为三个领域 -- 链接、事件和脚本。本文将依次讨论这三个领域。

注意:要查看本技巧中的 SVG 文档,需要有一个 SVG 查看程序,可以在 参考资料中找到这种查看程序(还有一个包括所有相关文件的 .zip 文件)。

链接

最基本的交互形式是链接。在 SVG 中,通过一个 <a> 标签提供链接,这与 HTML 链接的方式几乎相同。将 <a> 标签与一个xlink:href 属性结合使用便可以建立一个链接。在 <a>和 </a> 标签之间的所有内容都作为链接的一部分。清单1展示了一个例子,它有三个元素,设置为链接到三个不同的 URL。 单击这里以在浏览器中查看它们。

文本、矩形和多边形元素都有到不同页面的链接,这表明所有 SVG 元素 -- 不管是文本、圆还是不规则的多边形 -- 都可以作为一个链接。注意,如果将鼠标移动到这些元素上面,指针会相应地发生改变,表明这是一个链接。

其功能与 HTML 中的 image map(或者 hotspot)基本上相同。不过,在 HMTL 中这会是一个很麻烦的过程,要用专门的软件在一个图像上手工绘制热点 -- 如果这个图像或者链接改变了,那么更新它们会非常麻烦。在 SVG 中,定义和维护链接则容易得多,这主要是因为链接可以随着 SVG 内容动态移动。

清单1. 链接

<svg>
    <a xlink:href="http://www.w3.org//Graphics//SVG//Overview.htm8">
        <rect x="10" y="10" width="100" height="30" rx="10" ry="10" 
              style="fill:lightgrey"/>
        <text x="30" y="30" font-size="12">Click here</text>
    </a>
    <a xlink:href="http://www.ibm.com//developerworks/">
        <circle cx="100" cy="100" r="50" style="fill:grey"/>
        <text x="80" y="100" font-size="12">Or here</text>
    </a>
    <a xlink:href="http://www.ibm.com/" target="new">
        <polygon 
              points="60 160,165 172,180 60,290 290,272 280,172 285,250 255" 
              style="fill:dimgrey"/>
        <text x="160" y="200" font-size="12">Or even here</text>
    </a>
</svg>

注意在多边形的 xlink 中使用的 target=new 属性。它指示查看程序在单击这个元素时打开一个新的浏览器窗口。

回页首

事件

SVG 支持鼠标单击、鼠标移动和鼠标按下这样的用户鼠标事件。清单2展示了一个例子:

清单2. 使用鼠标的交互性

<svg>
<rect x="10" y="10" width="140" height="140" rx="5" ry="5" 
      style="fill:lightgrey">
   <set attributeName="fill" from="lightgrey" to="red" 
         begin="mouseover" end="mouseout"/>
</rect>
<text x="200" y="75" font-size="30">Move over me and click
   <set attributeName="font-size" from="30" to="35" 
         begin="mouseover" end="mouseout"/>
   <set attributeName="fill" from="black" to="red" 
         begin="mousedown" end="mouseup"/>
</text>
</svg>

单击这里以便观看效果。矩形和文本元素对不同的事件 -- 如移动鼠标和单击 -- 做出反应,产生一种简单的滚动效果。试着将鼠标移动到元素上面以观看这些效果。任何可以应用到元素上的 SVG 属性 -- 如填充颜色、笔划宽度、大小和透明度 -- 都可以以这种方式改变。

文字元素可以对两种事件做出反应 -- mouseovermousedown 。这表明可以对同一个元素指定多个事件。SVG 支持许多不同的事件 -- 有关所有事件类型的完整列表可以参看 参考资料中的 W3C 的 SVG 站点。

如果希望一个元素上的事件可以引发对另一个元素的操作,可以对 SVG 元素指定 id 属性,然后引用它们。清单3展示了一个例子。

清单3: 改变另一个元素的属性

<svg>
    <rect id="changeToRed" x="20" y="20" width="25" height="25" rx="5" 
          ry="5" style="fill:lightgrey"/>
    <text x="50" y="35" font-size="14">Move over for red text</text>
    <rect id="bigText" x="20" y="60" width="25" height="25" rx="5" 
          ry="5" style="fill:lightgrey"/>
    <text x="50" y="75" font-size="14">Move over for big text</text>
    <rect id="bigRedText" x="20" y="100" width="25" height="25" rx="5" 
          ry="5" style="fill:lightgrey"/>
    <text x="50" y="115" font-size="14">Click me for big red text</text>
    <text id="changingText" x="250" y="100" font-size="30" 
                               fill="black">Change me
        <set attributeName="fill" from="black" to="red" 
              begin="changeToRed.mouseover" end="changeToRed.mouseout"/>
        <set attributeName="font-size" from="14" to="50" 
              begin="bigText.mouseover" end="bigText.mouseout"/>
        <set attributeName="font-size" from="14" to="50" 
              begin="bigRedText.click" end="bigRedText.mouseout"/>
        <set attributeName="fill" from="black" to="red" 
              begin="bigRedText.click" end="bigRedText.mouseout"/>
    </text>
</svg>

单击这里可以在浏览器中观看效果。当鼠标移动到不同的矩形上时,文本就会改变。有三个矩形被指定了各自的 id 属性,文字的 set元素通过“ id.eventName ”引用这些属性。触发矩形的事件时,文本的属性就会相应地改变。

还可以用一个动画响应事件。清单4展示了这样的一个例子:

清单4. 开始一个动画

<svg>
    <rect x="20" y="20" width="250" height="250" rx="5" ry="5" 
          style="fill:red">
        <animate attributeName="opacity" from="1" to="0" 
              begin="click + 1s" dur="1s" fill="restore" />
    </rect>
    <circle cx="250" cy="250" r="100" style="fill:blue">
        <animate attributeName="fill" from="blue" to="green" 
              begin="mouseover" dur="2s" fill="restore" />
    </circle>
</svg>

单击这里以便观看效果。单击矩形时,它会淡出,在圆形上面移动鼠标时,它的颜色会改变。注意可以在 begin 属性中使用“ +Xs ”使动画延迟开始。

键按下

虽然 SVG 上的大部分交互是通过鼠标进行的,但是 SVG 也支持键盘输入。这是通过事件处理程序 accessKey 实现的,如清单5所示。

清单5. 捕获键按下

<svg>
    <rect x="20" y="20" width="100" height="100" rx="5" ry="5" 
          style="fill:red">
	<animate attributeName="opacity" from="1" to="0" 
	      begin="accessKey(1)" dur="3s" fill="restore" />
    </rect>
    <rect x="140" y="20" width="100" height="100" rx="5" ry="5" 
          style="fill:red">
        <animateTransform attributeName="transform" type="rotate" 
              from="0" to="90" begin="accessKey(2)" dur="3s"/>
    </rect>
    <rect x="260" y="20" width="100" height="100" rx="5" ry="5" 
          style="fill:red">
        <animateColor attributeName="fill" from="red" to="green" 
              begin="accessKey(3)" dur="3s" />
        <animate attributeName="y" from="20" to="100" 
              begin="accessKey(
)" dur="3s" fill="restore" />
    </rect>
</svg>

单击这里以观看效果。三个矩形设置为响应键盘上的数字键 1、2 和 3。试一试按下每一个键,并观察图像相应的反应。

可以设置一个元素响应任意数量的不同的键。注意第三个矩形设置为监听两个键按下。第三个矩形上的第二个 accessKey 处理程序设置为监听键 ( ) -- 您可能认出它就是回车键(Enter)的标准 HTML 编码。要指定任何特殊字符或者空格字符,必须使用 &#XX 这样的 HTML 编码格式,其中 XX 是 ASCII 字符编码。

回页首

脚本

到目前为止我只讨论了用 SVG 支持的内置功能响应事件的基本方法。虽然可以只使用这些功能完成很多工作,但是要实现更高级的效果就需要使用脚本了。SVG 支持像 VBScript 和 JavaScript 这样的脚本语言,对于这里的例子,我将使用 JavaScript。

要让一个 SVG 对象对脚本中的事件作出响应,要在触发器名上加前缀 on ,这样 click 就变为 onclickmouseover 就变为onmouseover ,等等。清单6展示了一个 SVG 脚本的例子。

清单6. 用 JavaScript 编写 SVG 脚本

<svg>
 
<script type="text/javascript">
<![CDATA[
var redVal=0;
var greenVal=0;
var blueVal=0;
function changeCol(evt)
{
   var targetshape = evt.getTarget();
   redVal = Math.round(Math.random()*255);
   greenVal = Math.round(Math.random()*255);
   blueVal = Math.round(Math.random()*255);
   targetshape.setAttribute("fill",
         "rgb(" + redVal + "," + greenVal + "," + blueVal + ")");
  
}
// ]]>
</script>
    <circle cx="200" cy="200" r="100" fill="blue" 
          onclick="changeCol(evt)" />
</svg>

下面逐步分析 清单6

  1. 编写 SVG 脚本的第一步是通知查看程序不再使用 SVG,而是使用脚本语言。还必须用 type 属性定义使用哪种脚本语言编码。在这里它设置为 text/javascript
  2. <![CDATA[ 是 XML 命令,它告诉查看程序停止解析代码,并读取接下来的块中的代码,这里的代码是字符数据的形式。这可以防止查看程序将括号和其他特殊字符按 SVG 元素处理,并使脚本编写更容易。
  3. 现在就可以开始脚本了。首先,定义三个变量: redValgreenValblueVal 。这些变量分别具有red、green 和 blue 值,它们将在函数中用到。这个函数名为 changeCol ,它带有一个参数 (evt)。 evt 是一个 SVG 保留字,它描述刚发生的事件。这里, evt 方法称为 getTarget(), 这个方法返回对触发该事件的 SVG 对象的一个引用。这个引用被存储在变量targetShape 中。
  4. 用简单的 JavaScript 函数 Math 生成三个值在 0 到 255 之间的随机数。
  5. 最后,对 targetshape 调用 setAttribute 方法。用前一步中生成的三个随机数将该对象的 fill 属性设置为一个 RGB 值(如rgb(150,200,50) )。
  6. 关闭 CDATA 块和脚本后,返回 SVG。画出一个圆,通过 onClick 元素,在单击时让它调用函数 changeCol(evt)。

单击这里以便观看效果。单击这个圆时,每次单击它时填充都会变为一个随机颜色。

当一个函数要应用到多个 SVG 元素时,脚本是最有用的。例如,可以在清单6中添加一个矩形,如下所示:

<rect x="400" cy="400" width="100" height="100" fill="blue" 
          onclick="changeCol(evt)" />

单击时,这个矩形会与前面的圆形一样调用同一个脚本改变其颜色。

要查看这一点,可以看一下 其他例子。如果查看源代码,您会看到三个方法: changeColchangeEdgeresetEdge 。试着将鼠标移动矩形上面并单击。所有矩形都设置为响应 onclickonmouseoveronmouseout 事件,它们为此调用的是同一个脚本函数。还要注意 onload 属性:第一次装载 SVG 文档时要调用这个属性,它对于您的 SVG 初始化很有用。

交互文本

在 SVG 中创建交互文本比您想象中的要复杂一些。在定义文本元素时,显示的文本是文本元素的子元素,而不是像 font-size 这样的属性,因此不能像前面那样简单地调用 setAttribute 来修改其内容。相反,必须创建一个新的文本元素,并用它替换当前的文本元素。清单7展示了一个例子。

清单7. 编写文本变化的脚本

<svg> 
<script type="text/javascript">
<![CDATA[
function changeText(evt)
{
   targetXtext=svgDocument.getElementById("XPos");
   targetYtext=svgDocument.getElementById("YPos");
   var XPos = evt.getClientX();
   var YPos = evt.getClientY();
   var newXPosText = svgDocument.createTextNode("X Position : " + XPos);
   var newYPosText = svgDocument.createTextNode("Y Position : " + YPos);
   targetXtext.replaceChild(newXPosText,targetXtext.getFirstChild());
   targetYtext.replaceChild(newYPosText,targetYtext.getFirstChild());
}
function changeTextNotOver(evt)
{
   targetXtext=svgDocument.getElementById("XPos");
   targetYtext=svgDocument.getElementById("YPos");
   var newXPosText = 
     svgDocument.createTextNode("X Position : Not over Rectangle");
   var newYPosText = 
     svgDocument.createTextNode("Y Position : Not over Rectangle");
   targetXtext.replaceChild(newXPosText,targetXtext.getFirstChild());
   targetYtext.replaceChild(newYPosText,targetYtext.getFirstChild());
}
function recordClick(evt)
{
   targetClickText=svgDocument.getElementById("ClickPos");
   var XPos = evt.getClientX();
   var YPos = evt.getClientY();
   var newClickText = 
     svgDocument.createTextNode("Last Click made at X=" + XPos + " Y=" + YPos);
   targetClickText.replaceChild(newClickText, 
         targetClickText.getFirstChild());
}
// ]]>
</script>
<text id="XPos" x="50" y="50"<X Position :</text>
<text id="YPos" x="50" y="70"<Y Position :</text>
<text id="ClickPos" x="50" y="90"<Last Click made at : </text>
<rect x="50" y="100" width="200" height="200" style="fill:blue" 
      onmousemove="changeText(evt)" onmouseout="changeTextNotOver(evt)" 
      onclick="recordClick(evt)"/>  
</svg>

单击这里以便观看效果。将鼠标移动到矩形上面时,会显示鼠标的 X 和 Y 位置,并且这两个显示的值会随着鼠标的移动而改变,在矩形上单击鼠标会记录下单击的位置。

分析函数 changeText(evt) 可揭示创建交互文本的步骤:

  1. 为所使用的每一个文本元素指定 id ,这样脚本就可以提取它们。
  2. 第一次调用 svgDocument.getElementById() ,其中传递的参数是要改变的文本元素的 ID。它被存储在一个变量中以供以后使用。
  3. 调用 evt 方法 getClientX()getClientY() 以得到指针的 X 和 Y 坐标,并将它们存储在变量 XPosYPos 中。
  4. 调用 svgDocument.createTextNode() 创建一个新文本节点。将更新过的文本字符串传递给这个函数。
  5. 最后,对这个文字元素调用 replaceChild 方法。它带两个参数 -- 替换文本节点和被替换的子元素。对 getFirstChild() 的调用保证更新的文本放置正确。

参照清单7,您应该可以将交互文本加入到自己的 SVG 文档中。

回页首

结束语

可以使用本文中描述的各种交互技术使您的 SVG 文档对用户有更大的用途。设法将这些技术结合在一起以得到您想要的功能。

看一下 这个小例子以了解如何综合使用这些技术制作一个交互菜单。

参考资料

关于作者

Author photo

Brian Venn 在英国太空防御系统(British Aerospace Defence Systems)工作了三年后,于 2000 年 10 月加入 IBM。他毕业于南安普敦大学,获得了天体物理学学士学位,并且通过了 DB2 和软件测试方面的认证。他目前在 Hursley Park 从事集成测试工作。

© 著作权归作者所有

共有 人打赏支持
随智阔
粉丝 20
博文 687
码字总数 705350
作品 0
海淀
程序员
条形图,折线图和散点图

附录: 您可以参阅本文在 developerWorks 全球站点上的 英文原文。 下载本文所用的示例代码。 请参阅 W3C 站点上的 Scalable Vector Graphics (SVG) 规范。 阅读 Brian Venn 撰写的其他 deve...

储明城
2016/03/08
39
0
如何在 SVG 和 Canvas 之间进行选择

本主题一开始将对 SVG 与 Canvas 进行简要比较,接下来会讨论大量的比较代码示例,如光线跟踪和绿屏。 注意 为了查看本主题中包含的很多示例,你必须使用支持 SVG 和 Canvas 元素的浏览器(如...

Lucups
2014/01/03
0
1
用VML实现Web工作流设计器

用SVG和VML开发工作流设计器 工作流是许多系统中必备的一种功能,而工作流设计器就显示对用户很重要。可视化的设计器对于客户来说就更好了,非常直观,有效果的减少用户的烦脑。 在各种应用中...

wanganf
2012/02/24
0
0
svg动画元素【1】:感性认识

背景说明:svg动画确切的说是SVG SMIL 动画,SVG的动画元素是和SMIL开发组合作开发的。SMIL开发组和SVG开发组合作开发了SMIL动画规范,在规范中制定了一个基本的XML动画特征集合。SVG吸收了S...

佣兵0926
2014/08/31
0
0
程序猿必备的10款web前端动画插件二

  1.菜单悬停效果的展示   一些菜单链接悬停效果为您的灵感。由CSS和JavaScript为单个字母动画提供支持。今天,我们希望与您分享一些菜单悬停效果。我们希望这一套启发你,并为你的下一个...

爱前端
2017/12/09
0
0
Web 开发中的矢量绘图处理和应用

矢量绘图一直是 Web 开发中一直比较薄弱的环节。本文首先针对不同浏览器详细阐述不同的矢量绘图解决方案,其中包括 HTML5 Canvas、SVG 以及 VML 等技术;之后针对每种不同的技术介绍其实现和...

IBMdW
2011/09/03
1K
0
Web开发中的矢量绘图(vml,svg)处理和应用

前言 1991 年物理学家 Tim Berners-Lee 首次在因特网上发布了 HTML 的第一版描述规范文档。经过了 20 多年的发展,HTML 语言成为如今编程最为广泛的语言和互联网上采用最广的文档格式。虽然 ...

kevin_pang
2014/02/25
0
0
程序猿必备的10款web前端动画插件一

  1.动画SVG框架幻灯片   在幻灯片之间切换时显示动画SVG帧的实验性幻灯片。不同的形状可以用来创建各种风格。   我们想和大家分享一个实验幻灯片。我们的想法是在从一个幻灯片转换到另...

爱前端
2017/12/08
0
0
gerbilcharts 0.59 发布,SVG图表库

GerbilCharts 是一个基于 SVG + JavaScript 的可交互式的时间序列图表库。 gerbilcharts的最新版本为gerbilcharts 0.59。 功能列表: 模型,帮助操控时间序列数据。 丰富的图表类型 (线、面、...

老枪
2011/03/03
1K
0
基于VML/SVG配电站接线系统的开发

近几年来,随着Internet的迅猛发展,网页技术日新月异,人们都试图设计出精美、有特色的页面。其中,图形技术发挥着至关重要的作用,可升级矢量图像( SVG, Scalable Vector Graphics)和VML (Vect...

wanganf
2012/03/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

istio 路由实例解析

根据链路追踪图如上: 资料:https://istio.io/docs/guides/bookinfo/ 流程解析: 1. 访问地址: http://IP:31380/productpage kubectl get svc --all-namespaces -o wide istio-system isti......

xiaomin0322
10分钟前
2
0
Centos7通过yum安装jdk8

先查看系统是否已有自带的jdk rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 如果没有输出信息,则说明系统没有安装。如果有输出信息,则执行下面的命令卸载 rpm -qa | grep jav...

iplusx
12分钟前
0
0
字体的动画

树不要皮必死无疑,人不要脸天下无敌。如果你此时正在被承受着不公平的待遇,不要伤心不要气馁,吃亏要趁早。 .menu ul li a { position:relative; color: #FFFFFF; text-decoration:...

Js_Mei
12分钟前
0
0
新手学习hadoop发行版本选择介绍

Hadoop对于从事互联网工作的朋友来说已经非常熟悉了,相信在我们身边有很多人正在转行从事hadoop开发的工作,理所当然也会有很多hadoop入门新手。Hadoop开发太过底层,技术难度远比我们想象的...

左手的倒影
13分钟前
0
0
iOS定时器循环引用问题解决

我们通常使用NSTimer或CADisplayLink会使用以下方式 //定义@property (nonatomic, strong)NSTimer *timer;//实现self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:p......

xiaobai1315
13分钟前
0
0
给wordpress程序提速

在上一节中,我们介绍了wordpress CMS主题提速,本节我们接着介绍wordpress主题提速:gravatar用户头像缓存和google字体去除。 gravatar头像受到全世界网络用户的喜爱,设置好gravatar头像后...

hero2019
16分钟前
0
0
DevExpress v18.1最新版帮助文档下载大全

DevExpress v18.1.4帮助文档下载列表大全来啦!包含.NET、VCL、HTML/JS系列所有帮助文档,提供CHM和PDF两个版本。除已停止更新的Silverlight、Windows 8外,其余均为最新版本。 文章底部扫描...

Miss_Hello_World
19分钟前
0
0
Unity Shader中各种空间及变换方法

前几天尝试写一个传送门的shader,发现自己对坐标之间的变换掌握的不够熟练,趁着这阵子想整理shader相关的知识点,先把各种空间及之间转换整理一下。 1 模型空间-世界空间-观察空间-裁剪空间...

爽歪歪ES
25分钟前
0
0

定义和应用 栈(stack)是一种特殊的线性表,其插入(也称入栈或压栈)和删除(也称出栈或弹栈)操作都在表的同一端进行。这一端被称为栈顶(top)另一端称为栈底端(bottom)。 我们生活中其实...

Frost729
26分钟前
0
0
数据分析挖掘学习干货:大数据处理技术的总结与分析

一 数据分析处理需求分类 1 事务型处理 在我们实际生活中,事务型数据处理需求非常常见,例如:淘宝网站交易系统、12306网站火车票交易系统、超市POS系统等都属于事务型数据处理系统。 这类系...

加米谷大数据
31分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部