or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation.mdapplication.mdassets.mddisplay-objects.mdevents.mdfilters.mdgraphics.mdindex.mdmath.mdrendering.mdtext.mdtextures.mdutils.md

animation.mddocs/

0

# Animation and Ticker

1

2

Animation system with frame-rate independent timing, ticker management, and sprite animation utilities. The ticker system provides the foundation for smooth animations and frame-based updates.

3

4

## Capabilities

5

6

### Ticker System

7

8

Core animation timing system with frame-rate independent updates.

9

10

```typescript { .api }

11

/**

12

* Ticker system for animation timing

13

*/

14

class Ticker extends EventEmitter {

15

constructor();

16

17

/** Is ticker started */

18

started: boolean;

19

20

/** Animation speed multiplier */

21

speed: number;

22

23

/** Delta time since last frame */

24

readonly deltaTime: number;

25

26

/** Delta time in milliseconds */

27

readonly deltaMS: number;

28

29

/** Elapsed time since last frame */

30

readonly elapsedMS: number;

31

32

/** Last frame timestamp */

33

readonly lastTime: number;

34

35

/** Minimum FPS before deltaTime clamping */

36

minFPS: number;

37

38

/** Maximum FPS cap */

39

maxFPS: number;

40

41

/** Target frames per second */

42

readonly FPS: number;

43

44

/**

45

* Add callback to ticker

46

* @param fn - Callback function

47

* @param context - Callback context

48

* @param priority - Execution priority

49

* @returns This ticker

50

*/

51

add(fn: TickerCallback, context?: any, priority?: UPDATE_PRIORITY): this;

52

53

/**

54

* Add callback to run once

55

* @param fn - Callback function

56

* @param context - Callback context

57

* @param priority - Execution priority

58

* @returns This ticker

59

*/

60

addOnce(fn: TickerCallback, context?: any, priority?: UPDATE_PRIORITY): this;

61

62

/**

63

* Remove callback from ticker

64

* @param fn - Callback function

65

* @param context - Callback context

66

* @returns This ticker

67

*/

68

remove(fn: TickerCallback, context?: any): this;

69

70

/**

71

* Start ticker

72

*/

73

start(): void;

74

75

/**

76

* Stop ticker

77

*/

78

stop(): void;

79

80

/**

81

* Destroy ticker

82

*/

83

destroy(): void;

84

85

/**

86

* Update ticker manually

87

* @param currentTime - Current timestamp

88

*/

89

update(currentTime?: number): void;

90

91

/** Shared ticker instance */

92

static readonly shared: Ticker;

93

94

/** System ticker (used by Application) */

95

static readonly system: Ticker;

96

}

97

98

/**

99

* Ticker callback function

100

*/

101

type TickerCallback = (ticker: Ticker) => void;

102

103

/**

104

* Update priorities for ticker callbacks

105

*/

106

enum UPDATE_PRIORITY {

107

INTERACTION = 50,

108

HIGH = 25,

109

NORMAL = 0,

110

LOW = -25,

111

UTILITY = -50

112

}

113

```

114

115

### Ticker Listener

116

117

Individual ticker listener management.

118

119

```typescript { .api }

120

/**

121

* Ticker listener for individual callback management

122

*/

123

class TickerListener {

124

constructor(fn: TickerCallback, context?: any, priority?: number, once?: boolean);

125

126

/** Callback function */

127

fn: TickerCallback;

128

129

/** Callback context */

130

context: any;

131

132

/** Execution priority */

133

priority: number;

134

135

/** Run once flag */

136

once: boolean;

137

138

/** Next listener in chain */

139

next: TickerListener;

140

141

/** Previous listener in chain */

142

previous: TickerListener;

143

144

/** Is destroyed */

145

destroyed: boolean;

146

147

/**

148

* Match function and context

149

* @param fn - Function to match

150

* @param context - Context to match

151

* @returns True if matches

152

*/

153

match(fn: TickerCallback, context?: any): boolean;

154

155

/**

156

* Emit callback

157

* @param ticker - Ticker instance

158

* @returns Next listener

159

*/

160

emit(ticker: Ticker): TickerListener;

161

162

/**

163

* Connect to another listener

164

* @param previous - Previous listener

165

*/

166

connect(previous: TickerListener): void;

167

168

/**

169

* Destroy listener

170

*/

171

destroy(): void;

172

}

173

```

174

175

### Animated Sprite

176

177

Sprite class with built-in texture-based animation support.

178

179

