ホームページ  >  記事  >  ウェブフロントエンド  >  tween.js 中国語使用ガイド

tween.js 中国語使用ガイド

小云云
小云云オリジナル
2018-01-08 09:24:335586ブラウズ

この記事では主に tween.js の詳細な中国語の使用ガイドを紹介します。編集者が非常に優れていると考えたので、参考として共有します。編集者をフォローして見てみましょう。皆さんのお役に立てれば幸いです。

トゥイーン (アニメーション) は、オブジェクトのプロパティをスムーズな方法で変更できるようにする概念です。どのプロパティを変更したいか、トゥイーンの実行が終了したときにどのような最終値を持つべきか、それにかかる時間はどれくらいかを指定するだけで、トゥイーン エンジンが開始点から開始点までの値を計算します。終点。

たとえば、位置オブジェクトには x と y の 2 つの座標があります:


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

x 座標の値を 100 から 200 に変更したい場合は、次のようにする必要があります:


// 首先为位置创建一个补间(tween)
var tween = new TWEEN.Tween(position);

// 然后告诉 tween 我们想要在1000毫秒内以动画的形式移动 x 的位置
tween.to({ x: 200 }, 1000);

一般的にこれだけでは十分ではありません。トゥイーンは作成されましたが、まだアクティブ化 (使用) されていません:


// 启动
tween.start();

最後に、このエフェクトを正常に完了するには、以下が必要です。 main 関数で TWEEN.update を呼び出すには、次のように使用します:


animate();

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

この方法では、各フレームを更新するときにトゥイーン アニメーションが実行され、1 秒 (1000 ミリ秒) 後にposition.x は 200 になります。

コンソールで x の値を出力しない限り、x の変化は確認できません。 onUpdate コールバックを使用するとよいでしょう:


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

ヒント: ここで object.x を取得できない場合があります。詳細については、前述したこの問題を参照してください。この関数はアニメーションが更新されるたびに呼び出されます。これがどのくらいの頻度で発生するかは、コンピューターやデバイスの速度 (およびビジー度) など、さまざまな要因によって決まります。

これまで、値をコンソールに出力するためにトゥイーン アニメーションのみを使用してきましたが、three.js オブジェクトと組み合わせることができます:

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);
}

この場合、three.js レンダラーはレンダリング前にオブジェクトの位置が確認されるため、明示的な onUpdate コールバックを使用する必要はありません。

また、何か違うことに気づくかもしれません: tween.js はチェーン内で呼び出すことができます。 すべてのトゥイーン関数はトゥイーン インスタンスを返すため、次のコードを書き換えることができます:

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

を次のように書き換えます:

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

ここにはたくさんの例があるので、よく理解しておくと良いでしょう。たとえば、04-simplest がその例です。

tween.js アニメーション

Tween.js は単独では実行されません。 update メソッドを明示的に呼び出して、いつ実行するかを指示する必要があります。推奨されるアプローチは、メイン アニメーション ループ内でこの操作を実行することです。グラフィックス パフォーマンスを最適化するには、requestAnimationFrame を使用してこのループを呼び出します。

たとえば、前の例:

animate();

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

呼び出し時にパラメータが渡されない場合、update は現在の時点を判断して、最後の実行からどれくらいの時間が経過したかを判断します。

もちろん、「更新時間 = 100 ミリ秒」を意味する update

TWEEN.update(100);

に明示的な時間パラメータを渡すこともできます。これを使用すると、コード内のすべての時間関連関数が同じ時間値を使用するようにすることができます。たとえば、プレーヤーがあり、トゥイーンを同期的に実行したいとします。 アニメーション関数は次のようになります:

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

単体テストには明示的な時間値を使用します。 testing.js の例を見ると、時間転送をシミュレートするためにさまざまな値を指定して TWEEN.update() を呼び出す方法がわかります。

トゥイーンの制御

開始と停止

