svgdotjs / svg.js

The lightweight library for manipulating and animating SVG
https://svgjs.dev
Other
11.15k stars 1.08k forks source link

SVG.invent - is there any changes in v3.0.13 #1032

Closed basilgass closed 5 years ago

basilgass commented 5 years ago

I'm trying to use SVG.invent. I followed some examples (from the doc website: rounded), stackoverlfow, ... They are working with v2.7, but not more with v3.0.13

So, either I missed somewhere the information on how to "invent", or there is a bug somewhere.

SVG.Rounded = SVG.invent({
create: 'rect'
, inherit: SVG.Shape
, extend: {
 size: function(width, height) {
  return this.attr({
    width:  width
  , height: height
  , rx:     height / 5
  , ry:     height / 5
  })
}
}
, construct: {
 rounded: function(width, height) {
  return this.put(new SVG.Rounded).size(width, height)
}

}
})
Fuzzyma commented 5 years ago

The way you do this in 3.0 is by cerating a new class:

class Rounded extends Shape {
  constructor (node) {
    super(nodeOrNew('rect', node), node)
  }

  size: function(width, height) {
    return this.attr({
      width:  width
    , height: height
    , rx:     height / 5
    , ry:     height / 5
    })
  }
}

extend(Container, {
  rounded: function(width, height) {
    return this.put(new Rounded).size(width, height)
  }
})
basilgass commented 5 years ago

Thanks ! I had to do some little modifications to make it work properly in my code:

class Rounded extends SVG.Shape {
        constructor (node) {
            super(SVG.nodeOrNew('rect', node), node)
        }

        size(width, height) {
            return this.attr({
                width:  width
                , height: height
                , rx:     height / 5
                , ry:     height / 5
            })
        }
    }

    SVG.extend(SVG.Container, {
        rounded: function(width, height) {
            return this.put(new Rounded).size(width, height)
        }
    });
basilgass commented 5 years ago

I'm continuing in the developement of a new object. Basically, the idea is to create a line passing through two points. The line should be updated when the points are dragged/moved. So I started to create a point in a specific class (as I want to use it for other purpose too).

When I'm creating the point 'manually' (without a class), it's working correctly. But I can't find the correct way to apply the "draggable" method on my custom shape.

class IPoint extends SVG.Shape {
    constructor(node) {
        super(SVG.nodeOrNew("circle", node), node);
        this.fill({color: "yellow", opacity: 0.5})
            .stroke({color: 'black', opacity: '1'})
            .attr({r: 20});
    }
    setPos(x, y){
         return this.attr({cx: x, cy: y});
    }
}
SVG.extend(SVG.Container, {
    iPoint: function (x, y) {
        return this.put(new IPoint).setPos(x, y).draggable();
    }
});

What I want to achieve is shown here: https://v5.scolcours.ch/dev

The yellow button was created using the class above... but unfortunatly, it doesn't move. Can you point me on how to do this ?

EDIT --- After some tests, it seems that adding the handler for dragmove is resolving the problem.

class IPoint extends SVG.Shape {
        constructor(node) {
            super(SVG.nodeOrNew('circle', node), node);

            let c = this.fill({color: "yellow", opacity: 0.5})
                .stroke({color: 'black', opacity: '1'})
                .attr({r: 20})
                .draggable()
                .on('dragmove.namespace', (e) => {
                    const {handler, box} = e.detail;

                    // Ne pas utiliser le déplacement par défaut
                    e.preventDefault();

                    handler.el.setPos(box.cx, box.cy);
                });
        }

        setPos(x, y) {
            return this.attr({cx: x, cy: y});
        }
    }