Detailed description of tween. js Chinese user guide and tween. js User Guide
Animation is a concept that allows you to smoothly change the attributes of an object. You only need to tell it which attributes need to be changed, what final values should they have when the population ends, and how long it will take, the replenishment engine calculates the value from the start point to the end point.
For example, the position object has two coordinates: x and y:
var position = { x: 100, y: 0 }
If you want to change the x coordinate value from 100 to 200, you should do this:
// Create a tween var tween = new TWEEN for the position. tween (position); // then tell tween that we want to move the position of x in animation within 1000 milliseconds. to ({x: 200}, 1000 );
In general, this is not enough. The tween has been created, but it has not been activated (used). You need to start it like this:
// Start tween. start ();
Finally, to successfully complete this effect, you need to call TWEEN. update in the main function, as follows:
animate();function animate() { requestAnimationFrame(animate); // [...] TWEEN.update(); // [...]}
In this way, the animation is executed when each frame is updated. After 1 second (1000 milliseconds), position. x will be changed to 200.
Unless you print the value of x in the console, you cannot see its changes. You may want to use onUpdate callback:
tween.onUpdate(function(object) { console.log(object.x);});
Tips: You may not be able to obtain object. x here. For details, see the issue I mentioned.
This function will be called every time an animation is updated; the frequency of this happens depends on many factors-for example, how fast a computer or device is (and how busy ).
So far, we only use a compensation animation to output values to the console, but you can combine it with three. js objects:
var tween = new TWEEN.Tween(cube.position) .to({ x: 100, y: 100, z: 100 }, 10000) .start();animate();function animate() { requestAnimationFrame(animate); TWEEN.update(); threeRenderer.render(scene, camera);}
In this case, because the three. js Renderer will view the object location before rendering, it does not need to use a clear onUpdate callback.
You may also notice some differences: tween. js can be called in a chain! Every tween function returns a tween instance, so you can rewrite the following code:
var tween = new TWEEN.Tween(position);tween.to({ x: 200 }, 1000);tween.start();
Changed to this:
var tween = new TWEEN.Tween(position) .to({ x: 200 }, 1000) .start();
I will see many examples, so it is good to be familiar with it! For example, 04-simplest.
Tween. js Animation
Tween. js does not run on its own. You need to explicitly call the update method to tell it when to run. The recommended method is to perform this operation in the active draw loop. Use requestAnimationFrame to call this loop for optimal graphic performance.
For example, in the previous example:
animate();function animate() { requestAnimationFrame(animate); // [...] TWEEN.update(); // [...]}
If no parameter is input during the call, update will judge the current time point to determine how long it has been since the last run.
Of course, you can also pass a clear time parameter to the update
TWEEN.update(100);
Indicates "Update time = 100 ms ". You can use it to ensure that all time-related functions in the Code use the same time value. For example, assume that you have a player and want to synchronize the task. Your animate function may look like this:
var currentTime = player.currentTime;TWEEN.update(currentTime);
We use clear time values for unit testing. You can take a look at the example of tests. js to see how we can use different values to call TWEEN. update () to simulate time transmission.
Controls a replenishment Interval
Start and stop
So far, we have learned about the Tween. start method, but there are more methods to control a single population. Perhaps the most important thing is the star method: Stop. If you want to cancel a tween, you only need to call this method through a separate TWEEN:
tween.stop();
Stopping a tween that has never started or stopped has no effect. No error is thrown.
The start method accepts a parameter time. If you use it, the replenishment interval does not start immediately until a specific time point, otherwise it will be started as soon as possible (I. e is the next time TWEEN. update is called ).
Update
There is also an update method for the population-this is actually called by TWEEN. update. You usually do not need to call it directly unless you are a crazy hacker.
Chain
It will become interesting when you arrange different tween sequentially. For example, you can immediately start another tween at the end of the previous tween. We call this a chain tween, which is done using the chain method. Therefore, to enable tweenB to start in tewwnA:
tweenA.chain(tweenB);
Or, for an infinite chain, set tweenA to start once tweenB is complete:
tweenA.chain(tweenB);tweenB.chain(tweenA);
For unlimited chained viewing of Hello world.
In other cases, you may need to link Multiple tween to another tween so that they (the Tween of The Link) can start animation at the same time:
tweenA.chain(tweenB,tweenC);
Warning calling tweenA. chain (tweenB) actually modifies tweenA, so tweenA is always started when tweenA is complete. The return value of chain is only tweenA, not a new tween.
Repeat
If you want to repeat a population forever, you can link to yourself, but a better way is to use the repeat method. It accepts a parameter to describe how many repetitions are required after the first replenishment period is completed
Tween. repeat (10); // loop 10 times tween. repeat (Infinity); // Infinite Loop
The total number of completions will be the number of repeated parameters plus an initial tween. View Repeat.
Yoyo
This function is effective only when repeat is used independently. When the population is active, it will be like yoyo. I. e, it will jump out from the starting value and the ending value, instead of repeating the same order from the beginning.
Delay
A more complex arrangement may need to delay the replenishment period before the actual operation starts. You can use the delay method to do this.
tween.delay(1000);tween.start();
It will be executed one second after the start method is called.
Control all population rooms
In the TWEEN global object, you can find the following method. Except for update, most of the objects do not need to be used.
TWEEN. update (time)
We have discussed this method. It is used to update the population of all activities.
If time is not specified, it uses the current time.
TWEEN. getAll and TWEEN. removeAll
Used to obtain references to the active tweens array and delete all of them from the array from one call.
TWEEN. add (tween) and TWEEN. remove (tween)
This interface is used to add a population to the list of activity population, or delete a specific population from the list.
These methods are usually used internally, but they are exposed if you want to do something interesting.
Inter-population group control
Using the TWEEN Singleton to manage the TWEEN may cause problems in large applications that contain many components. In these cases, you may want to create a smaller replenishment group.
Example: Cross-component conflict
If you use TWEEN to have multiple components and each component wants to manage its own set of population, a conflict may occur. If a component calls TWEEN. update () Or TWEEN. removeAll (), the TWEEN of other components will also be updated or deleted.
Create your own replenishment Group
To solve this problem, each component can create its own TWEEN. Group instance (the Global TWEEN object is used internally ). You can use these groups as the second optional parameter when completing new instances:
Var groupA = new TWEEN. group (); var groupB = new TWEEN. group (); var tweenA = new TWEEN. tween ({x: 1}, groupA ). to ({x: 10}, 100 ). start (); var tweenB = new TWEEN. tween ({x: 1}, groupB ). to ({x: 10}, 100 ). start (); var tweenC = new TWEEN. tween ({x: 1 }). to ({x: 10}, 100 ). start (); groupA. update (); // update only tweenAgroupB. update (); // update only tweenBTWEEN. update (); // update only tweenCgroupA. removeAll (); // only remove tweenAgroupB. removeAll (); // only remove tweenBTWEEN. removeAll (); // only remove tweenC
In this way, each component can process the creation, update, and destruction of a set of population.
Change the easing Function
Tween. js will execute interpolation between values in a linear way (I .e., easing), so the change will be proportional to the elapsed time. This is foreseeable, but it is visually boring. Don't worry-you can easily change this behavior using the easing method. For example:
tween.easing(TWEEN.Easing.Quadratic.In);
This will lead to a slow start to change to the final value, to accelerate to the middle, and then quickly reach its final value, on the contrary, TWEEN. easing. quadratic. the Out will accelerate at the beginning, but it will eventually slow down as the value approaches.
Available Easing functions: TWEEN. Easing
Tween. js provides some existing easing functions. They are grouped according to the equation they represent: linear, quadratic, cubic, four, five, sine, exponential, circular, elastic, back and bounce, and then easing: in, Out, And InOut.
Unless you are familiar with these concepts, these names may not tell you anything. Therefore, you may need to view the Graphs example, which graphically displays all curves on a page, to compare how they look at it.
These features are derived from the primitive equation that Robert Penner generously provided a few years ago as provided by free software, but have been optimized to play a role well with JavaScript.
Use the custom easing Function
You can not only use any existing functions, but also provide your own functions as long as you follow the Conventions:
It must accept a parameter:
K: The easing process, or the duration of our compensation period. The value range is [0, 1.
It must return a value based on the input parameter.
No matter how many attributes you want to modify, the easing function is called only once each time it is updated. Use the result with the initial value and the difference (delta) between the value and the final value, just like this pseudo code:
easedElapsed = easing(k);for each property: newPropertyValue = initialPropertyValue + propertyDelta * easedElapsed;
For those who pay more attention to performance, the increment value is calculated only when start () is called on the tween.
Therefore, let's assume that you want to use a user-defined easing function for easing values, but apply Math. floor to the output, so only the integer part is returned, resulting in a cascade output:
function tenStepEasing(k) { return Math.floor(k * 10) / 10;}
You can use it by simply calling its easing method, as we have seen before:
tween.easing(tenStepEasing);
View the graphs for M easing functions example to view this action (there are also some metaprogramming for generating step functions ).
Callback Function
Another powerful feature is the ability to run its own functions at a specific time in the lifecycle of each population. This is usually required when the property is not changed enough.
For example, if you are trying to set an animation for some objects that cannot directly access the property, you need to call setter. You can use the update callback to read the new update value and then manually call setters. All callback functions use the population object as the unique parameter.
var trickyObjTween = new TWEEN.Tween({ propertyA: trickyObj.getPropertyA(), propertyB: trickyObj.getPropertyB()}) .to({ propertyA: 100, propertyB: 200 }) .onUpdate(function(object) { object.setA( object.propertyA ); object.setB( object.propertyB ); });
You can also imagine that you want to play a sound when a population starts. You can use the start callback:
var tween = new TWEEN.Tween(obj) .to({ x: 100 }) .onStart(function() { sound.play(); });
The range of each callback is the population object-in this case, it is obj.
OnStart
Execute -- I. e. Before calculation before the completion interval starts. Each replenishment interval can only be executed once. I. e. When the repeat () is used to duplicate the replenishment interval, it will not run.
It is good to synchronize to another event or trigger the operation that you want to start during the replenishment period.
The population object is passed in as the first parameter.
OnStop
It is executed when the intercept is explicitly stopped through stop (), but when the intercept is completed normally and before any possible intercept.
The population object is passed in as the first parameter.
OnUpdate
The updated value is executed during each update of the replenishment interval.
The population object is passed in as the first parameter.
OnComplete
Execute when the replenishment interval is completed normally (that is, do not stop.
The population object is passed in as the first parameter.
Advanced tween
Relative Value
You can also use relative values when using the to method. When tween is started, Tween. js will read the current property value and apply the relative value to find the new final value.
However, you need to use quotation marks. Otherwise, these values are considered absolute. Let's look at an example:
// This will make the `x` property be 100, alwaysvar absoluteTween = new TWEEN.Tween(absoluteObj).to({ x: 100 });// Suppose absoluteObj.x is 0 nowabsoluteTween.start(); // Makes x go to 100// Suppose absoluteObj.x is -100 nowabsoluteTween.start(); // Makes x go to 100// In contrast...// This will make the `x` property be 100 units more,// relative to the actual value when it startsvar relativeTween = new TWEEN.Tween(relativeObj).to({ x: "+100" });// Suppose relativeObj.x is 0 nowrelativeTween.start(); // Makes x go to 0 +100 = 100// Suppose relativeObj.x is -100 nowrelativeTween.start(); // Makes x go to -100 +100 = 0
View the 09_relative_values example.
Array of population values
In addition to absolute values or relative values, Tween. js can also change attributes across a series of values. To do this, you only need to specify the value of an array, rather than a single value of an attribute. For example:
var tween = new TWEEN.Tween(relativeObj).to({ x: [0, -100, 100] });
Changes x from the initial value to 0,-100, and 100.
These values are calculated as follows:
- First, the completion progress is calculated as usual
- The progress (from 0 to 1) is used as the input of the interpolation function.
- Generate inner interpolation based on an array of progress and Value
For example, when the population is just started (the progress is 0), the interpolation function returns the first value in the array. When the population ends, the interpolation function returns a value approximately in the middle of the array. When the population ends, the interpolation function returns the last value.
You can use the interpolation method to change the interpolation function. For example:
tween.interpolation( TWEEN.Interpolation.Bezier );
The following values are available:
- TWEEN. Interpolation. Linear
- TWEEN. Interpolation. bezr
- TWEEN. Interpolation. CatmullRom
The default value is Linear.
Note that the interpolation function performs global population for all attributes of the array in the same population.
You cannot use arrays and linear functions to modify attribute A, or use the same tween to change the attributes of array B, B, And bezr functions; you should use two complementary objects running on the same object, but modify different attributes and use different interpolation functions.
View the 06_array_interpolation example.
Optimal Performance
Although Tween. js tries to execute it by itself, nothing can prevent you from using it in a counterproductive way. There are some ways to avoid slowing down the project speed when using Tween. js (or when making an animation on a webpage.
Use high-performance CSS
When you try to set the element position on the page, the simplest solution is to set an animation for the top and left attributes, as shown below:
var element = document.getElementById('myElement');var tween = new TWEEN.Tween({ top: 0, left: 0 }) .to({ top: 100, left: 100 }, 1000) .onUpdate(function(object) { element.style.top = object.top + 'px'; element.style.left = object.left + 'px'; });
But this is actually inefficient, because changing these attributes will force the browser to re-calculate the layout every time it is updated, which is very expensive. On the contrary, you should use transform, which will not invalidate the layout, and will be accelerated by hardware as possible, such:
var element = document.getElementById('myElement');var tween = new TWEEN.Tween({ top: 0, left: 0 }) .to({ top: 100, left: 100 }, 1000) .onUpdate(function(object) { element.style.transform = 'translate(' + object.left + 'px, ' + object.top + 'px);'; });
If you want to know