• SVG DOM常用属性和方法介绍


     将以Adobe SVG Viewer提供的属性和方法为准,因为不同解析器对JavaScript以及相关的属性和方法支持的程度不同,有些方法和属性是某个解析器所特有的。SVG支持DOM2标准。

    12.2.1  文档初始化相关

      evt属性

      evt表示事件本身,可以通过evt获取与当前事件相关的信息,用户可以在script中定义响应函数,进行相应的处理。它与普通JavaScript脚本中的event基本相同,只不过在普通JavaScript的脚本中简写成“e”。

      ownerDocument属性

      通过引用该属性获得当前SVG文件的文档对象,也就是得到SVG的DOM结构。

      使用举例:svgdoc = evt.target.ownerDocument

      getOwnerDocument()方法

      通过调用该方法获得当前SVG文件的文档对象,也就是得到SVG的DOM结构。

      使用举例:svgdoc = evt.target.getOwnerDocument()

      target属性

      通过引用该属性获得事件产生于哪个SVG元素,有时可能是该元素的父元素。

      使用举例:object = evt.target

      getTarget()方法

      通过调用该方法获得事件产生于哪个SVG元素,有时可能是该元素的父元素。

      使用举例:object = evt.getTarget()

      例程12-1  获得SVG文档对象

        function init(evt)
    {
    svgDoc = evt.target.ownerDocument; ②
    svgRoot = svgDoc.rootElement;
    alert(svgRoot.nodeName);
    }
    ]]>
        
             style="fill:rgb(255,0,0);stroke-2"/>

      该例展示了如何在SVG文档被载入后,调用初始化程序,以获得SVG的DOM结构,为后续的编程做好准备。

      例程12-1中,①处表示在SVG文档载入时激活的“onload”事件中执行“init”函数;“init”函数先是得到SVG Document对象,然后获得该对象的根元素(也就是“SVG”元素),最后的效果是弹出一个消息框,上面显示“SVG”。

      ②处的代码可以替换为“svgDoc = evt.getTarget().getOwnerDocument;”,得到的效果是一样的。

    12.2.2  DOM对象操作相关

      前面我们已经介绍过,DOM对象是一个树型的结构,并且经过载入后就放在内存中供我们读写。如何对这棵树进行操作,也就成为发挥SVG交互性很关键的一步。下面所示的方法中,有些是文档对象(Document)的方法,有些是文档元素(Element)的方法,需要区别开来。DOM可以分为三大部分:文档基本元素、文档对象和各种类型的从文档基本元素派生出的文档元素。文档对象是文档对象模型的顶级对象,它包含了整个文档的内容。各种类型的文档元素派生自文档基本元素类型,用于描述文档中各种实际存在的元素。其中可以定义一种文档元素,它们可以容纳其他的文档元素,这些元素就是容器元素,实际上文档对象就是最大的容器元素。由于文档对象模型中存在容器元素,因此所有的对象都组成一个树状结构,称为文档对象树或者DOM树,其中根节点就是文档对象。
    {reg}
      getElementById(ID_Name)方法


      通过元素的ID名获得该元素。

      使用举例:object = svgdoc.getElementById("map")

      getElementsByTagName(Tag_Name)方法

      通过元素名获得一个或者一组元素,注意方法名中的“Elements”是复数,说明返回的元素可能有多个,是一个“NodeList”。

      使用举例:object = svgdoc.getElementsByTagName ("rect")

      例程12-2  获得SVG文档中的元素

        function init(evt)
    {
            svgDoc = evt.target.ownerDocument;
            svgRoot = svgDoc.rootElement;
            rect    = svgRoot.getElementById("rect1"); ①
            rects   = svgRoot.getElementsByTagName("rect"); ②
            alert(rect+","+rects);
    }

    ]]>
        
             style="fill:rgb(255,0,0)"/>
        
             style="fill:rgb(255,0,0)"/>
        
             style="fill:rgb(255,0,0)"/>

      打开该文档后,弹出的消息框上显示“[object SVGRectElement],[object NodeList]”。

      例程12-2中,①处使用“rect1”的ID名得到了“svgRoot”下属的一个矩形元素(SVGRectElement)。②是为了获得所有“svgRoot”下属的“”元素,返回的是一个“NodeList”,本例中一共有三个符合条件的元素。

      getAttribute(ID_Name)方法

      根据所提供的ID名来获得元素的属性值。

      使用举例:color = node.getAttribute ("fill")

      setAttribute(Attribute_Name,Value)方法

      设置该元素属性名为“Attribute_Name”的,属性的值为“Value”。

      使用举例:color = node.getAttribute ("fill")

      setAttributeNS(NameSpace, Attribute_Name ,Value)方法

      功能效果同 setAttribute方法,区别就是增加了为属性名加上命名空间(NameSpace)。在ASV3.0中,属性名都是默认SVG的命名空间,所以不需要再特别注明,但是如果你要使用“xlink”中的属性,就要加入相应的命名空间“http://www.w3.org/2000 /xlink/namespace/”。

      使用举例:object = svgdoc.setAttributeNS ("http://www.w3.org/2000/xlink/namespace/", xlink:href, "index.html")

      注意:绝对不要在同一个程序中混合使用DOM1非名称空间API和DOM2名称空间感知的API(例如,createElement和 createElementNS)。如果使用名称空间,请尽量在根元素位置声明所有名称空间,并且不要覆盖名称空间前缀,否则情况会非常混乱。一般来说,只要按照惯例,就不会触发使你陷入麻烦的临界情况。

    例程12-3  设置SVG元素的属性

        function init(evt)
    {
    svgDoc = evt.target.ownerDocument;
    svgRoot = svgDoc.rootElement;
    rect1   = svgRoot.getElementById("rect1");
    rect2   = svgRoot.getElementById("rect2");
    }
    function setSvgAttribute(evt,flag)
    {
    if ( flag == 1)
    rect1.setAttribute("fill", "green"); ①
    else
    {
    rect2.setAttributeNS(null, "fill", "green");  ②
    }
    }
    function getSvgAttribute(evt)
    {
    alert(rect1.getAttribute("fill")+ "," + rect1.getAttribute("height")); ③
    }
    ]]>
        
            onclick="getSvgAttribute(evt)" onmousemove="setSvgAttribute(evt,1) "
             style="fill:rgb(255,0,0)"/>
        
            onclick="setSvgAttribute(evt,2)"
             style="fill:rgb(255,0,0)"/>

      这里例子中我们接触到了SVG中的事件,这跟HTML中的事件很相似,关于SVG的事件我们会在后面的章节中做详细介绍。这里用到了两个事件:一个是鼠标单击事件“onclick”,一个是鼠标移动到“”时触发的“onmousemove”事件,,注意它们的大小写,全部是小写,否则事件无法激活,浏览器会报告脚本错误。

      我们想要实现的效果是,单击ID为“rect1”的矩形时,能得到它的填充颜色值和矩形的高度值,并且鼠标移动到该矩形的时候,矩形的填充颜色从红色变成绿色;另外一个矩形,我们在单击它的时候,它的填充颜色从红色变成绿色。

      例程12-3中,①处设置矩形“rect1”的“fill”属性为“green”;。

      ②通过命名空间来设置属性值。不过命名空间参数的值是“null”,因为ASV3.0已经内置了命名空间,所以你再给这些SVG的属性添加命名空间的话就会出错,所以填入“null”值。

      ③是为了弹出消息框,显示我们需要知道的那两个属性值。

      createElement(Element_Type)方法

      在DOM对象内创建一个新的元素,可以指定创建哪一种类型的元素,并且返回对这个新元素的引用。

      使用举例:newnode = svgdoc.createElement("rect")

      appendChild(Element)方法

      在该元素的最后追加一个孩子节点。

      使用举例:someElement.appendChild(node)

      例程12-4  动态创建SVG的元素

        function alertMsg(evt)
    {
    objet=evt.target;
    large=objet.getAttribute("width");
    alert("Width of the rectangle is:" + evt.target.getAttribute ("width"));
    }
    function init(evt)
    {
    svgdoc=evt.target.ownerDocument;
    node=svgdoc.createElement("rect"); ①
    node.setAttribute("x","50");
    node.setAttribute("y","50");
    node.setAttribute("width","100");
    node.setAttribute("height","50");
    node.setAttribute("style","fill:red");
    node.addEventListener("mousemove",alertMsg,false); ②
    group=svgdoc.getElementById("group");
    group.appendChild(node); ③
    }
    ]]>
        
            Click the rectangle 
        

      在上面这个SVG文档中,没有看到对“rect”元素的定义,但是实际显示的时候还是显示了一个红色的矩形,原因就在于例程12-4中①处,我们使用“createElement”方法动态生成了一个矩形元素,并且逐个设置了它的“x”、“y”、“width”、“height”及“fill”属性,并且在②处为该元素添加了“mousemove”事件及事件相应的函数名。但是这样生成的矩形元素依旧还是“流离失所”,无法显示出来,需要使用appendChild、insertBefore、 replaceChild等方法把生成的节点元素添加到其它其他元素下才能显示。所以,执行③处的语句后,生成的新元素被加入到名为“group”的组中去,从而显示出来。最终的DOM结构为:如图12-1所示。

    ***图1

    图12-1  动态生成SVG元素后的DOM结构

      从图12-1中可以看出,新加入的“rect”元素与之前就存在的“text”元素位置并列。

      replaceChild(newElement, oldElement)方法

      在某元素的子节点中,使用新元素替代旧元素。

      使用举例:someElement.replaceChild(newNode, oldNode)

      例程12-5  replaceChild方法使用举例

        function init(evt)
    {
    svgdoc = evt.target.ownerDocument;
    root = svgdoc.rootElement;
    }
    function change(evt)
    {
    obj = evt.target; ①
    node=svgdoc.createElement("rect");
    node.setAttribute("x",150);
    node.setAttribute("y",150);
    node.setAttribute("width","100");
    node.setAttribute("height","50");
    node.setAttribute("style","fill:blue");
    root.replaceChild(node,obj); ②
    }
    ]]>
         ③

      这个例子想要实现的效果是:单击一个黑色的矩形后,使它移动到新的位置,并且填充颜色变成蓝色。可以使用动画的办法来实现,但现在我们要用编写动态脚本的方法来实现。例程12-5中,③处已经存在一个黑色矩形了,单击后触发事件执行“change”函数。①的“obj”就是产生事件的“rect”元素,也就是此后要被替代掉的那个元素。然后创建一个新的 “rect”元素,设置新的位置属性和填充颜色值。在②处进行元素的替代,③处的矩形元素就被替换成新的矩形元素,旧的矩形元素不复存在,从而也在显示区域内消失。

      removeChild(Element)方法

      删除某元素下的指定元素。

      使用举例:someElement.replaceChild(Node)

      insertBefore(newElement,refElement)方法

      newElement是一个包含新子元素地址的对象,refElement是参照元素的地址,新子元素被插到参照元素之前。如果refElement参数没有包含在内,或者refElement不是此集合的成员,新的子元素会被插到该元素子元素列表的末尾。

      使用举例:objDocumentElement =someElement.insertBefore(newNode, refNode)

      cloneNode(true/false)方法

      复制一个新的元素,并且返回对这个元素的引用。

      使用举例:someElement.cloneNode(true)

      例程12-6  删除、插入、复制一个新元素

        function init(evt)
    {
    svgdoc = evt.target.ownerDocument;
    root = svgdoc.rootElement;
    }
    function remove(evt) ①
    {
    obj = evt.target;
    root.removeChild(obj);
    }
    function insert(evt) ②
    {
    obj = evt.target;
    node=svgdoc.createElement("rect");
    node.setAttribute("x",150);
    node.setAttribute("y",150);
    node.setAttribute("width","100");
    node.setAttribute("height","50");
    node.setAttribute("style","fill:blue");
    root.insertBefore(node,obj);
    }
    function clone(evt) ③
    {
    obj = evt.target;
    var newNode = obj.cloneNode(true);
    newNode.setAttribute("y", 300);
    newNode.setAttribute("style", "fill:blue");
    root.appendChild(newNode);
    }
    ]]>
        
        
        

      该例中有三个矩形元素,分别进行删除、插入和复制操作。例程12-6中,函数①进行删除元素的操作,直接调用“removeChild”方法,要删除的是在root 元素下的“rect”元素,执行后,“rect”元素被删除,矩形也就消失了;函数②依旧是先在内存中生成一个新的“rect”元素,然后使用 “insertBefore”方法把它插入到产生事件的那个“rect”元素的前面,两者是并列的位置;函数③先是“克隆”了一个与产生事件的 “rect”元素一模一样的元素,并且返回给局部变量“newNode”,我们再对这个局部变量设置了属性“y”和填充颜色,然后把这个元素追加到 “root”元素内的最后的位置,使它显示出来。

      firstChild属性、getFirstChlid()方法

      获得某个元素的第一个子元素。

      使用举例:node = someElement.firstChild

      或node = someElement.getFirstChild()

      childNodes属性、getChildNodes()方法


      获得某个元素下面所有的子元素。

      使用举例:nodeList = someElement.childNodes

      或nodeList = someElement.getChildNodes()

      item(n)方法

      当获得了一个元素集合的时候,需要使用该方法进行引用。

      使用举例:node = someElement.childNodes.items(1)

      NodeType属性


      节点类型,是一个枚举量。

      使用举例:i = someElement.NodeType

      详见下面的列表12-1:

      表12-1  节点类型

      返回的整数 节点类型常数 
     1  ELEMENT_NODE
     2  ATTRIBUTE_NODE
     3  TEXT_NODE
     4  CDATA_SECTION_NODE
     5  ENTITY_REFERENCE_NODE
     6  ENTITY_NODE
     7  PROCESSING_INSTRUCTION_NODE
     8  COMMENT_NODE
     9  DOCUMENT_NODE
     10  DOCUMENT_TYPE_NODE
     11  DOCUMENT_FRAGMENT_NODE
     12  NOTATION_NODE

      NodeName属性

      节点名。

      使用举例:name = someElement.NodeName

      详见表12-2。

      表12-2  节点名称

     返回的字符串  说    明
     #comment  这是一个注释节点
     #document  这是一个文档节点
     Element.tagName  元素的标记名,同时也说明这是一个元素
     Attri.name  属性的名字,同时也说明这是一个元素
     #text  这是一个文本节点

      例程12-7  SVG节点操作

        function init(evt)
    {
    svgdoc = evt.target.ownerDocument;
    root = svgdoc.rootElement;
    alert("First node of root:" + root.firstChild.nodeName); ①
    alert("Seconde child node of root:"+root.getChildNodes().item(1). nodeName); ②
    var obj = svgdoc.getElementById("words");
    alert("Third child node of text element:"+obj.childNodes.item(0). nodeName); ③
    }
    ]]>
        
            
                 style="fill:rgb(255,255,255);stroke:rgb(0,0,0);stroke-2"/>
            
    W
                 orld!
                        
        

      这个例子帮助大家更加深刻地理解SVG的DOM树型结构。

      例程12-7中,①是为了取到“svg”元素下的第一个子元素,也就是“script”元素,所以执行后消息框显示“First node of root:script”;。

      ②是使用“getChildNodes”方法取到“svg”下所有子元素,然后再引用第2个元素(索引值同数组相同,从0开始),执行后消息框显示 “First node of root:g”,也可以使用“root.firstChild. nextSibling.nodeName”语句获得同样的效果,这里的“nextSibling”属性指的是紧挨着某个元素的下一个元素;。

      ③是取得“text”元素下的所有子元素,然后取得这些子元素的第一个元素也就是“tspan”元素,执行后显示“Third child node of text element:tspan”。在使用这些取节点元素的方法或者属性时,一定要小心地数好元素的排列顺序,稍有不慎就会引起错误,所以应该尽可能减少引用层次。

      attributes

      获得某元素的属性集合。

      使用举例:attributes = someElement.attributes

      length属性、getLength()方法

      获得集合元素所含有元素的个数,如attributes、childNodes属性有此属性或方法。

      使用举例:len = attributes.length

      或len = attributes.getLength()

      例程12-8  SVG遍历元素值操作

        function information(evt)
    {
    obj=evt.target;
    att=obj.attributes; ①
    str="Attributs: Number: "+att.length;
    for (i=0; i
    {
    str = str+" "+att.item(i).name+" : "+att.item(i).value;
    }
    alert(str);
    }
    ]]>
        
             style="fill:rgb(0,0,255);opacity:0.7" onclick="information(evt)"/>

      这个例子很好理解,就是遍历矩形元素的所有属性值,在①处,通过attributes获得一个属性值的集合,然后同“childNodes”属性类似,可以使用“item()”方法进行引用,从而获得相应的属性值,如图12-2所示。

      图12-1  2  遍历属性值的显示结果

    ***2

    图2

      12.2.3  事件对象evt相关

      clientX属性、getClientX()方法

      鼠标指针相对于浏览器窗口的客户区的X坐标。

      使用举例:cx = evt.clientX 或 cx = evt.getClientX()

      clientY属性、getClientY()方法

      鼠标指针相对于浏览器窗口的客户区的Y坐标。

      使用举例:cx = evt.clientY 或 cx = evt.getClientY()

      注意:这两个坐标并没有计算文档的滚动高度或者宽度,如果事件发生在窗口的最上边,不管这个文档已经向下滚动了多远,clientX或clientY都是0

      screenX属性、getScreenX()方法


      鼠标指针相对于用户显示器左上角的X坐标。

      使用举例:sx = evt.screenX 或 sx = evt.getScreenX()

      screenY属性、getScreenY()方法

      鼠标指针相对于用户显示器左上角的Y坐标。

      使用举例:sx = evt.screenY 或 sx = evt.getScreenY()

      例程12-9  SVG动态获得和设置样式操作

    function mousePos(evt)
    {
    cx=evt.clientX;cy=evt.clientY;
    sx=evt.getScreenX();sy=evt.getScreenY();
    root=evt.target.ownerDocument;
    root.getElementById("pos1").firstChild.setData("Client: "+cx+" "+cy);
    root.getElementById("pos2").firstChild.setData("Screen: "+sx+" "+sy)
    }
    ]]>

    style="stroke-1; stroke:black;fill:white"/>


      这个例子不复杂,就是获得鼠标当前的客户区坐标和屏幕坐标,这两个坐标其实有着“相对坐标”和“绝对坐标”的味道。但是很奇怪的是,在这个例子中,不论鼠标在什么地方,浏览器窗口在什么地方,两个坐标值总是相等的。

      getCharCode()方法

      获得键盘输入的字符的ASCII码。

      使用举例:key = evt.getCharCode()

      例程12-10  SVG动态获得键盘输入字符

                var phrase="";
            function type(evt)
            {
                svgdoc=evt.target.ownerDocument;
                key=evt.getCharCode(); ①
                if (key==8)
                {
                    if (phrase!="")
                    {
                        phrase=phrase.substring(0,phrase.length-1);
                    }
                }
                else
                {
                    letter=String.fromCharCode(key); ②
                    phrase=phrase+letter;
                }
                obj = svgdoc.getElementById("enter");
                child = obj.firstChild.setData(phrase);
            }
        ]]>
        
            
                 style="fill:rgb(255,255,255)"/>
             Display here
        

      例程12-10很有趣,用来实时地显示用户在键盘上输入的字符。首先使用①处的“getCharCode”方法获得字符的ASCII码,如果是控制键(如Ctrl、Alt、方向键等),则该方法自动过滤掉这些字符。②处的“String.fromCharCode”方法可以把获得的ASCII码转换成相应的字符。


    12.2.4  字符串及文本相关

      createTextNode(TextContent)方法

      动态生成文本节点的文本内容。

      使用举例:text = svgdoc.createTextNode("SVG")

      例程12-11  SVG动态生成节点

            function creatTextNode(evt)
        {
            svgtarget = evt.getTarget();
            svgdoc = svgtarget.ownerDocument;
            node   = svgdoc.createElement("text"); ①
            node.setAttribute("x","50");
            node.setAttribute("y","50");
            node.setAttribute("style","text-anchor:middle;font-size:25; font-family:Arial;fill:red");
            text = svgdoc.createTextNode("SVG"); ②
            node.appendChild(text);
            ou = evt.getTarget();
            svgtarget.appendChild(node);
        }
        ]]>

      例程12-11向我们展示了如何动态地生成一个文本节点,并添加这个节点文本内容。首先需要生成一个“text”元素,①处开始的代码就做了这样一件事情,相信大家已经很熟悉这种动态生成元素的方法了,这里不再赘述。②处的代码调用了“createTextNode”方法,参数就是“text”元素的文本内容,也就是要显示出来的内容。然后使用 “appendChild”方法添加到新创建的“text”元素中去。最后再把整个新创建好的元素加入到根元素中。例子中没有任何实现定义好的 “text”元素,完全通过脚本程序动态生成。

      getNumberOfChars()方法

      获得元素所包含的文本字符的个数(包括空格)。

      使用举例:number = someElement.getNumberOfChars()

      getComputedTextLength()方法


      获得元素所包含的文本字符的显示长度。

      使用举例:len = someElement.getComputedTextLength()

      selectSubString(i,j) 方法

      高亮显示元素所包含的文本字符串中第i个字符(不包括i)后的j个字符。

      使用举例:letter = someElement.selectSubString (2,3)

      例程12-12  元素文本字符相关方法

        function detail(evt)
    {
    textdoc=evt.target.ownerDocument;
    textNode=textdoc.getElementById("mtext");
    number = textNode.getNumberOfChars(); ①
    len = textNode.getComputedTextLength(); ②
    textNode.selectSubString(2,3); ③
    alert("Total:" + number + " "+"Length:" + len);
    }
    ]]>
        
             style="text-anchor:middle;font-size:24;font-family:Arial;fill:rgb(255,0,0)"> Welcome to SVG world!

      上述三个方法是针对“text”元素的,只有“text”元素才能使用。

      例程12-12中,①处代码计算了该文本元素所含的文本字符的数字,此例是计算“Welcome to SVG world!”这个字符串的字符个数,一共有21个;

      ②处代码计算字符串的显示长度,单位是像素;

      ③处代码执行后,“lco”这几个字母呈现蓝色背景高亮显示,即第2个字母“l”后3个字母高亮显示。


    12.2.5  样式相关

      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动态获得和设置样式操作

        function information(evt)
    {
    obj  =  evt.target;
    style = obj.getStyle(); ①
    alert(style.getPropertyValue("fill")); ②
    }
    function changeStyle(evt)
    {
    obj  =  evt.target;
    obj.style.setProperty("fill","red"); ③
    obj.style.setProperty("opacity",1);
    }
    ]]>
        
             style="fill:rgb(0,0,255);opacity:0.7" onclick="information(evt)"/>
        
             style="fill:rgb(0,0,255);opacity:0.7" onclick="changeStyle(evt)"/>

      例12-13中有两个矩形,单击上方的那个矩形,会弹出一个消息框显示该矩形的填充颜色值“blue”;单击另外一个矩形,矩形的填充颜色和透明度分别变成红色和不透明。在①处获得了产生事件的这个矩形的样式信息,通过②处的“getPropertyValue”方法可以获得样式信息中你想要的某项的值,这里我们获取了“fill”属性的值。我们要对另外一个矩形产生改变样式的效果,就需要使用③处的“setProperty”方法,传入的参数是样式项目名称和要修改的目标值。无论是获得还是设置样式值的方法,都必须跟在“style”属性或“getStyle”方法的后面才有效。


    12.2.6  图形变换相关

      getBBox()方法

      返回一个SVGRect矩形对象,这个矩形表示该SVG元素的外包矩形。

      使用举例:someElement.getBBox()

      例程12-14  在可视区域内移动一段文字

            var isMove=false,cible="",xt1=0,yt1=0;
        function init(evt)
        {
            svgdoc=evt.target.ownerDocument;
            obj=svgdoc.getElementById("mtext");
            contour=obj.getBBox(); ①
            trace="M"+contour.x+" "+contour.y+" l"+contour.width+" 0 0 "+contour.height+" -"+contour.width+" 0z"; ②
            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"); ③
                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) ④
        {
            isMove=false;
        }
        function moveDown(evt) ⑤
        {
            cible=evt.getTarget().getAttribute("id");
            if (cible=="rectBox")
        {
            isMove=true;
            xt1=parseInt(evt.clientX);
            yt1=parseInt(evt.clientY);
        }
    }
    ]]>
        
            
                 style="fill:rgb(255,255,255)"/>
            
                SVG 
                
            
        

      例程12-14比较复杂,希望大家耐心一些。例子想要实现的效果是拖动“SVG”这段文字,在一个矩形区域内移动,充分体现了SVG的交互性。

      图形部分主要是一个“text”元素和“path”元素,“path”元素帮助绘制一个背景矩形区域,使得用户在操作时无需无须非常小心地单击到文字才能触发事件,只要鼠标在这个矩形区域内进行操作即可,可以称之为“热区”。为了让大家能够清楚地看到这个区域又不影响使用,设置透明度为不完全透明。例子中的事件主要有三个:鼠标键按下时(onmousedown)、鼠标键弹起时(onmouseup)和鼠标移动时(onmousemove),注意它们被放在了不同的地方,被激活的范围有所不同。

      初始化程序初始化了上述的“热区”,也就是包裹着“SVG”这三个文字的最小矩形,使用“getBBox”方法获得这个外包矩形框,然后使用路径绘制这个封闭区域。

      当鼠标键按下时,⑤处的代码被执行。首先判断“cible”变量是不是“rectBox”,也就是判断事件的来源是不是在“SVG”这几个字的矩形区域内产生的,如果在这个区域外产生,则后续的效果都不会产生,也就无法拖动文字移动了。“isMove”这个变量就是用来控制是否能够移动文字。此外,还记住了当前鼠标的位置。

      如果 “isMove”变量是“true”的话,当鼠标移动时,③处以下的代码都会被执行。要使文字能够移动,就要改变它们相对位置偏移属性“x”和“y”。一旦文字的位置改变了,它的外包矩形区域也就改变了,我们要使用“getBBox”方法获得这个外包矩形框,并且重绘一遍。所以,最后的效果就是这个外包矩形框和文字一起移动了。

      鼠标键弹起时,执行④处的代码,“isMove”变量又被置回“false”,本次操作完成。

      getCTM()方法

      返回一个初始变换矩阵。

      使用举例:someElement.getBBox()

      currentScale属性、getCurrentScale()方法

      获得当前视图的缩放比例。

      使用举例:someElement.currentScale

      或someElement.getCurrentScale()

      currentTranslate()属性、getCurrentTranslate()方法

      获得当前视图的平移距离的SVGPoint对象。

      使用举例:someElement.currentTranslate

      或someElement.getCurrentTranslate()

      例程12-15  SVG动态获得当前坐标系统信息

            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);
        }
        ]]>

    style="stroke- 1;stroke:black;fill:#999999" />

    ViewBox: 
    ViewBox: -200 -200 1750 1750
    Centre 700 180

    CurrentTranslate: 
    CurrentScale : 

      这几个函数很有用,通过它们可以获得当前SVG视图的平移以及变形情况,这样视图内的其它其他元素就有了参照值。

    12.2.7  XML序列化相关

      printNode(Element)方法

      将参数Element节点解析为字符串。

      使用举例:printNode(node)

      parseXML(string)方法

      将参数字符串序列化成一个节点对象。

      使用举例:parseXML(string , svgdoc)

      例程12-16  XML和DOM对象之间的序列化和逆序列化

        function init(evt)
    {
    svgdoc = evt.target.ownerDocument;
    }
    function node2string(evt)
    {
    node = evt.target;
    string = printNode(node); ①
    alert(string);
    }
    function string2node()
    {
    string = "
                  stroke='#000000' />";
    node = parseXML(string, svgdoc);  ②
    svgdoc.rootElement.appendChild(node);
    }
    ]]>
        
             style="stroke-1;stroke:rgb(0,0,0);fill:rgb(0,0,0)"
            onclick="node2string(evt)"/>
        
             style="stroke-1;stroke:rgb(255,0,0);fill:rgb(255,0,0)"
            onclick="string2node()"/>

    图12--23是单击了黑色矩形后的显示结果。图12-4是单击了红色矩形后的显示结果,在左上角出现了一个小圆。


    ***    

    图12-3  printNode方法执行结果

    ***

    图12-4  parseXML方法执行结果

      这两个方法刚好是相互对应的一组函数,这一组函数用于进行字符串和DOM节点之间的转换。我们可以使用printNode()逆序列化指定节点元素,用于将当前SVG文档中的Node元素生成字符串保存为文本文件或提交给远程服务器。相反地,我们也可以通过parseXML()将一个字符串用指定的文档对象解析为一个节点(Node)对象;在Adobo SVG Viewer环境下可以不指定document对象,系统会默认使用当前SVG文档的Document对象解析字符串,所以在②处的“svgdoc”可以替换成“document”关键字。

      例程12-16中,①处代码就是把这个节点转换成一个字符串,字符串内容就是这个节点的内容,如图12--23所示。

      ②处的代码把事先定义后的字符串内容(字符串内容是合法的符合SVG语法的语句)通过解析后成为一个DOM对象的节点,并且添加到DOM对象中,使之能够显示出来

  • 相关阅读:
    原笔迹手写实现平滑和笔锋效果之:笔迹的平滑(二)
    区块链入门(4)Truffle创建项目,编译,及项目部署
    github的基本使用
    ES6新特性之傻瓜式说明
    webpack之傻瓜式教程及前端自动化入门
    查找树莓派ip地址的常用方法
    树莓派的无屏幕安装的教程
    采用QHD分辨率使用kinect2_calibration,完成QHD图像校正
    编译ORBSLAM2 build_ros.sh,实现kinect2在ROS环境下运行ORBSLAM2
    重写kinect2_viewer,编译高博kinect2在orbslam2上跑的程序(解决cmakefile中库依赖和头文件的问题)
  • 原文地址:https://www.cnblogs.com/dh-hui/p/3870250.html
Copyright © 2020-2023  润新知