これまで Tween.start メソッドを見てきましたが、単一のトゥイーンを制御する方法は他にもたくさんあります。 おそらく最も重要なものは star に相当する stop です。 トゥイーンをキャンセルしたい場合は、別のトゥイーンを通じてこのメソッドを呼び出すだけです:

tween.stop();

開始されていない、または停止されているトゥイーンを停止しても効果はありません。 エラーはスローされません。

start メソッドはパラメーター時間を受け入れます。これを使用すると、トゥイーンは特定の時点まですぐには開始されません。それ以外の場合は、できるだけ早く (つまり、次回 TWEEN.update が呼び出されたとき) 開始されます。

update

Tween にも update メソッドがあります --- これは実際には TWEEN.update によって呼び出されます。 通常、クレイジーなハッカーでない限り、これを直接呼び出す必要はありません。

チェーン

前のトゥイーンが終了するとすぐに別のトゥイーンを開始するなど、異なるトゥイーンをシーケンスすると、物事が面白くなります。これを連鎖トゥイーンと呼び、連鎖メソッドを使用して実行します。したがって、tweenB を tewwnA で開始させるには:

tweenA.chain(tweenB);

または、無限チェーンの場合は、tweenB が完了するとすぐに開始するように tweenA を設定します:

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

無限チェーンについては、Hello world を参照してください。

他の場合には、複数のトゥイーン (リンクされたトゥイーン) が同時にアニメーションを開始できるように、複数のトゥイーンを別のトゥイーンにリンクする必要がある場合があります:

tweenA.chain(tweenB,tweenC);

警告: tweenA.chain(tweenB) の呼び出し 実際には tweenA を変更したので tweenA tweenA が完了すると常に開始されます。 chain の戻り値は tweenA のみであり、新しいトゥイーンではありません。

リピート

如果你想让一个补间永远重复,你可以链接到自己,但更好的方法是使用 repeat 方法。 它接受一个参数,描述第一个补间完成后需要多少次重复


tween.repeat(10); // 循环10次
tween.repeat(Infinity); // 无限循环

补间的总次数将是重复参数加上一个初始补间。查看 Repeat。

yoyo

这个功能只有在独自使用 repeat 时才有效果。 活跃时,补间的行为将像 yoyo 一样,i.e 它会从起始值和结束值之间跳出,而不是从头开始重复相同的顺序。

delay

更复杂的安排可能需要在实际开始运行之前延迟补间。 你可以使用 delay 方法来做到这一点


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

将在调用启动方法后的1秒钟后开始执行。

控制所有补间

在 TWEEN 全局对象中可以找到以下方法,除了 update 之外,通常不需要使用其中的大部分对象。

TWEEN.update(time)

我们已经讨论过这种方法。 它用于更新所有活动的补间。

如果 time 不指定,它将使用当前时间。

TWEEN.getAll and TWEEN.removeAll

用于获取对活动 tweens 数组的引用,并分别仅从一个调用中将它们全部从数组中删除

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

用于将补间添加到活动补间的列表,或者分别从列表中删除特定的补间。

这些方法通常只在内部使用,但是如果您想要做一些有趣的事情,则会被暴露。

控制补间组

使用 TWEEN 单例来管理补间可能会导致包含许多组件的大型应用程序出现问题。 在这些情况下,您可能希望创建自己的更小的补间组。

示例:交叉组件冲突

如果使用 TWEEN 有多个组件,并且每个组件都想管理自己的一组补间,则可能发生冲突。 如果一个组件调用 TWEEN.update() 或 TWEEN.removeAll(),则其他组件的补间也将被更新或删除。

创建你自己的补间组

为了解决这个问题,每个组件都可以创建自己的 TWEEN.Group 实例(这是全局的 TWEEN 对象在内部使用的)。 实例化新的补间时,可以将这些组作为第二个可选参数传入:


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(); // 只更新tweenA
groupB.update(); // 只更新tweenB
TWEEN.update(); // 只更新tweenC

