tween.js 用户指南

tween.js 用户指南- 与Three.js 配合使用的补间动画库

Learning Three.js - Tween.js forSmooth Animation

tween.js 用户指南tween.js user guide

注意,这是一个进行中的工作,请原谅其中的不足。无论何时,你看到标记为 TODO 的内容,就说明它是还未做的部分。如果你有哪些东西不清楚或缺少细节内容,请提交一个问题,以帮助使这个指南变得更好。或者如果你觉得你也可以提供帮助的话,你可以随意提交你自已的说明或改进。

NOTE

 thisis a work in progress, please excuse the gaps. Wherever you see somethingmarked as TODO, it's not done yet. If you something is unclear or missingdetails, please file an issue and help make this guide better. Orfeel free to submit clarifications or improvements of your own if you feel youcan help too!

什么是补间动画?他们如何工作?为什么你想要使用它们?

What is a tween? How do they work? Why doyou want to use them?

A tween (fromin-between) is a concept thatallows you to change the values of the properties of an object in a smooth way.You just tell it which properties you want to change, which final values shouldthey have when the tween finishes running, and how long should this take, andthe tweening engine will take care of finding the intermediate values from thestarting to the ending point. For example, suppose you have a position object with x and y coordinates:

var position = { x: 100, y:0 }

If you wanted to change thex value from  to , you'd do this:

// Create a tween for position firstvar tween = new TWEEN.Tween(position);// Then tell the tween we want to animatethe x property over 1000 millisecondstween.to({ x: 200 }, 1000);

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

// And set it to starttween.start();

Finally in order to run as smoothly aspossible you should call theTWEEN.update function in the same main loopyou're using for animating. This generally looks like this:

animate();function animate(){requestAnimationFrame(animate);// [...]TWEEN.update();// [...]}

This will take care of updating all activetweens; after 1 second (i.e. 1000 milliseconds)position.x will be .

But unless you print the value ofx to the console, you can't see its value changing. You might want touse the onUpdate callback:

tween.onUpdate(function(){console.log(this.x);});

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

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

var tween = new TWEEN.Tween(cube.position);  .to({ x: 100, y:100, z: 100 }, 10000)  .start();animate();functionanimate(){requestAnimationFrame(animate);TWEEN.update();threeRenderer.render(scene,camera);}

In this case, because the three.js rendererwill look at the object's position before rendering, you don't need to use anexplicitonUpdate callback.

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

var tween = newTWEEN.Tween(position);tween.to({ x: 200 }, 1000);tween.start();

into this

var tween = new TWEEN.Tween(position).to({ x:200 }, 1000).start();

You'll see this a lot in the examples, soit's good to be familiar with it! Check04-simplest for a working example.

使用 tween.js 的动画

Animating with tween.js

Tween.js doesn't run by itself. You need totell it when to run, by explicitly calling theupdate method. The recommended method is to do this inside your mainanimation loop, which should be called with requestAnimationFrame for getting the best graphicsperformance:

We've seen this example before:

animate();function animate(){requestAnimationFrame(animate);// [...]TWEEN.update();// [...]}

If called without parameters,update will determine the current time inorder to find out how long has it been since the last time it ran.

However you can also pass an explicit timeparameter toupdate. Thus,

TWEEN.update(100);

means "update with time = 100milliseconds". You can use this to make sure that all the time-dependentfunctions in your code are using the very same time value. For example supposeyou've got a player and want to run tweens in sync. Youranimate code could look like this:

var currentTime =player.currentTime;TWEEN.update(currentTime);

We use explicit time values for the unittests. You can have a look atTestTweens to see how we call TWEEN.update()with different values in order to simulate time passing.

控制一个补间动画

Controlling a tween

启动和停止
start
 and stop

So far we've learnt about theTween.start method, but there are more methodsthat control individual tweens. Probably the most important one is the start counterpart: stop. If you want to cancel a tween, just callthis method over an individual tween:

tween.stop();

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

Thestart method also accepts a time 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 TWEEN.update).

更新
update

Individual tweens also have anupdate method---this is in fact calledby TWEEN.update. You generally don't need to call thisdirectly, but might be useful if you're doing crazy hacks.

链接
chain

Things get more interesting when yousequence different tweens in order, i.e. setup one tween to start once aprevious one has finished. We call thischaining tweens, and it's done withthe chain method. Thus, to make tweenB start after tweenA finishes:

tweenA.chain(tweenB);

Or, for an infinite chain, settweenA to start once tweenB finishes:

tweenA.chain(tweenB);tweenB.chain(tweenA);

CheckHello world to see an example ofthese infinite chains.


重复
repeat

If you wanted a tween to repeat forever youcould chain it to itself, but a better way is to use therepeat method. It accepts a parameter thatdescribes how many repetitions you want:

tween.repeat(10); // repeats 10 times and stopstween.repeat(Infinity); // repeats forever

Check theRepeat example.

摇摇乐
yoyo

This function only has effect if used alongwithrepeat. When active, the behaviour of the tweenwill be like a yoyo, i.e. it will bounce to and from the start and endvalues, instead of just repeating the same sequence from the beginning.

延迟
delay

More complex arrangements might requiredelaying a tween before it actually starts running. You can do that using thedelaymethod:

tween.delay(1000);tween.start();

will start executing 1 second after thestart method has been called.

控制所有的补间动画

Controlling 

all

 the tweens

The following methods are found in theTWEEN global object, and you generally won't need to use most of them, exceptforupdate.

TWEEN.update(time)

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

Iftime is notspecified, it will use the current time.

TWEEN.getAll and TWEEN.removeAll

Used to get a reference to the activetweens array and to remove all of them fromthe array with just one call, respectively.

TWEEN.add(tween) and TWEEN.remove(tween)

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

These methods are usually used internallyonly, but are exposed just in case you want to do somethingfunny.

修改 easing 功能(AKA make it councy)

Changing the easing function (AKA make itbouncy)

Tween.js will perform the interpolationbetween values (i.e. the easing) in a linear manner, so the change will bedirectly proportional to the elapsed time. This is predictable but also quiteuninteresting visually wise. Worry not--this behaviour can be easily changedusing theeasing method. For example:

tween.easing(TWEEN.Easing.Quadratic.In);

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

可用的 easing 函数

Available easing functions: TWEEN.Easing

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

Probably the names won't be saying anythingto you unless you're familiar with these concepts already, so it is probablythe time to check theGraphs example, which graphs all the curves in onepage so you can compare how they look at a glance.

Credit where credit is due: thesefunctions are derived from the original set of equations that Robert Pennergraciously made available as free software a few years ago, but have beenoptimised to play nicely with JavaScript.

使用自定义的 easing 函数

Using a custom easing function

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

·        itmust accept one parameter:

o   k: the easing progress, or how far alongthe duration of the tween we are. Allowed values are in the range [0, 1].

·        itmust return a value based on the input parameters.

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

easedElapsed = easing(k);for eachproperty:newPropertyValue = initialPropertyValue + propertyDelta *easedElapsed;

For the performance obsessed people outthere: the deltas are calculated only whenstart() is called on a tween.

So let's suppose you wanted to use a customeasing 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-ladderoutput:

function tenStepEasing(k) {return Math.floor(k* 10) / 10;}

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

tween.easing(tenStepEasing);

Check thegraphs for custom easingfunctions example to see this in action (and alsosome metaprogramming for generating step functions).

回调

Callbacks

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

For example, suppose you're trying to animatesome object whose properties can't be accessed directly but require you to calla setter instead. You can use anupdate callback to read the new updatedvalues and then manually call the setters:

var trickyObjTween = new TWEEN.Tween({       propertyA: trickyObj.getPropertyA(),        propertyB:trickyObj.getPropertyB()}) .to({ propertyA:100, propertyB: 200 })  .onUpdate(function() {               this.setA( this.propertyA);          this.setB(this.propertyB );  });

Or imagine you want to ensure the values ofan object are in an specific state each time the tween is started. You'llassign astartcallback:

var tween = new TWEEN.Tween(obj).to({ x:100 }).onStart(function() {this.x = 0;});

The scope for each callback is the tweenedobject.

启动时回调

onStart

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

停止时回调

onStop

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

更新时回调

onUpdate

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

完成时回调

onComplete

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

高级补间动画

Advanced tweening

相对值

Relative values

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

// This will make the `x` property be 100,alwaysvar absoluteTween = newTWEEN.Tween(absoluteObj).to({ x: 100 });// Suppose absoluteObj.x is 0 nowabsoluteTween.start(); // Makes x go to 100// Suppose absoluteObj.xis -100 nowabsoluteTween.start();// Makes x go to 100// In contrast...//This will make the `x` property be 100 units more,// relative to the actualvalue when it startsvar relativeTween = newTWEEN.Tween(relativeObj).to({ x: "+100" });// SupposerelativeObj.x is 0 nowrelativeTween.start();// Makes x go to 0 +100 = 100// SupposerelativeObj.x is -100 nowrelativeTween.start();// Makes x go to -100 +100 = 0

Check09_relative_values for anexample.

补间到数组值

Tweening to arrays of values

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

var tween = new TWEEN.Tween(relativeObj).to({x: [0, -100, 100] });

will makex gofrom its initial value to 0, -100 and 100.

The way these values are calculated is asfollows:

·        firstthe tween progress is calculated as usual

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

·        basedon the progress and the array of values, an interpolated value is generated

For example, when the tween has juststarted (progress is 0), the interpolation function will return the first valuein the array. When the tween is halfway, the interpolation function will returna value approximately in the middle of the array, and when the tween is at theend, the interpolation function will return the last value.

You can change the interpolation functionwith theinterpolation method. For example:

tween.interpolation(TWEEN.Interpolation.Bezier );

The following values are available:

·        TWEEN.Interpolation.Linear

·        TWEEN.Interpolation.Bezier

·        TWEEN.Interpolation.CatmullRom

The default isLinear.

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

Check06_array_interpolation for anexample.

获得最佳性能

Getting the best performance

While Tween.js tries to be performant onits 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 usingTween.js (or when animating in the web, in general).

使用高性能的 CSS

Use performant CSS

When you try to animate the position of an elementin the page, the easiest solution is to animate thetop and left style properties, like this:

var element = document.getElementById('myElement');var tween = new TWEEN.Tween({ top:0, left: 0 }).to({ top:100, left: 100 }, 1000).onUpdate(function() {element.style.top = this.top+ 'px';element.style.left = this.left+ 'px';});

but this is really inefficient becausealtering these properties forces the browser to recalculate the layout on eachupdate, and this is a very costly operation. Instead of using these, you shouldusetransform, which doesn't invalidate the layout andwill also be hardware accelerated when possible, like this:

var element = document.getElementById('myElement');var tween = new TWEEN.Tween({ top:0, left: 0 }).to({ top:100, left: 100 }, 1000).onUpdate(function() {element.style.transform ='translate(' + this.left + 'px, ' + this.top + 'px);';});

If you want to read more about this, have alook atthis article.

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

做好垃圾回收(别名 GC

Be good to the Garbage collector (alias theGC)

If you use anonUpdate callback, you need to be very careful with what you put on it. Thisfunction will be called many times per second, so if you're doing costlyoperations on each update, you might block the main thread and causehorrible jank, or---if your operations involve memory allocations, you'llend up getting the garbage collector to run too often, and cause jank too.So just don't do either of those things. Keep your onUpdate callbacks very lightweight, and besure to also use a memory profiler while you're developing.

超级补间动画

Crazy tweening

This is something you might not use often,but you can use the tweening equations outside of Tween.js. They're justfunctions, after all. So you could use them to calculate smooth curves as inputdata. For example, they're used to generate audio data inthis experiment.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值