D.Mietke
D.Mietke

Reputation: 1

Snap.Matrix().scale(...) does not work as expected explained in Snap docs

I try to learn the use of Snap.SVG. Creating an new Snap matrix I get unexspected results with the method matrix.scale(). Using el.transform("s...") will work as described in the Snap docs. Here the only used script code:

var s = Snap(#svgout);
var box = s.rect(100,70, 100,60).attr({opacity: 0.3});
var box2 = box.clone().attr({fill: "#0f0", opacity: 0.5});
var myMatrix = new Snap.matrix();
myMatrix.scale(0.5);
box2.transform(myMatrix);   // isn't using the center of box2

With myMatrix.scale(0.5,150,100) the coordinates of the centre of box2 it doesn't scale. I have to use myMatrix.scale(0.5,0.5,150,100) with both horizontal and vertical scale factors and the coordinates of elements centre for the expected result.
The shown results are the same in Firefox, Opera and Chrome. I'm using the newest Snap.Svg library and with the previus one it's the same result.

I hope to get some help, Yours faithfully, D. Mietke

complementary to Ian's answer I have an element box2 and myMatrix for scaleing the element. The Snap docs tell me in

Matrix.scale(x,[y],[cx],[cy]); 

that the parameters in [] are optional and the only use of x will scale horizontal and vertical with the same factor around the centre.

box2.transform("s0.5");   // works fine
box2.transform("s0.5,150,100"); // same result (150,100) is the centre

in the first line the methode transform("...") doesn't know about the middle of box2 so as myMatrix. In the second line the transform string works with one scale faktor for horz. and vert. but in myMatrix I have to write

myMatrix.scale(0.5,0.5,150,100); // both scale factors for one

applied to box2 and obtained the matrix with

var m = box2.transform().localMatrix; // matrix(0.5,0,0,0.5,75,50)

myMatrix.scale(0.5,150,100);  // doesn't work

applied to box2 the var m will show matrix(1,0,0,1,0,0)

myMatrix.scale(0.5);  // doesn't use the centre like the transform("...")

applied to box2 the var m will show matrix(0.5,0,0,0.5,0,0)

A few days ago all worked fine (yes!) with the same result by the use of box2.transform("s0.5"); or box2.transform(myMatrix); with predefined matrix as in the examples above. Two days later and up to now the results are unexpected. I don't see what I misunderstand in the use of myMatrix.

With kind regards, D. Mietke

Upvotes: 0

Views: 565

Answers (1)

Ian
Ian

Reputation: 13842

I think there's a couple of things. Firstly in the docs, the optional form of Matrix.scale takes 4 args, scalex, scaley, centerx, centery. So it seems reasonable to just duplicate scalex into scaley if they will both be the same.

For the code question of why the matrix isn't scaling around the objects center, it's because there is no way for a matrix to know what the objects center is (as there is no element associated!). And an SVG scale will scale around 0,0 still.

So the difference is, the transform strings are there to make life easier, and take all of that stuff into account if wanted.

But if you do these two lines...

var myMatrix = new Snap.matrix();
myMatrix.scale(0.5);

There is no object associated to know what it should scale around, so it will just do an SVG matrix scale from 0,0. (I believe the docs are wrong when it says "Default cx, cy is the middle point of the element." as there is no element involved with this currently).

When you later do

box2.transform(myMatrix);

It will just apply that matrix, nothing more.

So really if you want the easier route, use transform strings. Thats what they are there for. You very rarely need to use those matrix commands with Snap, so if you are doing, it could be that you are making life more difficult for yourself.

box2.transform('s2');

As this form of transform is applied to the element (as applied to a matrix), it knows where the center is, so it can be more helpful and add the center for you.

You can find further info on the transform strings here

Upvotes: 0

Related Questions