```typescript { .api }

180

/**

181

* Animated sprite with texture frame animation

182

*/

183

class AnimatedSprite extends Sprite {

184

constructor(textures: Texture[] | FrameObject[], autoUpdate?: boolean);

185

186

/** Animation textures/frames */

187

textures: Texture[] | FrameObject[];

188

189

/** Current frame index */

190

currentFrame: number;

191

192

/** Animation speed (frames per second at 60 FPS) */

193

animationSpeed: number;

194

195

/** Loop animation */

196

loop: boolean;

197

198

/** Update anchor with frames */

199

updateAnchor: boolean;

200

201

/** Callback when animation completes */

202

onComplete: () => void;

203

204

/** Callback when frame changes */

205

onFrameChange: (currentFrame: number) => void;

206

207

/** Callback when animation loops */

208

onLoop: () => void;

209

210

/** Total number of frames */

211

readonly totalFrames: number;

212

213

/** Is animation playing */

214

readonly playing: boolean;

215

216

/**

217

* Start playing animation

218

*/

219

play(): void;

220

221

/**

222

* Stop animation

223

*/

224

stop(): void;

225

226

/**

227

* Go to specific frame and play

228

* @param frameNumber - Frame to go to

229

*/

230

gotoAndPlay(frameNumber: number): void;

231

232

/**

233

* Go to specific frame and stop

234

* @param frameNumber - Frame to go to

235

*/

236

gotoAndStop(frameNumber: number): void;

237

238

/**

239

* Update animation

240

* @param deltaTime - Time since last update

241

*/

242

update(deltaTime: number): void;

243

244

/**

245

* Destroy animated sprite

246

* @param options - Destroy options

247

*/

248

destroy(options?: DestroyOptions): void;

249

250

/**

251

* Create from array of image sources

252

* @param images - Array of image sources

253

* @returns New animated sprite

254

*/

255

static fromImages(images: string[]): AnimatedSprite;

256

257

/**

258

* Create from sprite sheet frames

259

* @param sheet - Sprite sheet

260

* @param frameNames - Array of frame names

261

* @returns New animated sprite

262

*/

263

static fromFrames(frameNames: string[]): AnimatedSprite;

264

}

265

266

/**

267

* Animation frame with timing information

268

*/

269

interface FrameObject {

270

/** Frame texture */

271

texture: Texture;

272

273

/** Frame duration in milliseconds */

274

time: number;

275

}

276

```

277

278

### Animation Utilities

279

280

Utility functions and classes for animation management.

281

282

```typescript { .api }

283

/**

284

* Simple tween class for property animation

285

*/

286

class Tween {

287

constructor(target: any);

288

289

/** Target object */

290

target: any;

291

292

/** Is tween playing */

293

playing: boolean;

294

295

/** Tween duration */

296

duration: number;

297

298

/** Tween progress (0-1) */

299

progress: number;

300

301

/** Easing function */

302

easing: (t: number) => number;

303

304

/** Completion callback */

305

onComplete: () => void;

306

307

/** Update callback */

308

onUpdate: (progress: number) => void;

309

310

/**

311

* Animate to target values

312

* @param properties - Target property values

313

* @param duration - Animation duration in milliseconds

314

* @param easing - Easing function

315

* @returns This tween

316

*/

317

to(properties: Record<string, number>, duration: number, easing?: (t: number) => number): this;

318

319

/**

320

* Start tween

321

* @returns This tween

322

*/

323

start(): this;

324

325

/**

326

* Stop tween

327

* @returns This tween

328

*/

329

stop(): this;

330

331

/**

332

* Update tween

333

* @param deltaTime - Time since last update

334

*/

335

update(deltaTime: number): void;

336

337

/**

338

* Set completion callback

339

* @param callback - Completion callback

340

* @returns This tween

341

*/

342

call(callback: () => void): this;

343

}

344

345

/**

346

* Common easing functions

347

*/

348

const Easing = {

349

/** Linear interpolation */

350

linear: (t: number) => t,

351

352

/** Ease in (accelerate) */

353

easeIn: (t: number) => t * t,

354

355

/** Ease out (decelerate) */

356

easeOut: (t: number) => 1 - (1 - t) * (1 - t),

357

358

/** Ease in-out (accelerate then decelerate) */

359

easeInOut: (t: number) => t < 0.5 ? 2 * t * t : 1 - 2 * (1 - t) * (1 - t),

360

361

/** Elastic ease out */

362

elasticOut: (t: number) => Math.sin(-13 * (t + 1) * Math.PI / 2) * Math.pow(2, -10 * t) + 1,

363

364

/** Bounce ease out */

365

bounceOut: (t: number) => {

366

if (t < 1 / 2.75) {

367

return 7.5625 * t * t;

368

} else if (t < 2 / 2.75) {

369

return 7.5625 * (t -= 1.5 / 2.75) * t + 0.75;

370

} else if (t < 2.5 / 2.75) {

371

return 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375;

372

} else {

373

return 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375;

374

}

375

}

376

};

377

378

/**

379

* Animation timeline for sequencing animations

380

*/

381

class Timeline {

382

constructor();

383

384

/** Timeline duration */

385

duration: number;

386

387

/** Timeline progress */

388

progress: number;

389

390

/** Is timeline playing */

391

playing: boolean;

392

393

/** Timeline animations */

394

animations: TimelineAnimation[];

395

396

/**

397

* Add animation to timeline

398

* @param target - Target object

399

* @param properties - Properties to animate

400

* @param duration - Animation duration

401

* @param delay - Animation delay

402

* @returns This timeline

403

*/

404

add(target: any, properties: Record<string, number>, duration: number, delay?: number): this;

405

406

/**

407

* Play timeline

408

* @returns This timeline

409

*/

410

play(): this;

411

412

/**

413

* Stop timeline

414

* @returns This timeline

415

*/

416

stop(): this;

417

418

/**

419

* Update timeline

420

* @param deltaTime - Time since last update

421

*/

422

update(deltaTime: number): void;

423

}

424

425

interface TimelineAnimation {

426

target: any;

427

properties: Record<string, number>;

428

startValues: Record<string, number>;

429

duration: number;

430

delay: number;

431

startTime: number;

432

}

433

```

