Skip to content

Tween Animation

The Tween system animates entity properties over time — position, scale, rotation, color, size, and camera ortho size. The AnimationPlugin is included by the engine by default.

Basic Usage

Use Tween.to() to animate a property from one value to another:

import { Tween, TweenTarget } from 'esengine';
// Move entity to x=200 over 1 second
Tween.to(entity, TweenTarget.PositionX, 0, 200, 1.0);
// Fade out sprite over 0.5 seconds
Tween.to(entity, TweenTarget.ColorA, 1, 0, 0.5);
// Scale up over 0.3 seconds
Tween.to(entity, TweenTarget.ScaleX, 1, 2, 0.3);
Tween.to(entity, TweenTarget.ScaleY, 1, 2, 0.3);

Parameters

Tween.to(entity, target, from, to, duration, options?)
ParameterTypeDescription
entityEntityTarget entity
targetTweenTargetProperty to animate
fromnumberStart value
tonumberEnd value
durationnumberDuration in seconds
optionsTweenOptionsOptional easing, delay, loop config

Tween Targets

TargetProperty
PositionXTransform position X
PositionYTransform position Y
PositionZTransform position Z
ScaleXTransform scale X
ScaleYTransform scale Y
RotationZTransform rotation around Z axis (radians)
ColorRSprite color red (0–1)
ColorGSprite color green (0–1)
ColorBSprite color blue (0–1)
ColorASprite color alpha (0–1)
SizeXSprite width
SizeYSprite height
CameraOrthoSizeCamera orthographic size

Easing

Pass an easing option to control the animation curve:

import { Tween, TweenTarget, EasingType } from 'esengine';
Tween.to(entity, TweenTarget.PositionX, 0, 100, 1.0, {
easing: EasingType.EaseOutCubic,
});

Available Easing Types

EasingDescription
LinearConstant speed (default)
EaseInQuadSlow start, accelerating
EaseOutQuadFast start, decelerating
EaseInOutQuadSlow start and end
EaseInCubicSlow start, steeper acceleration
EaseOutCubicFast start, steeper deceleration
EaseInOutCubicSmooth start and end
EaseInBackPulls back before moving forward
EaseOutBackOvershoots then settles
EaseInOutBackPull back + overshoot
EaseInElasticElastic wind-up
EaseOutElasticElastic settle
EaseInOutElasticElastic both ends
EaseOutBounceBouncing settle
CubicBezierCustom curve via control points
StepInstant jump (no interpolation)

Custom Bezier Curve

Use CubicBezier easing with .bezier() to define a custom curve:

Tween.to(entity, TweenTarget.PositionX, 0, 100, 1.0, {
easing: EasingType.CubicBezier,
}).bezier(0.25, 0.1, 0.25, 1.0);

Delay

Start a tween after a delay:

Tween.to(entity, TweenTarget.ColorA, 1, 0, 0.5, {
delay: 1.0, // wait 1 second before fading
});

Looping

import { Tween, TweenTarget, LoopMode } from 'esengine';
// Loop forever (ping-pong)
Tween.to(entity, TweenTarget.PositionY, 0, 50, 2.0, {
loop: LoopMode.PingPong,
});
// Loop 3 times then stop
Tween.to(entity, TweenTarget.ScaleX, 1, 1.5, 0.5, {
loop: LoopMode.Restart,
loopCount: 3,
});
ModeBehavior
NonePlays once (default)
RestartResets to start value and replays
PingPongReverses direction each iteration

Set loopCount to limit iterations. Omit it for infinite looping.

Sequencing

Chain tweens so they play one after another with .then():

const moveRight = Tween.to(entity, TweenTarget.PositionX, 0, 100, 1.0);
const moveDown = Tween.to(entity, TweenTarget.PositionY, 0, 100, 1.0);
moveRight.then(moveDown);

Or chain fluently:

Tween.to(entity, TweenTarget.PositionX, 0, 100, 1.0)
.then(Tween.to(entity, TweenTarget.PositionY, 0, 100, 1.0));

Controlling Tweens

Tween.to() returns a TweenHandle for runtime control:

const handle = Tween.to(entity, TweenTarget.PositionX, 0, 100, 2.0);
handle.pause(); // pause
handle.resume(); // resume
handle.cancel(); // cancel and remove
// Check state
if (handle.state === TweenState.Running) {
// still animating
}

TweenState

StateMeaning
RunningCurrently animating
PausedPaused, can resume
CompletedFinished playing
CancelledCancelled, will be removed

Cancelling Tweens

Cancel a single tween or all tweens on an entity:

import { Tween } from 'esengine';
// Cancel one
handle.cancel();
// Cancel all tweens on an entity
Tween.cancelAll(entity);

Custom Property Animation

Use Tween.value() to animate any numeric value with a callback:

import { Tween, EasingType } from 'esengine';
// Animate a custom property
const handle = Tween.value(0, 100, 1.0, (v) => {
health.hp = v;
}, { easing: EasingType.EaseOutQuad });
// Supports all tween features
handle.pause();
handle.resume();
handle.cancel();

Parameters

Tween.value(from, to, duration, callback, options?)
ParameterTypeDescription
fromnumberStart value
tonumberEnd value
durationnumberDuration in seconds
callback(value: number) => voidCalled each frame with the interpolated value
optionsTweenOptionsOptional easing, delay, loop config

Custom Bezier Curve

Use CubicBezier easing with .bezier() on value tweens:

Tween.value(0, 100, 1.0, (v) => { progress = v; }, {
easing: EasingType.CubicBezier,
}).bezier(0.25, 0.1, 0.25, 1.0);

Sequencing with Built-in Tweens

Value tweens can be chained with built-in property tweens using .then():

// Move entity, then animate custom value
Tween.to(entity, TweenTarget.PositionX, 0, 100, 1.0)
.then(Tween.value(0, 1, 0.5, (v) => { shield.opacity = v; }));
// Animate custom value, then scale entity
Tween.value(0, 360, 1.0, (v) => { rotation = v; })
.then(Tween.to(entity, TweenTarget.ScaleX, 1, 2, 0.5));

Looping Value Tweens

import { Tween, LoopMode } from 'esengine';
// Infinite ping-pong
Tween.value(0, 1, 2.0, (v) => { pulse = v; }, {
loop: LoopMode.PingPong,
});
// Loop 3 times
Tween.value(0, 360, 1.0, (v) => { angle = v; }, {
loop: LoopMode.Restart,
loopCount: 3,
});