I am making a small interactive website using scrollmagic and GSAP to animate SVG elements.
However, when animating the y value of an element that had a rotate() transformation, the transformation was removed.
Adding the rotation into the animation did not yield the right result; the rotation was removed from the animation and then animated back in again.
Does anyone know how to preserve the rotation of an SVG element when animating other attributes in GSAP?
example code:
html:
<svg height='300px' width='500px' style='position: absolute;'>
<rect id='rect' width='200' height='75' style='fill:#888;stroke-width:2;stroke:#000' y='0' x='120' transform='rotate(45)' />
</svg>
js:
TweenMax.to('#rect', 1, {x: 100})
fiddle: https://jsfiddle.net/159phcxw/
Short answer: as Tahir suggested, just add this to your JS code:
TweenMax.set("#rect", {rotation:45});
I'd strongly recommend handling all of your transforms through GSAP because it protects you from a bunch of things like browser inconsistencies and loss of precision with rotational values beyond 360 degrees.
GSAP records transform-related values in a special _gsTransform object that's attached to the element itself; this not only boosts performance (no re-parsing of computed style matrix or matrix3d values), but also permits complete independent control of each transform component (rotation, scaleX, scaleY, x, y, skewX, skewY, etc.) regardless of timing offsets or extreme rotational values (impossible with CSS).
In your case, you were mixing transforms - you put the rotation in the attribute and then you asked GSAP to handle the translation. GSAP can actually parse matrix() values you put into the transform attribute or it can also parse any CSS transforms, but you happened to define only a rotate() which is not able to be parsed (I'll spare you the explanation).
Setting any transform-related values through GSAP gets you the best performance and compatibility, plus it's easier to look up current values inside the _gsTransform object later if you need them.
Related
I use rotateX, rotateY, perspective to achieve the effect of transform elements.
I use getBoundingClientRect() to get the top, left, bottom, right, width, height of the element.
How to calculate the four vertices coordinate of the (dom element) after the image is transform.
sorry my enlish is bad
video demo:https://i.imgur.com/YYArUMz.mp4
image demo:
Element.getBoundingClientRect considers the current CSS/SVG transform(CSSOM View Module). See it for yourself, while transform is changing, the return value of getBoundingClientRect will also change.
I'm playing around with SVGs and was working off of this example. However, in my
jsbin the pattern isn't repeating for my <rect> elements.
And when I change the height and width attributes (no I'm not changing the x , y attributes) the rect svg objects just disappear when I enter in large values.
I'm just dipping my toe into SVGs so my knowledge is quite limited. I figure it is something simple but am not seeing what I'm doing incorrectly when I compare to what I'm doing to the grid2.svg that I'm going off of.
You've written this...
<pattern id="OvalPattern2" patternUnits="objectBoundingBox" width="70" height="70" >
With objectBoundingBox units 1 is the size of the shape using it. So your pattern is 70 times the size of the object using it. I suspect you want .7 as the width/height.
I am new to the JavaScript canvas element. I actually just started a few hours ago. I'm working on a free transform of a rectangular section of an image. (For an example of what I am calling a "free transform," see this: http://www.html5.jp/test/perspective_canvas/demo1_en.html. Please note that I do not want to be able to allow the user to transform the image with handles as this example features.)
I know a little bit of how to transform a large image, but I want to transform only the left half (for example) of an image. How can I single out a section and free transform it? I'm guessing I should start by loading the image. I'm also betting the solution will involve marking the left side with paths. But setTransform() doesn't given me the control I need. I would like to have a function similar to this:
function freeTransform(canvas, image,
startX1, startY1, startX2, startY2, startX3, startY3, startX4, startY4,
endX1, endY1, endX2, endY2, endX3, endY3, endX4, endY4)
But the canvas's context does not have this function (as far as I know). Would someone give me some direction? Thank you.
You are correct.
The html canvas cannot transform 1 corner of a rectangle using its common 2d context.
You can use "triangulation" to deform an image in canvas 2d to give it perspective:
http://tulrich.com/geekstuff/canvas/perspective.html
You can get closer to a perspective transform using canvas's 3d context (webGL).
You can use non-parallel transforms to deform an image in webGL to give it perspective:
http://games.greggman.com/game/webgl-3d-perspective/
I am trying to get the height of an element in JavaScript after applying one/several CSS3 transformations on it.
#transformed{
transform:scale(.5);
}
Unfortunately, JQuery's outerHeight doesn't seem to do this naively.
$('#after').outerHeight(); //not affected by the transformation
Example:
http://jsfiddle.net/mQ2nT/
You can use getBoundingClientRect to get the dimensions and positions after the transformation.
Simply, transform your elements, and:
$('#after')[0].getBoundingClientRect();
// note the [0], the function is DOM not jQuery's.
The best thing is that this will also return proper positions, dimensions after every transformation you apply.
You are free to rotate, skew, translate and everything else what CSS provides. gBCR will handle it.
I'd like to build a function like
fromHeretoThere(x1,y1,x2,y2){
//....
}
So that I can move a <div> or an image from one point on the HTML page to another point in a curve.
Is this doable only using Canvas? HTML5? any plugin/scripts yo suggest?
Edit: Here's a work in progress that packages up the second concept described below as a re-usable JS object. You can edit the code or visually drag the curve to see the resulting code:
http://phrogz.net/SVG/animation_on_a_curve.html
I'd personally use SVG, which makes this sort of thing (animating along an arbitrary Bézier curve) trivial using the <animateMotion> element. As a bonus, you can even cause it to calculate the rotation for you. Some examples:
http://www.w3.org/TR/SVG/images/animate/animMotion01.svg
https://developer.mozilla.org/en/SVG/Element/animateMotion
http://devfiles.myopera.com/articles/76/SolarSystem.svg
Note that you don't even have to actually use SVG to display the result; you could simply create an off-screen SVG with this animation and sample the transform of the animated element to get your desired point/rotation.
Alternatively (if you don't want the rotation, or want to calculate it yourself while controlling the rate of traversal) you can create an SVG path and just use getPointAtLength()/getTotalLength() to find where you should be along the path at a given percentage of the total traversal distance. With this you don't even need an SVG document:
// Moving along an S curve from 0,0 to 250,450
var p = document.createElementNS('http://www.w3.org/2000/svg','path');
p.setAttribute('d','M0,0 C350,20 -200,400 250,450');
var len = p.getTotalLength();
for (var i=0;i<=100;i+=10){
var pct = i/100;
var pt = p.getPointAtLength(pct*len);
console.log( i, pt.x, pt.y );
}
// 0 0 0
// 10 65.54324340820312 10.656576156616211
// 20 117.17988586425781 49.639259338378906
// 30 120.2674789428711 114.92564392089844
// 40 100.49604034423828 178.4400177001953
// 50 78.06965637207031 241.1177520751953
// 60 63.526206970214844 305.9412841796875
// 70 74.59959411621094 370.6294860839844
// 80 122.1227798461914 415.8912658691406
// 90 184.41302490234375 438.8457336425781
// 100 250 450
Now all you have to do is set the .style.top and .style.left of your <div> or <img> appropriately. The only 'hard' part is deciding what you want to the curve to look like and defining where to put the handles.
sometimes googling is easier:
http://yuilibrary.com/yui/docs/anim/curve.html
You can use at least:
JavaScript (http://api.jquery.com/animate/)
CSS3 Transitions (http://www.the-art-of-web.com/css/css-animation/)
Canvas (https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images)
CSS3 is probably the easiest, but JavaScript would be the most browser compatible.
You may also want to look at something like this:
http://jsanim.com/
http://processingjs.org/
What is it that you're trying to do?
Using jQuery animate's step function you can animate in any curve you'd like.
For some things using a canvas is better, but for most small and simple animations just changing css values with jQuery (this is what animate does) is faster and simpler.
Here's a quick demonstration I made, built on top of the jQuery.path plugin : http://jsfiddle.net/zVddG/