Giter Club home page Giter Club logo

playcanvas-tween's Introduction

Overview

This is a tween library for PlayCanvas. You can include tween.js in your Project to start using the library.

If you create your application after loading this library, you can call the following method to enable tweening on your application:

app.addTweenManager();

Usage

Tweening pc.Entity properties looks like this:

var tween = entity.tween(fromProperty).to(toProperty, duration, easing);
tween.start();

For example, this tweens the entity's local position with duration 1.0 and SineOut easing:

var tween = entity.tween(entity.getLocalPosition()).to({x: 10, y: 0, z: 0}, 1.0, pc.SineOut);
tween.start();

If you are dealing with rotations you should use rotate instead of to. This takes euler angles and uses an internal quaternion or it can take quaternions to slerp between angles. For example:

entity.tween(entity.getLocalEulerAngles()).rotate({x: 0, y: 180, z: 0}, 1.0, pc.Linear);
entity.tween(entity.getLocalRotation()).rotate(targetQuaternionRotation, 1.0, pc.Linear);

You can also tween properties of any other object not just entities. For example:

// some object with a property called 'value'
var data = {
    value: 0
};

// create a new tween using pc.Application#tween
// passing another object as the target. Any properties
// that are common between the target and the source object
// will be tweened
app.tween(data).to({value: 1}, 1.0, pc.BackOut);

Chaining

You can chain method calls for a tween. For example:

// delay, yoyo and loop tween
entity
.tween(entity.getLocalPosition()).to({x: 10, y: 0, z: 0}, 1.0, pc.SineOut)
.delay(1.0)
.yoyo(true)
.loop(true)
.start();

Methods

start()

To start playing a tween call tween.start().

stop()

To stop a tween call tween.stop().

pause()

To pause a tween call tween.pause().

resume()

To resume a paused tween call tween.resume().

delay(duration)

To delay a tween call tween.delay(duration) where duration is in seconds.

repeat(count)

To repeat a tween count times call tween.repeat(count).

loop(true / false)

To loop a tween forever call tween.loop(true).

yoyo(true / false)

To make a tween play in reverse after it finishes call tween.yoyo(true). Note that to actually see the tween play in reverse in the end, you have to either repeat the tween at least 2 times or set it to loop forever. E.g. to only play a tween from start to end and then from end to start 1 time you need to do:

tween.yoyo(true).repeat(2);

reverse()

To reverse a tween call tween.reverse().

Events

To subscribe to events during Tween execution, use a these methods:

onUpdate

This is called on every update cycle. You can use this method to manually update something in your code using the tweened value. It provides dt argument.

E.g.

var color = new pc.Color(1, 0, 0);

var tween = app.tween(color).to(new pc.Color(0, 1, 1), 1, pc.Linear);
tween.onUpdate((dt) => {
    material.diffuse = color;
    material.update();
});

onComplete

This is called when the tween is finished. If the tween is looping the onLoop will be called instead.

E.g.

entity
.tween(entity.getLocalPosition())
.to({x: 10, y: 0, z: 0}, 1, pc.Linear)
.onComplete(() => {
   console.log('tween completed');
});

onLoop

This is called whenever a looping tween finishes a cycle. This is called instead of the onComplete for looping tweens.

E.g.

entity
.tween(entity.getLocalPosition())
.to({x: 10, y: 0, z: 0}, 1, pc.Linear)
.loop(true)
.onLoop(() => {
   console.log('tween loop');
});

Easing methods