groupA.removeAll(); // 只移除tweenA
groupB.removeAll(); // 只移除tweenB
TWEEN.removeAll(); // 只移除tweenC

通过这种方式,每个组件都可以处理创建,更新和销毁自己的一组补间。

改变缓动功能

Tween.js 将以线性方式执行值之间的插值(即缓动),所以变化将与流逝的时间成正比。 这是可以预见的,但在视觉上也是相当无趣的。 不要担心 - 使用缓动方法可以轻松更改此行为。 例如:


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

这将导致缓慢地开始向最终值变化,向中间加速,然后迅速达到其最终值,相反,TWEEN.Easing.Quadratic.Out 一开始会加速,但随着值的接近最终放缓。

可用的缓动函数:TWEEN.Easing

tween.js提供了一些现有的缓动功能。它们按照它们表示的方程式进行分组:线性,二次,三次,四次,五次,正弦,指数,圆形,弹性,背部和弹跳,然后是缓动型:In,Out和InOut。

除非您已经熟悉这些概念,否则这些名称可能不会对您说什么,所以您可能需要查看 Graphs 示例,该示例将一个页面中的所有曲线进行图形化,以便比较它们如何看待一瞥。

这些功能是从 Robert Penner 慷慨地提供几年前作为自由软件提供的原始方程派生而来的,但是已经被优化以便与JavaScript很好地发挥作用。

使用自定义缓动功能

您不仅可以使用任何现有的功能,还可以提供您自己的功能,只要遵循一些约定即可:

它必须接受一个参数:

k: 缓动过程,或我们的补间所处的时间有多长。允许的值在[0,1]的范围内。

它必须根据输入参数返回一个值。

不管要修改多少个属性,easing函数在每次更新时只调用一次。 然后将结果与初始值以及这个值和最终值之间的差值(delta)一起使用,就像这个伪代码一样:


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

对于更注重性能表现的人来说:只有在补间上调用 start() 时才会计算增量值。

因此,让我们假设您想使用一个缓解值的自定义缓动函数,但是将 Math.floor 应用于输出,所以只返回整数部分,从而产生一种梯级输出:


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

你可以通过简单地调用它的缓动方法来使用它,就像我们之前看到的那样:


tween.easing(tenStepEasing);

查看 graphs for custom easing functions 示例,以查看这个动作(还有一些用于生成步进函数的元编程)。

回调函数

另一个强大的特性是能够在每个补间的生命周期的特定时间运行自己的功能。 当更改属性不够时,通常需要这样做。

例如,假设你正在试图给一些不能直接访问属性的对象设置动画,但是需要你调用setter。 您可以使用 update 回调来读取新的更新值,然后手动调用setters。 所有的回调函数都将补间对象作为唯一的参数。


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 );
 });

或者想象一下,当一个补间开始时,你想播放声音。你可以使用 start 回调:


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

每个回调的范围是补间对象--在这种情况下,是 obj。

onStart

在补间开始之前执行--i.e. 在计算之前。每个补间只能执行一次,i.e. 当通过 repeat() 重复补间时,它将不会运行。

同步到其他事件或触发您要在补间启动时发生的操作是非常好的。

补间对象作为第一个参数传入。

onStop

当通过 stop() 显式停止补间时执行,但在正常完成时并且在停止任何可能的链补间之前执行补间。

补间对象作为第一个参数传入。

onUpdate

每次补间更新时执行,实际更新后的值。

补间对象作为第一个参数传入。

onComplete

当补间正常完成(即不停止)时执行。

补间对象作为第一个参数传入。

高级补间

相对值

使用 to 方法时,也可以使用相对值。 当tween启动时,Tween.js将读取当前属性值并应用相对值来找出新的最终值。

但是你需要使用引号,否则这些值将被视为绝对的。 我们来看一个例子:


// This will make the `x` property be 100, always
var absoluteTween = new TWEEN.Tween(absoluteObj).to({ x: 100 });

