— style属性、getStyle()方法
获得某元素的样式值,单独使用没有太大的意义,需要配后合后续两个方法一起使用。
使用举例:style = someElement.style 或style = someElement.getStyle()
— setProperty(Style_Name, Value)方法
设置某元素的某样式项的值。
使用举例:someElement.style.setProperty("fill","red")
或someElement.getStyle().setProperty("fill","red")
— getProperty(Style_Name)方法
获得某元素的某样式项的值。
使用举例:someElement.style.getProperty("fill")
或someElement.getStyle().getProperty("fill")
例程12-13 SVG动态获得和设置样式操作
<svg width="640" height="480">
<script><![CDATA[
function information(evt)
{
obj = evt.target;
style = obj.getStyle();u
alert(style.getPropertyValue("fill"));v
}
function changeStyle(evt)
{
obj = evt.target;
obj.style.setProperty("fill","red");w
obj.style.setProperty("opacity",1);
}
]]></script>
<rect x="100" y="100" width="150" height="100"
style="fill:blue;opacity:0.7" onclick="information(evt)"/>
<rect x="100" y="210" width="150" height="100"
style="fill:blue;opacity:0.7" onclick="changeStyle(evt)"/>
</svg>
例12-13中有两个矩形,单击上方的那个矩形,会弹出一个消息框显示该矩形的填充颜色值“blue”;单击另外一个矩形,矩形的填充颜色和透明度分别变成红色和不透明。在u处获得了产生事件的这个矩形的样式信息,通过v处的“getPropertyValue”方法可以获得样式信息中你想要的某项的值,这里我们获取了“fill”属性的值。我们要对另外一个矩形产生改变样式的效果,就需要使用w处的“setProperty”方法,传入的参数是样式项目名称和要修改的目标值。无论是获得还是设置样式值的方法,都必须跟在“style”属性或“getStyle”方法的后面才有效。
— getBBox()方法
返回一个SVGRect矩形对象,这个矩形表示该SVG元素的外包矩形。
使用举例:someElement.getBBox()
例程12-14 在可视区域内移动一段文字
<svg width="500" height="400" onload="init(evt)">
<script><![CDATA[
var isMove=false,cible="",xt1=0,yt1=0;
function init(evt)
{
svgdoc=evt.target.ownerDocument;
obj=svgdoc.getElementById("mtext");
contour=obj.getBBox();u
trace="M"+contour.x+" "+contour.y+" l"+contour.width+" 0 0 "+contour.height+" -"+contour.width+" 0z";v
obj=svgdoc.getElementById("rectBox");
obj.setAttribute("d",trace);
}
function mouseMove(evt)
{
xm=evt.clientX;ym=evt.clientY;
if ((cible=="rectBox")&&(isMove==true))
{
obj=svgdoc.getElementById("mtext");w
var
xt2=parseInt(obj.getAttribute("x")),yt2=parseInt(obj. getAttribute("y"));
var depx=xt2+xm-xt1,depy=yt2+ym-yt1;
obj.setAttribute("x",depx);
obj.setAttribute("y",depy);
contour=obj.getBBox();
target=svgdoc.getElementById(cible);
trace="M"+contour.x+" "+contour.y+" l"+contour.width+" 0 0 "+contour.height+" -"+contour.width+" 0z";
target.setAttribute("d",trace);
xt1=xm;yt1=ym;
}
}
function cancel(evt) x
{
isMove=false;
}
function moveDown(evt) y
{
cible=evt.getTarget().getAttribute("id");
if (cible=="rectBox")
{
isMove=true;
xt1=parseInt(evt.clientX);
yt1=parseInt(evt.clientY);
}
}
]]></script>
<g onmouseup="cancel(evt)">
<rect x="0" y="0" width="400" height="400" fill="white"/>
<g onmousemove="mouseMove(evt)" onmousedown="moveDown(evt)">
<text id="mtext" x="20" y="50" fill="red" font-size="25">SVG </text>
<path id="rectBox" d="M0 0" opacity=".2"/>
</g>
</g>
</svg>
例程12-14比较复杂,希望大家耐心一些。例子想要实现的效果是拖动“SVG”这段文字,在一个矩形区域内移动,充分体现了SVG的交互性。
图形部分主要是一个“text”元素和“path”元素,“path”元素帮助绘制一个背景矩形区域,使得用户在操作时无需无须非常小心地单击到文字才能触发事件,只要鼠标在这个矩形区域内进行操作即可,可以称之为“热区”。为了让大家能够清楚地看到这个区域又不影响使用,设置透明度为不完全透明。例子中的事件主要有三个:鼠标键按下时(onmousedown)、鼠标键弹起时(onmouseup)和鼠标移动时(onmousemove),注意它们被放在了不同的地方,被激活的范围有所不同。
初始化程序初始化了上述的“热区”,也就是包裹着“SVG”这三个文字的最小矩形,使用“getBBox”方法获得这个外包矩形框,然后使用路径绘制这个封闭区域。
当鼠标键按下时,y处的代码被执行。首先判断“cible”变量是不是“rectBox”,也就是判断事件的来源是不是在“SVG”这几个字的矩形区域内产生的,如果在这个区域外产生,则后续的效果都不会产生,也就无法拖动文字移动了。“isMove”这个变量就是用来控制是否能够移动文字。此外,还记住了当前鼠标的位置。
如果“isMove”变量是“true”的话,当鼠标移动时,w处以下的代码都会被执行。要使文字能够移动,就要改变它们相对位置偏移属性“x”和“y”。一旦文字的位置改变了,它的外包矩形区域也就改变了,我们要使用“getBBox”方法获得这个外包矩形框,并且重绘一遍。所以,最后的效果就是这个外包矩形框和文字一起移动了。
鼠标键弹起时,执行x处的代码,“isMove”变量又被置回“false”,本次操作完成。
— getCTM()方法
返回一个初始变换矩阵。
使用举例:someElement.getBBox()
— currentScale属性、getCurrentScale()方法
获得当前视图的缩放比例。
使用举例:someElement.currentScale
或someElement.getCurrentScale()
— currentTranslate()属性、getCurrentTranslate()方法
获得当前视图的平移距离的SVGPoint对象。
使用举例:someElement.currentTranslate
或someElement.getCurrentTranslate()
例程12-15 SVG动态获得当前坐标系统信息
<svg id="root" width="350" height="350" viewBox="-200 -200 1750 1750" onmousemove="info(evt)">
<script><![CDATA[
function info(evt)
{
xm=evt.clientX;ym=evt.clientY;
svgdoc=evt.target.ownerDocument;
root=svgdoc.getElementById("root");
scale=root.currentScale;
tx=root.currentTranslate.x;
ty=root.currentTranslate.y;
xsvg=-200+(xm-tx)*5/scale;
ysvg=-200+(ym-ty)*5/scale;
svgdoc.getElementById("pos1").firstChild.setData("ClientX clientY: "+xm+" "+ym);
svgdoc.getElementById("pos2").firstChild.setData("ViewBox: "+xsvg+" "+ysvg);
svgdoc.getElementById("pos3").firstChild.setData("current Translate: "+tx+" "+ty);
svgdoc.getElementById("pos4").firstChild.setData("currentScale: "+scale);
}
]]></script>
<rect x="-200" y="-200" width="2000" height="2000"
style="stroke-width: 1;stroke:black;fill:#999999" />
<text id="pos1" x="-180" y="-100" style="font-size:60"></text>
<text id="pos2" x="-180" y="0" style="font-size:60">ViewBox: </text>
<text x="-180" y="100" style="font-size:60">ViewBox: -200 -200 1750 1750</text>
<text x="-180" y="200" style="font-size:60">Centre 700 180</text>
<circle cx="700" cy="180" r="20" fill="red" />
<text id="pos3" x="-180" y="300" style="font-size:60"> CurrentTranslate: </text>
<text id="pos4" x="-180" y="400" style="font-size:60"> CurrentScale : </text>
</svg>
这几个函数很有用,通过它们可以获得当前SVG视图的平移以及变形情况,这样视图内的其它其他元素就有了参照值。
— printNode(Element)方法
将参数Element节点解析为字符串。
使用举例:printNode(node)
— parseXML(string)方法
将参数字符串序列化成一个节点对象。
使用举例:parseXML(string , svgdoc)
例程12-16 XML和DOM对象之间的序列化和逆序列化
<svg width="400" height="400" onload="init(evt)">
<script>
<![CDATA[
function init(evt)
{
svgdoc = evt.target.ownerDocument;
}
function node2string(evt)
{
node = evt.target;
string = printNode(node); u
alert(string);
}
function string2node()
{
string = "<circle cx='20' cy='20' r='10' fill='#FFFFFF'
stroke='#000000' />";
node = parseXML(string, svgdoc); v
svgdoc.rootElement.appendChild(node);
}
]]></script>
<rect x="200" y="200" width="100" height="50" style="stroke-width:1; stroke:black;fill:black" onclick="node2string(evt)"/>
<rect x="100" y="100" width="100" height="50"
style="stroke-width:1; stroke:red;fill:red" onclick="string2node()" />
</svg>
图12--23是单击了黑色矩形后的显示结果:。图12--34是单击了红色矩形后的显示结果,在左上角出现了一个小圆:。
图12--2 3 printNode方法执行结果 图12--3 4 parseXML方法执行结果
这两个方法刚好是相互对应的一组函数,这一组函数用于进行字符串和DOM节点之间的转换。我们可以使用printNode()逆序列化指定节点元素,用于将当前SVG文档中的Node元素生成字符串保存为文本文件或提交给远程服务器。相反地,我们也可以通过parseXML()将一个字符串用指定的文档对象解析为一个节点(Node)对象;在Adobo SVG Viewer环境下可以不指定document对象,系统会默认使用当前SVG文档的Document对象解析字符串,所以在v处的“svgdoc”可以替换成“document”关键字。
例程12-16中,u 处代码就是把这个节点转换成一个字符串,字符串内容就是这个节点的内容,如图12--23所示。
v 处的代码把事先定义后的字符串内容(字符串内容是合法的符合SVG语法的语句)通过解析后成为一个DOM对象的节点,并且添加到DOM对象中,使之能够显示出来。