Jump to content
GreenSock

ThrowPropsPlugin

ThrowPropsPlugin allows you to smoothly glide any property to a stop, honoring an initial velocity as well as applying optional restrictions on the end value. You can define a specific end value or allow it to be chosen automatically based on the initial velocity (and ease) or you can define a max/min range or even an array of snap-to values that act as notches. You can have it "watch" certain properties to keep track of their velocities and then use them automatically when you do a throwProps tween. This is perfect for flick-scrolling or animating things as though they are being thrown (where momentum factors into the animation).

For example, let's say a user drags a ball and and then when released, the ball should continue flying at the same velocity as it was just moving (so that it appears seamless), and then glide to a rest. You can't do a normal tween because you don't know exactly where it should land or how long the tween should last (faster initial velocity would usually mean a longer duration). You'd like it to decelerate based on whatever ease you define in your tween (always use some sort of easeOut, like Power1.easeOut, Strong.easeOut, etc.).

Maybe you want the final resting value to always land within a particular range so that the ball doesn't fly off the edge of the screen. But you don't want it to suddenly jerk to a stop when it hits the edge of the screen either; instead, you want it to ease gently into place even if that means going past the landing spot briefly and easing back (if the initial velocity is fast enough to require that). The whole point is to make it look smooth.

No problem.

In its simplest form, you can pass just the initial velocity for each property like this:

TweenLite.to(obj, 2, {throwProps:{x:500, y:-300}});