// Suppose absoluteObj.x is 0 now
absoluteTween.start(); // Makes x go to 100

// Suppose absoluteObj.x is -100 now
absoluteTween.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 starts
var relativeTween = new TWEEN.Tween(relativeObj).to({ x: "+100" });

// Suppose relativeObj.x is 0 now
relativeTween.start(); // Makes x go to 0 +100 = 100

// Suppose relativeObj.x is -100 now
relativeTween.start(); // Makes x go to -100 +100 = 0

查看09_relative_values 示例。

补间值的数组

除了补间为绝对值或相对值之外,还可以让Tween.js跨一系列值更改属性。 要做到这一点,你只需要指定一个数组的值,而不是一个属性的单个值。 例如:


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

将使 x 从初始值变为0,-100和100。

这些值的计算方法如下:

  1. 首先,补间进度如常计算

  2. 进度(从0到1)用作插值函数的输入

  3. 基于进度和值的数组,生成内插值

例如,当补间刚刚启动(进度为0)时,插值函数将返回数组中的第一个值。 当补间到一半时,插值函数将返回一个大约在数组中间的值,当补间结束时,插值函数将返回最后一个值。

您可以使用插值方法更改插值函数。 例如:


tween.interpolation( TWEEN.Interpolation.Bezier );

以下值可用:

  1. TWEEN.Interpolation.Linear

  2. TWEEN.Interpolation.Bezier

  3. TWEEN.Interpolation.CatmullRom

默认是 Linear。

请注意,插值函数对于与同一补间中的数组进行补间的所有属性是全局的。
您不能使用数组和线性函数进行属性A的更改,也不能使用相同的补间进行数组B的属性B和Bezier函数的更改; 您应该使用运行在同一对象上的两个补间对象,但修改不同的属性并使用不同的插值函数。

查看 06_array_interpolation 示例。

获得最佳性能

虽然Tween.js试图自己执行,但是没有什么能够阻止你以一种反作用的方式使用它。 这里有一些方法可以避免在使用Tween.js时(或者在网页中进行动画制作时)减慢项目速度。

使用高性能的CSS

当您尝试在页面中设置元素的位置时,最简单的解决方案是为 top 和 left 属性设置动画,如下所示:


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';
 });

但这实际上是效率低下的,因为改变这些属性会迫使浏览器在每次更新时重新计算布局,这是非常昂贵的操作。 相反的,您应该使用 transform,这不会使布局无效,并且在可能的情况下也将被硬件加速,比如:


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);';
 });

但是,如果您的动画需求非常简单,那么在适用的情况下使用CSS动画或转换可能会更好,以便浏览器尽可能优化。
当您的动画需要涉及复杂的布局时,Tween.js是非常有用的,也就是说,您需要将多个补间同步到一起,在完成一些动作之后,循环多次等等。

对垃圾收集器(别名GC)

onUpdate コールバック関数を使用する場合は、非常に注意して使用する必要があります。 この関数は 1 秒間に何度も呼び出されるため、各更新に多額のコストがかかる場合、メイン スレッドがブロックされてひどい結果が生じる可能性があります。また、操作にメモリ割り当てやガベージ コレクションが含まれる場合、サーバーを頻繁に実行しすぎると問題が発生する可能性があります。 したがって、これらのことのうちの 1 つだけは行わないでください。 onUpdate コールバックを非常に軽量にし、開発中もメモリ プロファイラーを必ず使用してください。

Crazy Tweens

これはあまり使用しないかもしれませんが、Tween.js の外部でトゥイーン式を使用できます。 結局のところ、それらは単なる関数です。 したがって、これらを使用して、入力データとして滑らかな曲線を計算できます。

たとえば、この実験では音声データを生成するために使用されました。

関連する推奨事項:

tween.jsの使用の詳細な例

簡単なアニメーションライブラリのカプセル化tween.jsのサンプルチュートリアル

Tween.jsアニメーションの詳細な紹介

以上がtween.js 中国語使用ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。