434

435

### Performance Animation

436

437

High-performance animation utilities for large numbers of objects.

438

439

```typescript { .api }

440

/**

441

* Animation pool for reusing animation objects

442

*/

443

class AnimationPool {

444

constructor();

445

446

/** Available animations */

447

available: Tween[];

448

449

/** Active animations */

450

active: Tween[];

451

452

/**

453

* Get animation from pool

454

* @param target - Target object

455

* @returns Pooled animation

456

*/

457

get(target: any): Tween;

458

459

/**

460

* Return animation to pool

461

* @param animation - Animation to return

462

*/

463

return(animation: Tween): void;

464

465

/**

466

* Update all active animations

467

* @param deltaTime - Time since last update

468

*/

469

update(deltaTime: number): void;

470

471

/**

472

* Clean up pool

473

*/

474

destroy(): void;

475

}

476

477

/**

478

* Batch animation system for many objects

479

*/

480

class BatchAnimator {

481

constructor();

482

483

/** Animation targets */

484

targets: any[];

485

486

/** Animation properties */

487

properties: string[];

488

489

/** Animation duration */

490

duration: number;

491

492

/** Animation progress */

493

progress: number;

494

495

/**

496

* Add target to batch

497

* @param target - Target object

498

* @param startValues - Starting values

499

* @param endValues - Ending values

500

*/

501

addTarget(target: any, startValues: Record<string, number>, endValues: Record<string, number>): void;

502

503

/**

504

* Update all targets

505

* @param deltaTime - Time since last update

506

*/

507

update(deltaTime: number): void;

508

509

/**

510

* Start batch animation

511

*/

512

start(): void;

513

514

/**

515

* Stop batch animation

516

*/

517

stop(): void;

518

}

519

```

520

521

**Usage Examples:**

522

523