There are various easing methods you can use that change the way that values are interpolated. The available easing methods are:

  • pc.Linear
  • pc.QuadraticIn
  • pc.QuadraticOut
  • pc.QuadraticInOut
  • pc.CubicIn
  • pc.CubicOut
  • pc.CubicInOut
  • pc.QuarticIn
  • pc.QuarticOut
  • pc.QuarticInOut
  • pc.QuinticIn
  • pc.QuinticOut
  • pc.QuinticInOut
  • pc.SineIn
  • pc.SineOut
  • pc.SineInOut
  • pc.ExponentialIn
  • pc.ExponentialOut
  • pc.ExponentialInOut
  • pc.CircularIn
  • pc.CircularOut
  • pc.CircularInOut
  • pc.BackIn
  • pc.BackOut
  • pc.BackInOut
  • pc.BounceIn
  • pc.BounceOut
  • pc.BounceInOut
  • pc.ElasticIn
  • pc.ElasticOut
  • pc.ElasticInOut

Tutorial

You can find a tutorial with various use cases here.

playcanvas-tween's People

Contributors

attackgoat avatar daredevildave avatar e-strokov avatar epreston avatar leonidaspir avatar lexxik avatar maksims avatar matteobartalinisc avatar mvaligursky avatar nikitaosyak avatar vkalpias avatar vmwxiong avatar willeastcott avatar yaustar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

playcanvas-tween's Issues

An arbitrary sequence of signals cause Tween to enter invalid state.

Description

There is no validation against invalid command sequence e.g. stop/resume will enter 'playing' and 'stopped' state. Moreover, restarting Tween adds it to the manager second time.

Steps to Reproduce

  1. Create Tween and 'start' it.
  2. Apply 'stop/start' or 'pause/start' or 'stop/resume' commands.
  3. As result Tween is added to manager twice and/or internal state is broken.

tween opacity

It would be nice if you were able to tween values on 2D elements like opacity. This would make UI elements much easier to subtly animate a bit. I'm aware you can do this by wrapping the opacity within an object but it seems like an unnecessary work around within each project.

[Feature Request] Add delay event

We can delay a tween call but there is no event when the delay ends, which makes the method not so useful. Usually when you want to delay a tween, it's to do something before starting. Since there is no event for delay, I still need to use setTimeout...

Chaining and Rotation

Hey!

I am having LOADS of trouble with this. I have an object that I set a local rotation on (180 deg on the Y) and I want to do a "turn" tween (+/-20deg and then reverse it).

dir is either 1 or -1 to signify rotation.

this.car.tween(this.car.getLocalRotation()).rotate({y: (20*dir)}, 0.1, pc.QuadraticInOut).yoyo(true).repeat(2).start(); will make the proper "turn" tween, but will start and end the car in the 0 Ydeg position, not the 180 Ydeg like previously set.

I then set out to do chaining, but the syntax is unclear. I want to do this: this.car.tween(this.car.getLocalRotation()).rotate({y: (20*dir)}, 0.1, pc.QuadraticInOut).start(); followed by this.car.tween(this.car.getLocalRotation()).rotate({y: (0)}, 0.2, pc.BackOut).start();, the .chain() method doesn't seem to work well... What would the syntax look like for this?

Stopping chained tweens?

We changed stop in tween.js to this, to stop all tweens in a chain:

        stop: function () {
            if ( !this._chained ) {
                this.playing = false;
                this.stopped = true;
            }
            else {
                // Chained.  Iterate, tracking what we've seen (to avoid infinite loops).
                // Could use a chase-pointer, but the list is likely to
                // be short, and we'll avoid extra stops this way,
                // but likely take extra GC load due to the array.
                var seen = [];
                for ( var cur = this; cur && seen.indexOf(cur) === -1; cur = cur._chained ) {
                    cur.playing = false;
                    cur.stopped = true;
                    seen.push( cur );
                }                
            }
        },

Posting this more or less as a "Request for Comment".

We ran into a few cases where devs assumed stopping the head of a chain would stop the rest, and bugs resulted. I could see arguing for a separate stopChain or similar, and the singly-linked nature of the chain makes the prospect of stopping something mid-chain a little wonky, so -- not sure what I think about this generally. But we're likely to ship with it for at least one game, so it seemed worth bumping upstream for comment.

Rotation only supports euler angles?

This works (getLocalEulerAngles with rotate):

        obj.tween( obj.getLocalEulerAngles() )
            .rotate( dst.getLocalEulerAngles(), duration, pc.Linear )
            .start();

