Rotation based on rotation point set on an object while in inkscape

938 views
Skip to first unread message

Marc Olivier Chouinard

unread,
Apr 23, 2016, 9:27:24 AM4/23/16
to Snapsvg
Hi,

I'm rotating an object but I want to rotate it on a certain point.

In inkscape where I've created my object, I can define the point of rotation on an object and use the rotate tool to rotate it like I wish.

But if I try to transform('r45') with snap.svg, it will rotate around it center.

I found a way to do it which you can look here : https://teslalog.com/demo_svg_manipulation/

Is there a better way to do it ?

Is it normal that I have to save the original bbox value for this to work correctly ?


A more advance gauge I've made can be seen here : https://teslalog.com/demo_canbus_recorded_route/

Which I also had to SAVE the transform_local of the object when loaded.

Then I had to do obj.transform(saved_transform_local + "r45, (bbox.cx - (bbox.width/2) + "," + bbox.cy);

All this worked, but It just would be so much intuitive if I didn't had to do all this in the first place.

I'm I missing something, or could snap.svg could be changed so I don't have to do this ?

Thanks

Marc

Ian

unread,
Apr 23, 2016, 12:15:51 PM4/23/16
to Snapsvg
I'm not quite sure I'm seeing the problem...

The logic seems to be, you want to rotate around an arbitrary point, so you need to calculate this and store it somewhere. So this is what you are doing. You could store the points, rather than the bounding box, but its much the same principle in logic. I'm not quite sure what step you want to miss out ?

I would possibly redo it something like... http://svg.dabbles.info/testrot/demo/  but really the logic is the same

Snap.plugin( function( Snap, Element, Paper, global ) {
        Element.prototype.storePivot = function() {
                return this.data('px', this.getBBox().x2-(this.getBBox().w/2))
                           .data('py', this.getBBox().y2 );
        };
});

function me(item, val) {
        item.transform( "r" + val + ',' + item.data('px') + ',' + item.data('py') );
}

var l,m,r;
s = Snap("#svg");
g = s.group();

Snap.load("drawing.svg", function (f) {
        g.append(f);
        l = g.select("#lineleft").storePivot();
        m = g.select("#linemiddle").storePivot();
        r = g.select("#lineright").storePivot();
});



Ian

unread,
Apr 23, 2016, 12:24:17 PM4/23/16
to Snapsvg
Or you could break the transform into its own plugin as well, so it would look like this... http://svg.dabbles.info/testrot/demo/index2.html

But its still much the same logic wise.

1: <input type="range" name="points" min="-90" max="90" oninput="l.pivot(this.value);"></br>
2: <input type="range" name="points" min="-90" max="90" oninput="m.pivot(this.value);"></br>
3: <input type="range" name="points" min="-90" max="90" oninput="r.pivot(this.value);"></br>
...


Snap.plugin( function( Snap, Element, Paper, global ) {
        Element.prototype.storePivot = function() {
                return this.data('px', this.getBBox().x2-(this.getBBox().w/2))
                           .data('py', this.getBBox().y2 );
        };

        Element.prototype.pivot = function( angle ) {
                return this.transform( "r" + angle + ',' + this.data('px') + ',' + this.data('py') );

Marc Olivier Chouinard

unread,
Apr 23, 2016, 12:52:16 PM4/23/16
to Snapsvg
You made me realized I might have assumed the inkscape rotation point might be something unique to inkscape and not to the svg standard itself.

So I've compare 2 svg file with the rotation point change and found my issue.

Inkscape save it x,y center using inkscape:transform-center-x/y attribute

So this actually does what I hoped :
        var y = item['bbox'].cy;
        if (item.node.getAttribute('inkscape:transform-center-y'))
        y -= parseFloat(item.node.getAttribute('inkscape:transform-center-y'));

        var x = item['bbox'].cx;
        if (item.node.getAttribute('inkscape:transform-center-x'))
                x -= parseFloat(item.node.getAttribute('inkscape:transform-center-x'));

        item.transform("r" + val +"," + x + "," + y  );

I'll also use your storePivot method you showed which will make thing look much cleaner !

Thanks

Marc Olivier Chouinard

unread,
Apr 23, 2016, 1:48:10 PM4/23/16
to Snapsvg
I've updated the demo at https://teslalog.com/demo_svg_manipulation/ with the inkscape center rotation support and your suggestion of using storePivot.

I also need to save the local_transform in some instance.  For example here is the first svg I made that I wanted to animate :
https://teslalog.com/demo_svg_manipulation/advance/

The speed graph was flip in inkscape, so that is lost if I don't save it before applying the rotation.

Thanks again ! Your sample code really make thing look nice and clean now !



Reply all
Reply to author
Forward
0 new messages