Similar questions appear to have been asked before, however none of the solutions seem to work for me so here is my code:
this.animate({scale(2, 2, vinerBBoxX, vinerBBoxY)}, 100, mina.easeinout);
vinerBBoxX is the x centre of the element and vinerBBoxY is the y centre, both have worked fine when scaling without animating.
I have had trouble with scaling generally and there are so many solutions on the web that I found completely impenetrable. Please help!
Snap uses its own string format for transforms. s stands for scale, and by default it will scale around its centre.
The attribute to animate is 'transform' as opposes to scale (transform can take scale as a part of a string when set, eg transform: 'scale(2,2)', but this wouldn't work as an animation as it is.
The simplest way is like this...
g.animate({ transform: 's2,4'}, 2000)
You can combine transform elements as well, like
g.animate({ transform: 't200,200s2,4'}, 2000)
In order to translate 't' 200,200 followed by scalex,y 's' 2,4
jsfiddle
Related
I've been playing around with using matrices to hold transforms for 2D elements in canvas. setTransform works pretty well for this, but I ran into an interesting issue where I get the Moire effect when I try to render a transformed cube at the coordinates (0, 0). Setting the coordinates to (0, 1) or (1, 0) fixes this. Also the problem seems to only be with fillRect, rendering text instead of the cube works just fine.
Example Pen: https://codepen.io/danman113/pen/mdEYdKx
I figured out a solution but I still don't fully understand why I was getting a Moire pattern. I would love if someone could explain that to me.
The solution was to reset the transform after setting it. I'm not sure why this works as I thought setTransform implicitly reset the transform after it was called.
c.setTransform(transform[0], transform[3], transform[1], transform[4], transform[6], transform[7])
c.fillRect(0, 0, 100, 100)
c.resetTransform()
Working example: https://codepen.io/danman113/pen/dyXEGQw
EDIT:
As Kaiido points out in his comment, the Moire effect happens because clearRect() is also transformed. Adding the resetTransform fixes this.
I use the $(window).resize(function()) to get changes in window size, and acoording to those I want to zoom in and zoom out. Why zooming?!, because I have a lot of dynamically appended divs with absolute coordinate and I want those divs to keep the allignment when window is changed.Basically what one would get, if pressed 'Ctrl' + '-'.
Let's say I have this image
If I use .css to add the following line, which zooms out '-moz-transform': 'scale(0.8)' I get an image like this
But if I use Ctrl + - instead I get
As you see the second image has some coordinates messed up(not changed). Has anyone any idea on why that is, or another function I could use to zoom out?
Here is a jsfiddle to play yourself http://jsfiddle.net/rnhev60f/8/
EDIT:: After the responses, I gave up on the idea. Instead I created a function to calculate the percentage of the changes (newSize / originalSize) and used the percentage to change the position and size of every object in order to avoid all backdoors and bugs. It's a bit more comlicated and ended up with a LOC-wise longer function, but works for me for now. Thanks for the responses tho!
You need to scale both the body and the span
Demo
http://jsfiddle.net/tdov936x/
Code
$('body,span').css({'transform': 'scale(' + currentZoom + ')'});
Result
Consider adding transform-origin: 0% 0%; as 2D transformations can change the x- and y-axis of an element
I am using css 3d transforms in my project. I am trying to apply a new transform on the containing element of several other elements. I am also trying to use getBoundingClientRect on one of its child elements. That container also has other elements in it. When the container has this value for the transform css property:
translateZ(1026px) rotateX(-90deg) rotateY(180deg) translateZ(439.001px)
here's what element.getBoundingClientRect().top for that certain child element is: 77.953109741210944 according to chrome's developer tools but when I use the elements tab to change the `transform property to this:
translateZ(1027px) rotateX(-90deg) rotateY(180deg) translateZ(439.001px)
here's what element.getBoundingClientRect().top is: -75048.6484375 what would possibly cause this? I'm not posting any code because this occurs even when I modify the values through the console. And when I make the first translateZ something like 1000px, it is still about 77. Even when it is at 0 the top of the bounding rect is about 50-100 somewhere. But when it goes beyond 1026px, the elment seems to jump to top -80000 or so. Visually, however, the element look like it should and doesn't "jump" randomly at 1027px. Can somebody say a situation that might cause this?
in case it is a browser bug or something, I'm using chrome 32.0.1687.2 dev-m Aura
EDIT:
here is a jsfiddle link:
http://jsfiddle.net/a6KxQ/2/
It'll generate a table of all translateZ values and the resulting elt.getBoundingClientRect().top values. The code's messy, but in the outputted table, if you look over it carefully, you'll find that, at some point, the top value will randomly jump far, far down. And then it'll quickly recover to come back to it's previous value. Weird.
The fiddle might take a long time to load.
As you suspected, It has to do with the perspective of the viewpoint. By increasing of the value for the 1st translateZ, you are bringing the rectangle closer to you. Eventually it is so close, it has passed the point of the camera. From that point on, the shape, un-rotated, stood behind your eyes.
Then you did a rotateX(-90deg). what happens there is the rectangle fell down forwards (towards the positive Z direction, but behind the camera.). Now, since the tunnel of the view is of a trapezoid shape, hence you get what we see in this screenshot:
With the rectangle behind the camera, as the it rotates, part of it is pivoted back into view.
So the getBoundingClientRect() is actually giving you the bottom of the shape's bound! Now that the shape is flipped, and it doesn't understand 3D.
I hope that made sense to you. I want to get to you first :) Ask me before down-voting, I can explain in more details.
so, it is by design. You probably want to restrict the translateZ value to be smaller than perspective.
EDIT:
sorry I have been busy. I meant to give a more detailed response. Thanks for whoever gave me the bounty.
A updated demo
Play around the numbers, you will make the following observations:
when translateZ = perspective - 150px, the bounding box is abnormally small and in wrong position
when perspective - 150px < translateZ < perspective + 150px, the bounding box is on the opposite side of where it should be, and the size is abnormally large
when tranlateZ = perspective + 150px, the bounding box is abnormally small again and higher in position in case 1)
the above is not affected by perspective-origin
150px is half of the width/height of the square
when tranlateZ > perspective + 150px, the bounding box is normal again!
Why is that?
in case 1) one of the edges just intersects with the plane that the camera/perspective is located.
in case 2) the square intersects with the camera plane
in case 3) the edge opposite to the edge in case 1) now intersects with camera/perspective plane.
in case 6) all of the square has passed the camera plane
The projection algorithm used to convert 3D coordinates to on screen 2D coodinates does not take into account of the fact that two corners are infront of the camera, and two other corners are behind, hence creating a wrong projection, and hence wrong size.
That was what I meant by "it doesn't understand 3D". That was vague as it can be I realize, Sorry. When all the shape is passed the camera plane, it works again.
Firefox, and Chrome both have this problem, but have different representations, numerically. Probably because different projections matrix are used. So I don't want to figure out what exactly went wrong. Fire a bug report to them :)
Realistically though, you might need to work around it.
I'm not sure how to explain it, and it could be off base, but when you comment out the the perspective css you get the same values down the whole table. I'm not sure what perspective does to the math...
#main3DWrapper{
/*
-webkit-perspective: 1500px;
-moz-perspective: 1500px;
perspective:1500px;
-webkit-perspective-origin: 50% 1%;
perspective-origin:50% 1%;
*/
-webkit-transform: translate3d(0,0,0,0);
transform:translate3d(0,0,0,0);
display: block;
height: 100%;
left: -121.96603393554688px;
position: absolute;
top: 409.5150146484375px;
width: 100%;
}
Also, why are you setting the translateZ() value twice in the js?
container.style.webkitTransform='translateZ('+dist+'px) rotateX(-90deg) rotateY(180deg) translateZ(429.001px)';
container.style.transform='translateZ('+dist+'px) rotateX(-90deg) rotateY(180deg) translateZ(429.001px)';
Shouldn't is just be?:
container.style.webkitTransform='translateZ('+dist+'px) rotateX(-90deg) rotateY(180deg)';
container.style.transform='translateZ('+dist+'px) rotateX(-90deg) rotateY(180deg)';
I have the following code:
image1Rect.animate({
transform: "S-0.025,1"
}, 1000, 'easeOut', function () {
image1Rect.hide();
image1Ref.show();
image1Ref.scale(0.025, 1);
image1Ref.animate({
transform: "S1,1"
}, 1000, 'easeOut');
});
where I am trying to reduce X scale of image1Rect to 0.025 and then when that is done increase the scale X of image1Ref from 0.025 to 1. I am trying to do this using appended transforms but since that did not work for me I had to use deprecated function scale on image1Ref to first reduce its scale X to 0.025.
I would ideally like to do this using appended transforms, could you please help me out?
It is caused by the negative integer in
transform: "S-0.025,1"
Negative integers cause the image to flip in that axis.
use
transform: "S0.025,1"
Try using the matrix as part of the transform:
var R = this.paper;
loop through paths
R.path(blah blah).attr(blah blah).transform("m1,0,0,-1,0,0");
end loop
"m" stands for matrix, and the 4th place "-1" represents the image flip. "1" in that place - (the y-axis place) would be a normal 'as-the-path' dictates, view. Keep in mind you will no longer see your image on the screen, because it has been redrawn well above the containing div. As far as I can tell, it uses the top edge of the div as its pivot.
As an aside, the other places represent some form of 'skew' for the image, which is not interesting if all you want to do is flip it.
To see my image, I had to locate and zoom above it using the viewBox, like this:
R.setViewBox(0,-575,200,200);
I'm trying to draw a grid on a <canvas> element with the ultimate goal of making a Go board.
For some reason the grid is looking stretched, with the lines being thicker than 1 pixel and the spacing being completely wrong. It doesn't even start in the (10,10) position..
It would be great if someone could take a look at tell me what I'm doing wrong.
http://jsfiddle.net/h2yJn/
I've found the problem. I was setting the dimensions of the <canvas> using CSS, when you actually have to set the width and height attributes. This was causing it to be stretched/skewed.
var canvas = $('<canvas/>').attr({width: cw, height: ch}).appendTo('body');
http://jsfiddle.net/h2yJn/66/
Please try it outside jsfiddle, maybe jsfiddle is applying some linear transformation.
Also please make sure that you add 0.5 everywhere to both x and y coordinates. Alternatively, you can apply translate(0.5, 0.5) to shift all coordinates by half a pixel.