...and this does not work (getLocalRotation with rotate):

        obj.tween( obj.getLocalRotation() )
            .rotate( dst.getLocalRotation(), duration, pc.Linear )
            .start();

In our experiments the latter would result in rotation being effectively 0,0,0 at all times.

While it appears that the rotate function understands pc.Quat, the start function's if (this._slerp) clauses assume Euler angles when setting both _fromQuat and _toQuat.

It also seems that it may be desirable to skip the // increment property work entirely in update when _this.slerp is true, in favor of the later this._quat.slerp that happens just after.

(Might try to provide a PR for this at some point but we're on a heck of a deadline, and switching over to getLocalEulerAngles worked, so just leaving this issue here for now for anyone who trips over it. May be related to some of the troubles expressed in issue #1.)

ESM Support

This library is not compatible with ESM and should be updated to allow importing in ESM Scripts.

Something like

import { init } from 'playcanvas-tween;

init(this.entity)
this.entity.tween()

Additional option to tween by speed

It would be nice if we could pass a speed parameter for tweening instead of duration. It would be useful if you want to move from point x to point y at a constant speed regardless of the distance of said points. With only the duration, a movement tween can happen faster or slower depending on the distance between point x and point y.

Leaking entities when you don't clean up your tweens

We've built a couple of scenes with tween-driven animations etc; some on delays, some looping.

If the user skips or otherwise causes the scene to change early, the tween.entity links can keep the entities alive despite our scene changer calling pc.app.root.findByName('Root').destroy().

We've put a canary into Tween's update method to help us find these (and clean them up, although this is later than desired):

        update: function (dt) {
            if (this.stopped) return false;

            // 1P PATCH
            if ( this.entity && ! this.entity.parent ) {
                console.error( "Tween on unparented entity, likely leak (stopping tween): " + this.entity.name + ", guid: " + this.entity.getGuid() );
                return false;
            }            

But this requires the fix at playcanvas/engine#994 to set _parent = null as a canary, and it might be the case that one would have a legit reason to keep a tween on an unparented/unenabled/etc entity (although no good reason for a destroyed entity, presumably -- we just don't know how to tell them apart).

Is there a good pattern for removing these? I notice as Element and Screen went into the mainline there have been some event handlers for removed-style events that we might listen to? Would love some input on an approach, and we might even have time to convert it into a PR as a starting point. =)

Thanks!

[Feature Request] Tween arrays and other things

Currently, you can not tween arrays. For example, the following code won't work

var from = {arr : [0, 0]};
this.app.tween(from).to({ar: [1, 1]}, 1, pc.SineOut);

Instead, you have to do

var from = {val1: 0,val2: 0};
this.app.tween(from).to({val1: 1, val2: 1}, 1, pc.SineOut);

The following doesn't work either

var from = {
    myVec1: new pc.Vec4(1, 0.5, 1, 0.5),
    myVec2: new pc.Vec4(1, 0.5, 1, 0.5),
};

It seems that playcanvas-tween can only tween properties that are numbers when using objects. Anything more complex won't work.

Loading this library before creating an app

Creating an app may not always happen before loading playcanvas-tween. In those cases, the integration of the library with the app does not happen, which is problematic. I am dealing with a project that has PlayCanvas for only a part of the full project, as it uses simple DOM UI on the outside before entering the game world. In that case, I run into this race condition.

It would be so nice if this tween library could automatically register itself on any new app when the app gets created, just like how PlayCanvas already does actions like this when things are available (asset loading, etc).

Alternatively, perhaps expose the integration in some way so I can trigger it myself?

"Uncaught TypeError: this.easing is not a function" when project is opened

We've been running into an issue where early in our project tween.js will throw this error. The type of tween doesn't seem to have an impact on whether or not it is caused, and it happens from different points in the project at different times, but only ever once. Tweening in the project continues to work fine after this error is thrown. Directly before the error is called this.easing is equal to 1, but before and after this it is equal to the function that it should be. Any ideas why this might be happening?

Uncaught TypeError: this.easing is not a function update https://launch.playcanvas.com/api/assets/files/Scripts/tween.js?id=62419280&branchId=b564d77a-3d99-4d47-be12-b5442499d0bb:368 update https://launch.playcanvas.com/api/assets/files/Scripts/tween.js?id=62419280&branchId=b564d77a-3d99-4d47-be12-b5442499d0bb:24 addTweenManager https://launch.playcanvas.com/api/assets/files/Scripts/tween.js?id=62419280&branchId=b564d77a-3d99-4d47-be12-b5442499d0bb:675 fire https://launch.playcanvas.com/editor/scene/js/engine/playcanvas.dbg.js?version=1.52.6:759 update https://launch.playcanvas.com/editor/scene/js/engine/playcanvas.dbg.js?version=1.52.6:72251 makeTick https://launch.playcanvas.com/editor/scene/js/engine/playcanvas.dbg.js?version=1.52.6:72834 tween.js:368:26
image

Tweens are not working when playcanvas is in background

We are making a game in which we are updating entity's position and rotations using tween library using the following code.

//for position
let moveT = this.entity.tween(this.entity.getLocalPosition()).to({x: finalPos.x, y: finalPos.y, z: finalPos.z}, isInstant ? 0 : this.moveDuration, pc.CubicInOut)
                    .delay(isDelayed ? this.moveDelay * cardNumber : 0)
                    .on('complete', function(){
                    });
                    
    moveT.start();

//for rotation
this.entity.tween(this.entity.getLocalEulerAngles()).rotate(this.frontrotation, rotationDuration, pc.Linear)
            .start()
            .on('update', function (dt) {
          
            })
            .on('complete', function () {
            });

And the both of the functions are executed after a settimeout call.
Now the issue is when we are putting playcanvas in background, the tweens are not working.
and when the playcanavas is moved to foreground only the rotation tween works and position tween doesn't works.
Can anyone help me out here?
thanks.

Generate typescript definitions

This issue tracker is only for bug reports and feature requests. For general support/help, visit https://forum.playcanvas.com

For bug reports, include:

Description

Provide as much information as possible. Include (where applicable):

  • URL to a simple, reproducible test case that illustrates the problem clearly
  • Screenshots
  • The platform(s)/browser(s) where the issue is seen

Steps to Reproduce

options.element buggy?

Hi there,

I was looking to use this library, and was just skimming through the code base. I noticed this line of code that I'm pretty sure is a bug. options.element is being passed in, but element (not options.element) is then used. It seems element is not even defined (I doubt this code passes a lint test).

So, someone (who actually uses this library already) will probably want to have a look at this?

Snippet:

if (options && options.element) {
  // specifiy a element property to be updated
  tween.element = element; // <----- should this not be options.element?
}

[Feature Request] Delay between Loop Cycles

I'd like to have the ability to specify a delay between loop cycles.

Currently we are achieving this within the callback similar to:

.on("loop", () => 
    { this.movementTween.pause();
        this.timeOut = setTimeout(() =>
        {
            this.movementTween.resume();
        }, this.movementDelay * 1000.0);
    })

But this is quite hacky. Would prefer to have a .loopDelay(seconds) method instead.

Installing this repository via NPM fails: premature close

Description

Attempting to install this repository directly via NPM fails due to invalid JSON (a trailing comma).

Steps to Reproduce

  1. Attempt to install: npm i github:playcanvas/playcanvas-tween
  2. Error produced: npm ERR! premature close

Tween doesn't stop when entity is disabled

Update function processed even when entity is disabled.

entity
    .tween(entity.getLocalPosition())
    .to({x: 10, y: 0, z: 0}, 1.0, pc.SineOut)
    .loop(true)
    .yoyo(true)
    .on('update', function () {
            console.log('update')
        })
    .start();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.