简体   繁体   中英

Working with SVG polygon elements

I'm trying to work with an SVG polygon and javascript. I create a polygon and set its initial point list like this:

var polygon = document.createElementNS('http://www.w3.org/2000/svg','polygon');
polygon.setAttribute("points", "0,0  100,100 200,200");

now what do I do if I want to modify the 2nd point (100,100)? Right now I'm basically reconstructing the whole string again. But can we address "polygon.points" as an array somehow, or is it really just a plain simple string? This can work ok for very simple polygons, but if my polygon eventually has hundreds of point pairs, I'd hate to reconstruct the entire "points" attribute as a string every time I want to modify a single element.

Thanks

You can access the individual point values using the SVG DOM:

var p = polygon.points.getItem(1);
p.x = 150;
p.y = 300;

(Assuming that your UA implements this interface.) See SVGPolygonElement , SVGAnimatedPoints , SVGPointList and SVGPoint .

I find though that using these SVG DOM interfaces (at least for me in Batik, in which I do most of my SVG stuff) is often not faster than just updating the attribute with string manipulation.

No way around it I'm afraid. You have to reconstruct the string again. But it's not difficult to wrap the whole thing in an object, something like:

function Polygon () {
    var pointList = [];
    this.node = document.createElementNS('http://www.w3.org/2000/svg','polygon');
    function build (arg) {
        var res = [];
        for (var i=0,l=arg.length;i<l;i++) {
            res.push(arg[i].join(','));
        }
        return res.join(' ');
    }
    this.attribute = function (key,val) {
        if (val === undefined) return node.getAttribute(key);
        node.setAttribute(key,val);
    }
    this.getPoint = function (i) {return pointList[i]}
    this.setPoint = function (i,x,y) {
        pointList[i] = [x,y];
        this.attribute('points',build(pointList));
    }
    this.points = function () {
      for (var i=0,l=arguments.length;i<l;i+=2) {
          pointList.push([arguments[i],arguments[i+1]]);
      }
      this.attribute('points',build(pointList));
    }
    // initialize 'points':
    this.points.apply(this,arguments);
}

var polygon = new Polygon(0,0, 100,100, 200,200);
polygon.setPoint(0, 50,10); // set point and automatically re-build points
polygon.points(50,50, 50,100, 200,100); // set everything
polygon.node; // refer to the actual SVG element

* not the best implementation but you get the idea.

You need to use setAttributeNS . You'll probably want to cache that namespace in a variable somewhere so you don't have to keep typing it.

您需要一次设置所有点,性能非常可靠,您可能想要做的是在外部管理数组并在setAttribute调用上合并它

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM