0

I'm trying to scale and then rotate a triangle and then translate it to a given point in Snap SVG.
I want to rotate the triangle around the top of it not the center, so i can build something like a pie.
So I thought I scale first, then rotate and later translate.

var t = new Snap.Matrix();
t.scale(0.5); 
t.rotate(45, bbox.cx, (bbox.cy-(bbox.h/2)));

But the scale and rotation somehow are allways a bit off.
I reused a jsfiddle I found and updated it, so you can see what I try:
http://jsfiddle.net/AGq9X/477/
Somehow the bbox.cx and bbox.cy are not in the center of the triangle.
On my local setup they are.
The strange thing is, just rotation without scaleing works fine, but scaling and then roation always seems to be a bit off on the y axis, the triangle doesn't stays at the rotation point.
Any ideas how i can fix that?

EDIT:
Ok I found the Solution,thanks to lan, you were right, the center of scaleing is important, and
I thought it was useing the center of the object, but it was the upper left corner. I adjusted it
and now it works greate:

var bbox = obj.getBBox(); //get coords etc. of triangle object
var t = new Snap.Matrix();
var offset = (bbox.cy+(bbox.h)) - centerY; //translate Y to center,  
//depends on scaleing factor (0.5 = bbox.h, 0.25 = bbox.h*2)
t.scale(0.5, 0.5, bbox.cx, (bbox.cy+(bbox.h/2))); //scale object
t.translate(0,-offset); //translate to center
t.rotate(45, bbox.cx, (bbox.cy+(bbox.h/2))); //rotate object
obj.transform(t); //apply transformation to object  

EDIT2:
I wanted to know how to save transformation, so you don't need to apply them every time you use a new transformation. Ian recommended to use element.transform() like so to get the old transformations:

element.transform( element.transform() + 's2,2' )
Chill3er
  • 41
  • 1
  • 1
  • 5
  • I'm not clear what effect you are after. I suspect there is something amiss with your scaling center and also maybe you are taking the center of the triangle and then scaling it. Wouldn't you want the center of a triangle after it's been scaled (if it's not scaled from it's center, as in this case). You may also want to play with scaling after the rotation. – Ian Apr 24 '17 at 06:47
  • I want to scale the triangle and then imagen that you put an pin in one – Chill3er Apr 24 '17 at 21:19
  • *sorry hitted enter on above comment. Imagen you put a pin through one corner of the triangel, then scale it and than rotate it, so the one "fixed" corner should stay where it is. But it somehow doesnt stay "fixed" and changes position. I found out that scaleing comes before rotation: [Snap Matrix](http://svg.dabbles.info/snaptut-matrix) I just dont know what i need to change so i can keep the rotation/scaleing corner "fixed". – Chill3er Apr 24 '17 at 21:27
  • Don't you want a space starting the string after the previous transforms to separate those from the s2,2 ? – OG Sean Nov 17 '20 at 22:11

1 Answers1

0

This is slightly more complicated than one would expect, but you would be animating a matrix, which does some odd things sometimes.

Personally I would use Snaps alternate animate method Snap.animate() and not using a matrix. Set the scale first and then build your animation string.

Something like..

var triangle2 = p.select("#myShape2").transform('s0.5');

...

Snap.animate(0,90,function( val ) {
  triangle2.transform('r'+ val + ',' + bbox.cx+','+(bbox.cy-(bbox.h/2))+'s0.5')
}, 2000)

jsfiddle

Ian
  • 13,724
  • 4
  • 52
  • 75
  • I also thought about using just `Snap.Animate()`, but I find Matrix is better editable and turning a Matrix into an animatestring is no porblem, but the otherway around is not so easy. Thats why I prefere Matrix. – Chill3er Apr 29 '17 at 15:43