```typescript

524

import {

525

Ticker,

526

AnimatedSprite,

527

Tween,

528

Timeline,

529

Easing,

530

Assets,

531

Sprite,

532

Container,

533

UPDATE_PRIORITY

534

} from 'pixi.js';

535

536

// Basic ticker usage

537

const ticker = new Ticker();

538

539

ticker.add((ticker) => {

540

// This runs every frame

541

console.log(`FPS: ${ticker.FPS}, Delta: ${ticker.deltaTime}`);

542

});

543

544

ticker.start();

545

546

// Animation with different priorities

547

ticker.add((ticker) => {

548

// High priority update (runs first)

549

updatePhysics(ticker.deltaTime);

550

}, null, UPDATE_PRIORITY.HIGH);

551

552

ticker.add((ticker) => {

553

// Normal priority update

554

updateVisuals(ticker.deltaTime);

555

}, null, UPDATE_PRIORITY.NORMAL);

556

557

ticker.add((ticker) => {

558

// Low priority update (runs last)

559

updateUI(ticker.deltaTime);

560

}, null, UPDATE_PRIORITY.LOW);

561

562

// Animated sprite creation

563

const walkTextures = [

564

await Assets.load('walk1.png'),

565

await Assets.load('walk2.png'),

566

await Assets.load('walk3.png'),

567

await Assets.load('walk4.png')

568

];

569

570

const animatedSprite = new AnimatedSprite(walkTextures);

571

animatedSprite.animationSpeed = 0.167; // 10 FPS at 60 FPS

572

animatedSprite.loop = true;

573

animatedSprite.play();

574

575

// Animation callbacks

576

animatedSprite.onComplete = () => {

577

console.log('Animation completed');

578

};

579

580

animatedSprite.onFrameChange = (currentFrame) => {

581

console.log(`Frame changed to: ${currentFrame}`);

582

};

583

584

animatedSprite.onLoop = () => {

585

console.log('Animation looped');

586

};

587

588

// Frame objects with custom timing

589

const customFrames = [

590

{ texture: walkTextures[0], time: 100 }, // 100ms

591

{ texture: walkTextures[1], time: 150 }, // 150ms

592

{ texture: walkTextures[2], time: 100 }, // 100ms

593

{ texture: walkTextures[3], time: 200 } // 200ms

594

];

595

596

const customAnimatedSprite = new AnimatedSprite(customFrames);

597

customAnimatedSprite.play();

598

599

// Simple property tweening

600

const sprite = new Sprite(await Assets.load('sprite.png'));

601

602

const tween = new Tween(sprite)

603

.to({ x: 400, y: 300, alpha: 0.5 }, 2000, Easing.easeInOut)

604

.call(() => {

605

console.log('Tween completed');

606

});

607

608

tween.start();

609

610

// Update tween manually or with ticker

611

ticker.add((ticker) => {

612

tween.update(ticker.elapsedMS);

613

});

614

615

// Complex animation timeline

616

const timeline = new Timeline();

617

618

timeline

619

.add(sprite, { x: 200 }, 1000, 0) // Move to x: 200 over 1s, start immediately

620

.add(sprite, { y: 200 }, 1000, 500) // Move to y: 200 over 1s, start after 0.5s

621

.add(sprite, { alpha: 0 }, 500, 1500) // Fade out over 0.5s, start after 1.5s

622

.play();

623

624

ticker.add((ticker) => {

625

timeline.update(ticker.elapsedMS);

626

});

627

628

// Sprite scaling animation with bounce

629

const scaleSprite = new Sprite(texture);

630

const scaleTween = new Tween(scaleSprite.scale)

631

.to({ x: 2, y: 2 }, 1000, Easing.bounceOut);

632

633

scaleTween.start();

634

635

// Rotation animation

636

const rotationSprite = new Sprite(texture);

637

ticker.add((ticker) => {

638

rotationSprite.rotation += 0.01 * ticker.deltaTime;

639

});

640

641

// Color animation using tint

642

const colorSprite = new Sprite(texture);

643

let hue = 0;

644

645

ticker.add((ticker) => {

646

hue += 0.01 * ticker.deltaTime;

647

const color = new Color();

648

color.setHsl(hue % 1, 1, 0.5);

649

colorSprite.tint = color.value;

650

});

651

652

// Performance optimization - pause ticker when not needed

653

document.addEventListener('visibilitychange', () => {

654

if (document.hidden) {

655

ticker.stop();

656

} else {

657

ticker.start();

658

}

659

});

660

661

// Animation state machine

662

class AnimationStateMachine {

663

private currentState: string = 'idle';

664

private animations: Record<string, AnimatedSprite> = {};

665

666

constructor(private sprite: Container) {}

667

668

addAnimation(name: string, animation: AnimatedSprite) {

669

this.animations[name] = animation;

670

this.sprite.addChild(animation);

671

animation.visible = false;

672

}

673

674

setState(newState: string) {

675

if (this.animations[this.currentState]) {

676

this.animations[this.currentState].visible = false;

677

this.animations[this.currentState].stop();

678

}

679

680

this.currentState = newState;

681

682

if (this.animations[newState]) {

683

this.animations[newState].visible = true;

684

this.animations[newState].play();

685

}

686

}

687

}

688

689

// Character with multiple animations

690

const character = new Container();

691

const stateMachine = new AnimationStateMachine(character);

692

693

stateMachine.addAnimation('idle', new AnimatedSprite(idleTextures));

694

stateMachine.addAnimation('walk', new AnimatedSprite(walkTextures));

695

stateMachine.addAnimation('jump', new AnimatedSprite(jumpTextures));

696

697

// Switch animations based on input

698

stateMachine.setState('walk');

699

700

// Particle animation system

701

const particles: Sprite[] = [];

702

const particleCount = 100;

703

704

for (let i = 0; i < particleCount; i++) {

705

const particle = new Sprite(particleTexture);

706

particle.x = Math.random() * 800;

707

particle.y = Math.random() * 600;

708

particle.anchor.set(0.5);

709

particles.push(particle);

710

app.stage.addChild(particle);

711

}

712

713

ticker.add((ticker) => {

714

particles.forEach((particle, index) => {

715

particle.rotation += 0.01 * ticker.deltaTime;

716

particle.y += Math.sin(Date.now() * 0.001 + index) * 0.5;

717

particle.alpha = 0.5 + Math.sin(Date.now() * 0.002 + index) * 0.5;

718

});

719

});

720

721

// Clean up animations

722

window.addEventListener('beforeunload', () => {

723

ticker.destroy();

724

tween.stop();

725

timeline.stop();

726

animatedSprite.destroy();

727

});

728

```