In the above example, obj.x will animate at 500 pixels per second initially and obj.y will animate at -300 pixels per second. Both will decelerate smoothly until they come to rest 2 seconds later (because the tween's duration is 2 seconds).

To use the Strong.easeOut easing equation and impose maximum and minimum boundaries on the end values, use the object syntax with the max and min special properties like this:

TweenLite.to(obj, 2, {throwProps:{x:{velocity:500, max:1024, min:0}, y:{velocity:-300, max:720, min:0}}, ease:Strong.easeOut});

Notice the nesting of the objects ({}). The max and min values refer to the range for the final resting position (coordinates in this case), not the velocity. So obj.x would always land between 0 and 1024 in this case, and obj.y would always land between 0 and 720. If you want the target object to land on a specific value rather than within a range, simply set max and min to identical values or just use the "end" property. Also notice that you must define a velocity value for each property (unless you're using track() - see below for details).

Valid properties for object syntax

  • velocity : Number or "auto" - the initial velocity, measured in units per second. You may omit velocity or just use "auto" for properties that are being tracked automatically using the track() method.
  • min : Number - the minimum end value of the property. For example, if you don't want x to land at a value below 0, your throwProps may look like {x:{velocity:-500, min:0}}
  • max : Number - the maximum end value of the property. For example, if you don't want x to exceed 1024, your throwProps may look like {x:{velocity:500, max:1024}}
  • end : [Number | Array | Function] - if end is defined as a Number, the target will land EXACTLY there (just as if you set both the max and min to identical values). If end is defined as a numeric Array, those values will be treated like "notches" or "snap-to" values so that the closest one to the natural landing spot will be selected. For example, if [0,100,200] is used, and the value would have naturally landed at 141, it will use the closest number (100 in this case) and land there instead. If end is defined as a Function, that function will be called and passed the natural landing value as the only parameter, and your function can run whatever logic you want, and then return the number at which it should land. This can be useful if, for example, you have a rotational tween and you want it to snap to 10-degree increments no matter how big or small, you could use a function that just rounds the natural value to the closest 10-degree increment. So any of these are valid: end:100 or end:[0,100,200,300] or end:function(n) { return Math.round(n / 10) * 10; }
  • linkedProps : String - a comma-delimited list of properties that should be linked together into a single object when passed to a function-based end value so that they're processed together. This is only useful when, for example, you have an "x" and "y" but the logic in your end function needs BOTH of those (like for snapping coordinates). See https://codepen.io/GreenSock/pen/aqEdGM?editors=0010 for an example. The object that gets passed as the only parameter to the "end" function will have the properties are listed in linkedProps. So, for example, if linkedProps is "x,y", then an object like {x:100, y:140} gets passed to the function as a parameter. Those values are the natural ending values, but of course your function should return a similar object with the new values you want the end values to be, like return {x:200, y:300}.

ThrowPropsPlugin isn't just for tweening x and y coordinates. It works with any numeric property, so you could use it for spinning the rotation of an object as well. Or the scaleX/scaleYproperties. Maybe the user drags to spin a wheel and lets go and you want it to continue increasing the rotation at that velocity, decelerating smoothly until it stops. It even works with method-based getters/setters.

Automatically determine duration

One of the trickiest parts of creating a throwProps tween that looks fluid and natural (particularly if you're applying maximum and/or minimum values) is determining its duration. Typically it's best to have a relatively consistent level of resistance so that if the initial velocity is very fast, it takes longer for the object to come to rest compared to when the initial velocity is slower. You also may want to impose some restrictions on how long a tween can last (if the user drags incredibly fast, you might not want the tween to last 200 seconds). The duration will also affect how far past a max/min boundary the property may go, so you might want to only allow a certain amount of overshoot tolerance. That's why ThrowPropsPlugin has a few static helper methods that make managing all these variables much easier. The one you'll probably use most often is the to() method which is very similar to TweenLite.to() except that it doesn't have aduration parameter and it adds several other optional parameters. Read the docs below for details.

ThrowPropsPlugin.to(mc, {throwProps:{x:"auto", y:{velocity:"auto", max:1000, min:0}}, ease:Strong.easeOut});

Feel free to experiment with using different easing equations to control how the values ease into place at the end. You don't need to put the "ease" special property inside the throwPropsobject. Just keep it in the same place it has always been, like:

TweenLite.to(mc, 1, {throwProps:{x:500, y:-300}, ease:Strong.easeOut});

Automatically track velocity

Another tricky aspect of smoothly transitioning from a particular velocity is tracking the property's velocity in the first place! So we've made that easier too - you can use theThrowPropsPlugin.track() method to have the velocity (rate of change) of certain properties tracked and then throwProps tweens will automatically grab the appropriate tracked value internally, allowing you to omit the velocity values in your tweens altogether. See the track() method's description for details. And make sure you start tracking velocity at least a half-second before you need to tween because it takes a small amount of time to guage how fast something is going.

A unique convenience of ThrowPropsPlugin compared to most other solutions out there that use frame-based loops is that everything is reverseable and you can jump to any spot in the tween immediately. So if you create several throwProps tweens, for example, and dump them into a TimelineLite, you could simply call reverse() on the timeline to watch the objects retrace their steps right back to the beginning!

Examples

The following example creates a green box and a red box that you can drag and toss around the screen in a natural, fluid way. If you check the "Snap to grid" checkbox, the boxes will always land exactly on the grid. We use Draggable class so that we can focus more on the ThrowPropsPlugin code rather than all the boilerplate code needed to make things draggable:

The next example shows how rotation can be flicked as well, and we make sure that the end rotation is always a multiple of 45 degrees:

The following example demonstrates using a custom "end" function for complex snapping that requires both x and y values, thus linkedProps is used:

ThrowPropsPlugin is a Club GreenSock membership benefit. You must have a valid membership to use this class without violating the terms of use. Visit http://www.greensock.com/club/ to sign up or get more details.

ThrowPropsPlugin and other bonus plugins are not hosted on a CDN. Checkout our CDN FAQs for more info.

Properties

defaultResistance : Number

[static] The default resistance that is used to calculate how long it will take for the tweening property (or properties) to come to rest by the static ThrowPropsPlugin.to() and ThrowPropsPlugin.calculateTweenDuration() methods.

Methods

calculateChange( velocity:Number, ease:*, duration:Number, checkPoint:Number ) : Number

[static] Determines the amount of change given a particular velocity, an easing equation, and the duration that the tween will last.

calculateDuration( start:Number, end:Number, velocity:Number, ease:*, checkPoint:Number ) : Number

[static] Calculates the duration (in seconds) that it would take to move from a particular start value to an end value at the given initial velocity, decelerating according to a certain easing equation (like Strong.easeOut).

calculateTweenDuration( target:Object, vars:Object, maxDuration:Number, minDuration:Number, overshootTolerance:Number ) : Number

[static] Analyzes various throwProps variables (like initial velocities, max/min values, and resistance) and determines the appropriate duration.

getVelocity( target:Object, prop:String ) : Number

[static] Returns the current velocity of the given property and target object (only works if you started tracking the property using the ThrowPropsPlugin.track() or VelocityTracker.track() method).

isTracking( target:Object, prop:String ) : Boolean

[static] Allows you to discern whether the velocity of a particular target or one of its properties is being tracked (typically initiated using the track() method).

to( target:Object, vars:Object, maxDuration:Number, minDuration:Number, overshootTolerance:Number ) : TweenLite

[static] Automatically analyzes various throwProps variables (like velocity, max, min, and resistance) and creates a TweenLite instance with the appropriate duration.

track( target:Object, props:String, type:String ) : VelocityTracker

[static] Allows you to have the velocity of particular properties automatically tracked for you so that ThrowPropsPlugin tweens can access that data internally instead of manually calculating it and feeding it into each tween.

untrack( target:Object, props:String ) :

[static] Stops tracking the velocity of certain properties (or all properties of an object), like ones initiated with the track() method.

Copyright 2017, GreenSock. All rights reserved. This work is subject to theterms of useor for Club GreenSock members, the software agreement that was issued with the membership.
×