天天看點

tween.js 使用者指南 - 與 Three.js 配合使用的補間動畫庫Learning Three.js - Tween.js for Smooth Animationtween.js 使用者指南tween.js user guide

tween.js 使用者指南 - 與 Three.js 配合使用的補間動畫庫

<a target="_blank" href="http://blog.csdn.net/opengl_es">轉載請保留此句:太陽火神的美麗人生 -  本部落格專注于 靈活開發及移動和物聯裝置研究:iOS、Android、Html5、Arduino、pcDuino,否則,出自本部落格的文章拒絕轉載或再轉載,謝謝合作。</a>

注意,這是一個進行中的工作,請原諒其中的不足。無論何時,你看到标記為 TODO 的内容,就說明它是還未做的部分。如果你有哪些東西不清楚或缺少細節内容,請送出一個問題,以幫助使這個指南變得更好。或者如果你覺得你也可以提供幫助的話,你可以随意送出你自已的說明或改進。

If you wanted to change the <code>x</code> value from <code>100</code> to <code>200</code>, you'd do this:

Actually this won't do anything yet. The tween has been created but it's not active. You need to start it:

Finally in order to run as smoothly as possible you should call the <code>TWEEN.update</code> function in the same main loop you're using for animating. This generally looks like this:

This will take care of updating all active tweens; after 1 second (i.e. 1000 milliseconds) <code>position.x</code> will be <code>200</code>.

But unless you print the value of <code>x</code> to the console, you can't see its value changing. You might want to use the <code>onUpdate</code> callback:

This function will be called each time the tween is updated; how often this happens depends on many factors--how fast (and how busy!) your computer or device is, for example.

So far we've only used tweens to print values to the console, but you could use it for things such as animating positions of three.js objects:

In this case, because the three.js renderer will look at the object's position before rendering, you don't need to use an explicit<code>onUpdate</code> callback.

You might have noticed something different here too: we're chaining the tween function calls! Each tween function returns the tween instance, so you can rewrite the following code:

into this

Tween.js doesn't run by itself. You need to tell it when to run, by explicitly calling the <code>update</code> method. The recommended method is to do this inside your main animation loop, which should be called with <code>requestAnimationFrame</code> for getting the best graphics performance:

We've seen this example before:

If called without parameters, <code>update</code> will determine the current time in order to find out how long has it been since the last time it ran.

However you can also pass an explicit time parameter to <code>update</code>. Thus,

means "update with time = 100 milliseconds". You can use this to make sure that all the time-dependent functions in your code are using the very same time value. For example suppose you've got a player and want to run tweens in sync. Your <code>animate</code> code could look like this:

So far we've learnt about the <code>Tween.start</code> method, but there are more methods that control individual tweens. Probably the most important one is the <code>start</code> counterpart: <code>stop</code>. If you want to cancel a tween, just call this method over an individual tween:

Stopping a tween that was never started or that has already been stopped has no effect. No errors are thrown either.

The <code>start</code> method also accepts a <code>time</code> parameter. If you use it, the tween won't start until that particular moment in time; otherwise it will start as soon as possible (i.e. on the next call to <code>TWEEN.update</code>).

Individual tweens also have an <code>update</code> method---this is in fact called by <code>TWEEN.update</code>. You generally don't need to call this directly, but might be useful if you're doing crazy hacks.

Things get more interesting when you sequence different tweens in order, i.e. setup one tween to start once a previous one has finished. We call this chaining tweens, and it's done with the <code>chain</code> method. Thus, to make <code>tweenB</code> start after <code>tweenA</code> finishes:

Or, for an infinite chain, set <code>tweenA</code> to start once <code>tweenB</code> finishes:

If you wanted a tween to repeat forever you could chain it to itself, but a better way is to use the <code>repeat</code> method. It accepts a parameter that describes how many repetitions you want:

This function only has effect if used along with <code>repeat</code>. When active, the behaviour of the tween will be like a yoyo, i.e. it will bounce to and from the start and end values, instead of just repeating the same sequence from the beginning.

More complex arrangements might require delaying a tween before it actually starts running. You can do that using the <code>delay</code>method:

will start executing 1 second after the <code>start</code> method has been called.

The following methods are found in the TWEEN global object, and you generally won't need to use most of them, except for <code>update</code>.

We've already talked about this method. It is used to update all the active tweens.

If <code>time</code> is not specified, it will use the current time.

Used to get a reference to the active <code>tweens</code> array and to remove all of them from the array with just one call, respectively.

Used to add a tween to the list of active tweens, or to remove an specific one from the list, respectively.

These methods are usually used internally only, but are exposed just in case you want to do something funny.

Tween.js will perform the interpolation between values (i.e. the easing) in a linear manner, so the change will be directly proportional to the elapsed time. This is predictable but also quite uninteresting visually wise. Worry not--this behaviour can be easily changed using the <code>easing</code> method. For example:

This will result in the tween slowly starting to change towards the final value, accelerating towards the middle, and then quickly reaching its final value. In contrast, <code>TWEEN.Easing.Quadratic.Out</code> would start changing quickly towards the value, but then slow down as it approaches the final value.

There are a few existing easing functions provided with tween.js. They are grouped by the type of equation they represent: Linear, Quadratic, Cubic, Quartic, Quintic, Sinusoidal, Exponential, Circular, Elastic, Back and Bounce, and then by the easing type: In, Out and InOut.

Credit where credit is due: these functions are derived from the original set of equations that Robert Penner graciously made available as free software a few years ago, but have been optimised to play nicely with JavaScript.

Not only can you use any of the existing functions, but you can also provide your own, as long as it follows a couple of conventions:

it must accept one parameter:

<code>k</code>: the easing progress, or how far along the duration of the tween we are. Allowed values are in the range [0, 1].

it must return a value based on the input parameters.

The easing function is only called once per tween on each update, no matter how many properties are to be changed. The result is then used with the initial value and the difference (the deltas) between this and the final values, as in this pseudocode:

For the performance obsessed people out there: the deltas are calculated only when <code>start()</code> is called on a tween.

So let's suppose you wanted to use a custom easing function that eased the values but appplied a Math.floor to the output, so only the integer part would be returned, resulting in a sort of step-ladder output:

And you could use it in a tween by simply calling its easing method, as we've seen before:

Another powerful feature is to be able to run your own functions at specific times in each tween's life cycle. This is usually required when changing properties is not enough.

For example, suppose you're trying to animate some object whose properties can't be accessed directly but require you to call a setter instead. You can use an <code>update</code> callback to read the new updated values and then manually call the setters:

Or imagine you want to ensure the values of an object are in an specific state each time the tween is started. You'll assign a <code>start</code>callback:

The scope for each callback is the tweened object.

Executed right before the tween starts-i.e. before the deltas are calculated. This is the place to reset values in order to have the tween always start from the same point, for example.

Executed when a tween is explicitly stopped (not when it is completed normally), and before stopping any possible chained tween.

Executed each time the tween is updated, after the values have been actually updated.

Executed when a tween is finished normally (i.e. not stopped).

You can also use relative values when using the <code>to</code> method. When the tween is started, Tween.js will read the current property values and apply the relative values to find out the new final values. But you need to use quotes or the values will be taken as absolute. Let's see this with an example:

In addition to tweening to an absolute or a relative value, you can also have Tween.js change properties across a series of values. To do this, you just need to specify an array of values instead of a single value for a property. For example:

will make <code>x</code> go from its initial value to 0, -100 and 100.

The way these values are calculated is as follows:

first the tween progress is calculated as usual

the progress (from 0 to 1) is used as input for the interpolation function

based on the progress and the array of values, an interpolated value is generated

For example, when the tween has just started (progress is 0), the interpolation function will return the first value in the array. When the tween is halfway, the interpolation function will return a value approximately in the middle of the array, and when the tween is at the end, the interpolation function will return the last value.

You can change the interpolation function with the <code>interpolation</code> method. For example:

The following values are available:

TWEEN.Interpolation.Linear

TWEEN.Interpolation.Bezier

TWEEN.Interpolation.CatmullRom

The default is <code>Linear</code>.

Note that the interpolation function is global to all properties that are tweened with arrays in the same tween. You can't make property A change with an array and a Linear function, and property B with an array too and a Bezier function using the same tween; you should use two tween objects running over the same object but modifying different properties and using different interpolation functions.

獲得最佳性能

Getting the best performance

While Tween.js tries to be performant on its own, nothing prevents you from using it in a way that is counterperformant. Here are some of the ways you can avoid slowing down your projects when using Tween.js (or when animating in the web, in general).

When you try to animate the position of an element in the page, the easiest solution is to animate the <code>top</code> and <code>left</code> style properties, like this:

but this is really inefficient because altering these properties forces the browser to recalculate the layout on each update, and this is a very costly operation. Instead of using these, you should use <code>transform</code>, which doesn't invalidate the layout and will also be hardware accelerated when possible, like this:

However, if your animation needs are that simple, it might be better to just use CSS animations or transitions, where applicable, so that the browser can optimise as much as possible. Tween.js is most useful when your animation needs involve complex arrangements, i.e. you need to sync several tweens together, have some start after one has finished, loop them a number of times, etc.

If you use an <code>onUpdate</code> callback, you need to be very careful with what you put on it. This function will be called many times per second, so if you're doing costly operations on each update, you might block the main thread and cause horrible jank, or---if your operations involve memory allocations, you'll end up getting the garbage collector to run too often, and cause jank too. So just don't do either of those things. Keep your <code>onUpdate</code> callbacks very lightweight, and be sure to also use a memory profiler while you're developing.