Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Dakota

Animating multiple custom properties: Matrix3d Transform

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hi there, 

 

I'm new to GSAP and am trying to evaluate it for some animations for a project I'm working on. I found some examples of using tweenlite to animate a custom property and was able to create a test that does this. I'm not sure how or if I can extrapolate that concept into animating multiple values at the same time with one tweenlite call. 

 

What I'm doing is animating a square box with a Matrix3D transform. (this only needs to work in webkit)

To calculate the Matrix3D transform I'm using a handy bit of Javascript called PerspectiveTransform.js (https://github.com/edankwan/PerspectiveTransform.js) where I can pass the width & height of my element, and specify x&y coordinates for all four corners of the element. The script then calculates the Matrix3D transform required to distort the element to those new coordinates. 

 

I have a jsfiddle example that illustrates this. The first box has a Matrix3d transform applied showing the desired result. In this test the bottom right corner is moved from 250,250 to 220,220. 

 

I found examples on these forums that let me figure out how to animate that by creating an object with set/get functions. I need to figure out if I can do the same but for the "y" coordinate of that bottom right corner as well at the same time. I can only call the transform function once per frame of the animation because it generates a matrix3d transform for the whole element...not just a corner. In the end I'll actually have to animate all 4 corners of the element for a total of 8 coordinates. 

 

 

http://jsfiddle.net/jhBYw/1/

 

If anyone can help and tell me if this is even possible with GSAP or if there is a better way to do this I would greatly appreciate it. I know it is has been done: http://www.is-real.net/experiments/css3/wonder-webkit/

<div class="box1"></div>
<div class="box2"></div>
<a href="#">run</a>
.box1 {
    background: blue;
    width:250px;
    height:250px;
    -webkit-transform:matrix3d(0.956521739, -0.043478261, 0, 0.000347826, -0.043478261, 0.956521739, 0, 0.000347826, 0, 0, 1, 0, 0, 0, 0, 1);
}
.box2 {
    background: blue;
    width:250px;
    height:250px;
    
}
function transformPerspective(elem, br_x, br_y) {

		var transform = new PerspectiveTransform(elem, 250, 250, true);

	    // the properties represent the 4 corners are "topLeft", "topRight", "bottomLeft" and "bottomRight"
	    transform.bottomRight.x = br_x;
	    transform.bottomRight.y = br_y;

	    // check the polygon error before updating
	    if(transform.checkError()==0){
	        transform.update(); // update the perspective transform
	        elem.style.display = "block"; // show the element
	    }else{
	        elem.style.display = "none"; // hide the element
	    }
}

var box = $('.box2').get(0);
var endValX = 220;
var currValX = 250;


obj = {};

obj.getDistortVal = function() {
    return parseInt(currValX);
};
obj.setDistortVal = function(new_x) {
    currVal = parseInt(new_x);
    transformPerspective(box,currVal, 250);
};

var animate = function(e) {
	e.preventDefault();
    

	TweenLite.to(obj, 0.2, {setDistortVal: endValX, ease: Power2.easeInOut});
};

$('a').on('click',animate);

Link to post
Share on other sites

Hi Dakota,

 

Thanks for the question and all the supporting info. 

 

I didn't have time to dig deep into your code but, I was very curious to try to find a safe way to animate all 4 corners. 

 

I approached this by creating a transform and then using a TimelineLite with tweens for each corner and a single onUpdate callback.

var tl = new TimelineLite({onUpdate:update, onUpdateParams:[element, transform]}) //call update once per tick
//tween all corners at the same time
tl.to(transform.topLeft, 1, {x:126, ease: Power2.easeInOut}, 0)
  .to(transform.topRight, 1, {x:500, y:30, ease: Power2.easeInOut}, 0)
  .to(transform.bottomLeft, 1, {y:300, ease: Power2.easeInOut}, 0)
  .to(transform.bottomRight, 1, {x:600, y:126, ease: Power2.easeInOut}, 0)

http://jsfiddle.net/m7Yhg/2/

 

Seems to work well.

 

Pretty sure that is what they are doing here: http://fff.cmiscm.com/#!/section/sheeps

  • Like 2
Link to post
Share on other sites

Thank you Carl! I had not explored TimelineLite. This makes sense and the animation is very smooth. 

Link to post
Share on other sites
  • 4 weeks later...

So thanks to the help I got I was able to extrapolate that example into some code that works really well for the interface. 

 

I'm running into one problem though. It's not too bad, I actually might not change it if it is a real pain to code around but my elements transform to their finished position. But then they don't animate back to their original position. Now, i think this is due to how the PerspectiveTransform.js library (

 

I'm wondering if there is an easier way.

 

I do see that I can .reverse() a timeline but that won't really work here I don't think because each box has it's own timeline as needed and when you move from one box to the next some would need to animate to flat, some would need to animate from their current distorted position to a new distorted position.

 

http://jsfiddle.net/zDJun/

(might only work in webkit, this is all for a kiosk running in webkit on a Mac)

 

Here is a jsfiddle, you really have to see this to understand how it works. It's not bad, quite snappy in fact, but I'd be curious if it is possible to smoothly animate each box back flat, and some from distorted to a new distortion. 

 

 

Edit: 

some of the code in the jsFiddle has been simplified as far as the grid is concerned. This interface is actually more complicated than this reduced test. The grid can be dragged around and new tiles are added and old ones that are invisible are removed. They are all positioned absolutely instead of floated and they have text/icons and photo content within each box. Each one launches a modal interface that then lets the user play a video on another monitor in a separate browser window on a 55" TV. 

  • Like 1
Link to post
Share on other sites

unfortunately that is built with Canvas... and the performance isn't very good...the fans on my Macbook kick on like crazy running that. 

Link to post
Share on other sites

Did you give reverse() a try. Remember that the engine has a very complete overwrite management system build, so in theory while one elementis reversing and the other is going forward, the last tween being created takes over the properties being animated by both. So in this case as soon as you move the mouse out the element's four corners go to 0, but the other elements 4 corners go to 250, including the previous element's two adjacent or common points. At this juncture the new tween takes over those points so they go back to 250, while the other 2 points, that aren't adjacent, go back to 0.

 

Another option is check if the adjacent elements are being tweened, if so, you create a new tween that animates the common points values back to 250, that tween will also overwrite the previous one, so the common points go back to 250 and the rest to 0.

 

Hope that helps a little.

Rodrigo.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×