or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation.mdcameras.mdgeometries.mdindex.mdlights.mdloaders.mdmaterials.mdmath.mdrenderers.mdscene-management.mdtsl.mdwebgpu.md

animation.mddocs/

0

# Animation System

1

2

Three.js provides a comprehensive keyframe-based animation system for animating object properties over time. The animation system supports timeline control, blending, and complex animation sequencing with multiple tracks and interpolation modes.

3

4

## Capabilities

5

6

### Animation Mixer

7

8

Central animation control system that manages animation playback for objects and their hierarchies.

9

10

```javascript { .api }

11

/**

12

* Animation mixer for controlling multiple animation clips on objects

13

*/

14

class AnimationMixer extends EventDispatcher {

15

/**

16

* Create animation mixer for specified root object

17

* @param root - Root object that will be animated

18

*/

19

constructor(root: Object3D);

20

21

/** Root object being animated */

22

root: Object3D;

23

24

/** Current time in seconds */

25

time: number;

26

27

/** Time scale multiplier for all animations */

28

timeScale: number;

29

30

/**

31

* Create action for animation clip

32

* @param clip - Animation clip to create action for

33

* @param optionalRoot - Optional specific root for this action

34

* @returns Animation action ready for playback control

35

*/

36

clipAction(clip: AnimationClip, optionalRoot?: Object3D): AnimationAction;

37

38

/**

39

* Create action for animation clip by name

40

* @param name - Name of animation clip to find

41

* @param optionalRoot - Optional specific root for this action

42

* @returns Animation action or null if not found

43

*/

44

clipActionByName(name: string, optionalRoot?: Object3D): AnimationAction | null;

45

46

/**

47

* Get existing action for animation clip

48

* @param clip - Animation clip to find action for

49

* @param optionalRoot - Optional specific root for this action

50

* @returns Existing animation action or null

51

*/

52

existingAction(clip: AnimationClip, optionalRoot?: Object3D): AnimationAction | null;

53

54

/**

55

* Stop all currently active actions

56

* @returns This mixer for chaining

57

*/

58

stopAllAction(): AnimationMixer;

59

60

/**

61

* Update animations by specified time delta

62

* @param deltaTimeInSeconds - Time elapsed since last update in seconds

63

* @returns This mixer for chaining

64

*/

65

update(deltaTimeInSeconds: number): AnimationMixer;

66

67

/**

68

* Set time for all actions directly

69

* @param timeInSeconds - Time to set in seconds

70

* @returns This mixer for chaining

71

*/

72

setTime(timeInSeconds: number): AnimationMixer;

73

74

/**

75

* Get list of all actions on root or descendant objects

76

* @returns Array of all animation actions

77

*/

78

getRoot(): Object3D;

79

80

/**

81

* Deallocate all memory used by this mixer

82

*/

83

uncacheClip(clip: AnimationClip): void;

84

85

/**

86

* Deallocate memory used for root object

87

*/

88

uncacheRoot(root: Object3D): void;

89

90

/**

91

* Deallocate memory used for action

92

*/

93

uncacheAction(clip: AnimationClip, optionalRoot?: Object3D): void;

94

}

95

```

96

97

**Usage Example:**

98

99

```javascript

100

import { AnimationMixer, Clock } from 'three';

101

102

// Create mixer for loaded model

103

const mixer = new AnimationMixer(gltfScene);

104

105

// Create actions for loaded animations

106

const walkAction = mixer.clipAction(walkClip);

107

const runAction = mixer.clipAction(runClip);

108

109

// Configure and play animations

110

walkAction.play();

111

runAction.setWeight(0); // Start with walk only

112

113

// Animation loop

114

const clock = new Clock();

115

function animate() {

116

const deltaTime = clock.getDelta();

117

mixer.update(deltaTime);

118

119

requestAnimationFrame(animate);

120

renderer.render(scene, camera);

121

}

122

```

123

124

### Animation Clips

125

126

Container for animation data defining property changes over time using keyframe tracks.

127

128

```javascript { .api }

129

/**

130

* Container for keyframe track data representing an animation sequence

131

*/

132

class AnimationClip {

133

/**

134

* Create animation clip from keyframe tracks

135

* @param name - Name identifier for this clip

136

* @param duration - Length of animation in seconds (-1 for auto-calculate)

137

* @param tracks - Array of keyframe tracks defining property animations

138

* @param blendMode - How this clip blends with others

139

*/

140

constructor(name?: string, duration?: number, tracks?: KeyframeTrack[], blendMode?: AnimationBlendMode);

141

142

/** Unique name for this animation clip */

143

name: string;

144

145

/** Duration of animation in seconds */

146

duration: number;

147

148

/** Array of keyframe tracks defining property animations */

149

tracks: KeyframeTrack[];

150

151

/** Blend mode for combining with other animations */

152

blendMode: AnimationBlendMode;

153

154

/**

155

* Create copy of this animation clip

156

* @returns New animation clip with copied data

157

*/

158

clone(): AnimationClip;

159

160

/**

161

* Optimize clip by removing unnecessary keyframes

162

* @returns This clip for chaining

163

*/

164

optimize(): AnimationClip;

165

166

/**

167

* Reset duration based on track lengths

168

* @returns This clip for chaining

169

*/

170

resetDuration(): AnimationClip;

171

172

/**

173

* Trim clip to specified time range

174

* @param startTime - Start time in seconds

175

* @param endTime - End time in seconds

176

* @returns This clip for chaining

177

*/

178

trim(): AnimationClip;

179

180

/**

181

* Validate all tracks in this clip

182

* @returns True if valid

183

*/

184

validate(): boolean;

185

}

186

187

// Animation blend modes

188

type AnimationBlendMode =

189

| typeof NormalAnimationBlendMode // 2500 - Replace existing values

190

| typeof AdditiveAnimationBlendMode; // 2501 - Add to existing values

191

```

192

193

**Usage Example:**

194

195

```javascript

196

import { AnimationClip, VectorKeyframeTrack, NumberKeyframeTrack } from 'three';

197

198

// Create keyframe tracks

199

const positionTrack = new VectorKeyframeTrack(

200

'.position', // Property path

201

[0, 1, 2], // Times

202

[0, 0, 0, 10, 0, 0, 0, 0, 0] // Values (x,y,z for each time)

203

);

204

205

const opacityTrack = new NumberKeyframeTrack(

206

'.material.opacity', // Property path

207

[0, 1, 2], // Times

208

[1, 0.5, 1] // Values

209

);

210

211

// Create animation clip

212

const fadeAndMove = new AnimationClip('fadeAndMove', 2, [

213

positionTrack,

214

opacityTrack

215

]);

216

```

217

218

### Animation Actions

219

220

Playback control interface for animation clips with timing, weights, and state management.

221

222

```javascript { .api }

223

/**

224

* Controls playback of an animation clip with timing and blending options

225

*/

226

class AnimationAction {

227

/** Animation clip being controlled */

228

clip: AnimationClip;

229

230

/** Animation mixer managing this action */

231

mixer: AnimationMixer;

232

233

/** Current playback time in seconds */

234

time: number;

235

236

/** Playback speed multiplier */

237

timeScale: number;

238

239

/** Influence weight for blending (0-1) */

240

weight: number;

241

242

/** Number of repetitions (Infinity for endless) */

243

repetitions: number;

244

245

/** Whether action is currently paused */

246

paused: boolean;

247

248

/** Whether action is currently enabled */

249

enabled: boolean;

250

251

/** Whether to clamp when animation reaches end */

252

clampWhenFinished: boolean;

253

254

/** Whether to automatically start when mixed */

255

zeroSlopeAtStart: boolean;

256

257

/** Whether to smoothly end interpolation */

258

zeroSlopeAtEnd: boolean;

259

260

/** Loop mode for animation playback */

261

loop: AnimationActionLoopStyles;

262

263

/**

264

* Start or resume playback

265

* @returns This action for chaining

266

*/

267

play(): AnimationAction;

268

269

/**

270

* Stop playback and reset to beginning

271

* @returns This action for chaining

272

*/

273

stop(): AnimationAction;

274

275

/**

276

* Pause playback at current time

277

* @returns This action for chaining

278

*/

279

pause(): AnimationAction;

280

281

/**

282

* Pause all other actions and play this one

283

* @returns This action for chaining

284

*/

285

stopFading(): AnimationAction;

286

287

/**

288

* Reset action to initial state

289

* @returns This action for chaining

290

*/

291

reset(): AnimationAction;

292

293

/**

294

* Check if action is currently running

295

* @returns True if action is playing

296

*/

297

isRunning(): boolean;

298

299

/**

300

* Check if action is scheduled to start

301

* @returns True if action is scheduled

302

*/

303

isScheduled(): boolean;

304

305

/**

306

* Set effective weight with fade in/out

307

* @param weight - Target weight (0-1)

308

* @param duration - Fade duration in seconds

309

* @returns This action for chaining

310

*/

311

fadeIn(duration: number): AnimationAction;

312

313

/**

314

* Fade out action weight to zero

315

* @param duration - Fade duration in seconds

316

* @returns This action for chaining

317

*/

318

fadeOut(duration: number): AnimationAction;

319

320

/**

321

* Cross-fade to another action

322

* @param fadeOutAction - Action to fade out

323

* @param duration - Cross-fade duration in seconds

324

* @param warp - Whether to synchronize durations

325

* @returns This action for chaining

326

*/

327

crossFadeFrom(fadeOutAction: AnimationAction, duration: number, warp?: boolean): AnimationAction;

328

329

/**

330

* Cross-fade from this action to another

331

* @param fadeInAction - Action to fade in

332

* @param duration - Cross-fade duration in seconds

333

* @param warp - Whether to synchronize durations

334

* @returns This action for chaining

335

*/

336

crossFadeTo(fadeInAction: AnimationAction, duration: number, warp?: boolean): AnimationAction;

337

338

/**

339

* Gradually change playback speed

340

* @param timeScale - Target time scale

341

* @param duration - Warp duration in seconds

342

* @returns This action for chaining

343

*/

344

warp(startTimeScale: number, endTimeScale: number, duration: number): AnimationAction;

345

346

/**

347

* Set loop mode and repetition count

348

* @param mode - Loop style constant

349

* @param repetitions - Number of loops (Infinity for endless)

350

* @returns This action for chaining

351

*/

352

setLoop(mode: AnimationActionLoopStyles, repetitions: number): AnimationAction;

353

354

/**

355

* Set effective weight immediately

356

* @param weight - Weight value (0-1)

357

* @returns This action for chaining

358

*/

359

setEffectiveWeight(weight: number): AnimationAction;

360

361

/**

362

* Get current effective weight

363

* @returns Current effective weight

364

*/

365

getEffectiveWeight(): number;

366

367

/**

368

* Set effective time scale immediately

369

* @param timeScale - Time scale multiplier

370

* @returns This action for chaining

371

*/

372

setEffectiveTimeScale(timeScale: number): AnimationAction;

373

374

/**

375

* Get current effective time scale

376

* @returns Current effective time scale

377

*/

378

getEffectiveTimeScale(): number;

379

380

/**

381

* Get total duration accounting for time scale and repetitions

382

* @returns Total duration in seconds

383

*/

384

getClip(): AnimationClip;

385

386

/**

387

* Get animation mixer controlling this action

388

* @returns Animation mixer instance

389

*/

390

getMixer(): AnimationMixer;

391

392

/**

393

* Get root object being animated

394

* @returns Root object

395

*/

396

getRoot(): Object3D;

397

}

398

399

// Loop style constants

400

type AnimationActionLoopStyles =

401

| typeof LoopOnce // 2200 - Play once and stop

402

| typeof LoopRepeat // 2201 - Repeat from beginning

403

| typeof LoopPingPong; // 2202 - Reverse direction each loop

404

```

405

406

### Keyframe Tracks

407

408

Base classes for defining property animations over time with various interpolation modes.

409

410

```javascript { .api }

411

/**

412

* Base class for keyframe-based property animation tracks

413

*/

414

abstract class KeyframeTrack {

415

/**

416

* Create keyframe track for animating property

417

* @param name - Property path (e.g. '.position.x', '.rotation')

418

* @param times - Array of time values in seconds

419

* @param values - Array of property values at each time

420

* @param interpolation - Interpolation mode between keyframes

421

*/

422

constructor(name: string, times: ArrayLike<number>, values: ArrayLike<any>, interpolation?: InterpolationModes);

423

424

/** Property path being animated */

425

name: string;

426

427

/** Time values for keyframes */

428

times: Float32Array;

429

430

/** Property values at each keyframe */

431

values: Float32Array;

432

433

/** Type name for this track */

434

ValueTypeName: string;

435

436

/** Time interpolation mode */

437

interpolation: InterpolationModes;

438

439

/**

440

* Get interpolated value at specified time

441

* @param time - Time in seconds

442

* @returns Interpolated value

443

*/

444

evaluate(time: number): any;

445

446

/**

447

* Create copy of this track

448

* @returns New keyframe track with copied data

449

*/

450

clone(): this;

451

452

/**

453

* Scale all time values

454

* @param timeScale - Scale factor for times

455

* @returns This track for chaining

456

*/

457

scale(timeScale: number): this;

458

459

/**

460

* Trim track to specified time range

461

* @param startTime - Start time in seconds

462

* @param endTime - End time in seconds

463

* @returns This track for chaining

464

*/

465

trim(startTime: number, endTime: number): this;

466

467

/**

468

* Shift all keyframe times by offset

469

* @param timeOffset - Time offset in seconds

470

* @returns This track for chaining

471

*/

472

shift(timeOffset: number): this;

473

474

/**

475

* Optimize track by removing redundant keyframes

476

* @returns This track for chaining

477

*/

478

optimize(): this;

479

480

/**

481

* Validate track data consistency

482

* @returns True if track is valid

483

*/

484

validate(): boolean;

485

}

486

487

/**

488

* Keyframe track for animating Vector3 properties

489

*/

490

class VectorKeyframeTrack extends KeyframeTrack {

491

/**

492

* Create vector keyframe track

493

* @param name - Property path (e.g. '.position', '.scale')

494

* @param times - Array of time values

495

* @param values - Array of vector values [x,y,z,x,y,z,...]

496

* @param interpolation - Interpolation mode

497

*/

498

constructor(name: string, times: ArrayLike<number>, values: ArrayLike<number>, interpolation?: InterpolationModes);

499

}

500

501

/**

502

* Keyframe track for animating number properties

503

*/

504

class NumberKeyframeTrack extends KeyframeTrack {

505

/**

506

* Create number keyframe track

507

* @param name - Property path (e.g. '.opacity', '.intensity')

508

* @param times - Array of time values

509

* @param values - Array of number values

510

* @param interpolation - Interpolation mode

511

*/

512

constructor(name: string, times: ArrayLike<number>, values: ArrayLike<number>, interpolation?: InterpolationModes);

513

}

514

515

/**

516

* Keyframe track for animating Quaternion rotations

517

*/

518

class QuaternionKeyframeTrack extends KeyframeTrack {

519

/**

520

* Create quaternion keyframe track

521

* @param name - Property path (e.g. '.quaternion')

522

* @param times - Array of time values

523

* @param values - Array of quaternion values [x,y,z,w,x,y,z,w,...]

524

* @param interpolation - Interpolation mode

525

*/

526

constructor(name: string, times: ArrayLike<number>, values: ArrayLike<number>, interpolation?: InterpolationModes);

527

}

528

529

/**

530

* Keyframe track for animating Color properties

531

*/

532

class ColorKeyframeTrack extends KeyframeTrack {

533

/**

534

* Create color keyframe track

535

* @param name - Property path (e.g. '.color', '.emissive')

536

* @param times - Array of time values

537

* @param values - Array of color values [r,g,b,r,g,b,...]

538

* @param interpolation - Interpolation mode

539

*/

540

constructor(name: string, times: ArrayLike<number>, values: ArrayLike<number>, interpolation?: InterpolationModes);

541

}

542

543

/**

544

* Keyframe track for animating string/discrete properties

545

*/

546

class StringKeyframeTrack extends KeyframeTrack {

547

/**

548

* Create string keyframe track for discrete values

549

* @param name - Property path

550

* @param times - Array of time values

551

* @param values - Array of string values

552

*/

553

constructor(name: string, times: ArrayLike<number>, values: ArrayLike<string>);

554

}

555

556

/**

557

* Keyframe track for animating boolean properties

558

*/

559

class BooleanKeyframeTrack extends KeyframeTrack {

560

/**

561

* Create boolean keyframe track

562

* @param name - Property path

563

* @param times - Array of time values

564

* @param values - Array of boolean values

565

*/

566

constructor(name: string, times: ArrayLike<number>, values: ArrayLike<boolean>);

567

}

568

569

// Interpolation modes

570

type InterpolationModes =

571

| typeof InterpolateDiscrete // Step interpolation

572

| typeof InterpolateLinear // Linear interpolation

573

| typeof InterpolateSmooth; // Smooth/cubic interpolation

574

```

575

576

### Animation Utilities

577

578

Utility functions for creating, modifying, and managing animation data.

579

580

```javascript { .api }

581

/**

582

* Utility functions for animation system

583

*/

584

class AnimationUtils {

585

/**

586

* Convert track array to hierarchy of clips

587

* @param tracks - Array of keyframe tracks

588

* @returns Array of animation clips

589

*/

590

static arraySlice(array: any[], from: number, to: number): any[];

591

592

/**

593

* Create clip from morph target animation

594

* @param name - Animation name

595

* @param morphTargetNames - Names of morph targets

596

* @param fps - Frames per second

597

* @returns Animation clip for morph targets

598

*/

599

static makeSameType(source: KeyframeTrack, times: ArrayLike<number>, values: ArrayLike<any>): KeyframeTrack;

600

601

/**

602

* Get keyframe track constructor by name

603

* @param typeName - Track type name

604

* @returns Track constructor function

605

*/

606

static getKeyframeOrder(times: ArrayLike<number>): number[];

607

608

/**

609

* Sort keyframes by time and remove duplicates

610

* @param track - Keyframe track to sort

611

* @returns Sorted track

612

*/

613

static sortedArray(values: any[], stride: number, order: number[]): any[];

614

615

/**

616

* Create animation clip from object hierarchy

617

* @param root - Root object to extract animation from

618

* @param name - Name for created clip

619

* @param fps - Target framerate

620

* @returns Animation clip extracted from object

621

*/

622

static flattenJSON(jsonKeys: string[], times: number[], values: any[], valuePropertyName: string): KeyframeTrack[];

623

624

/**

625

* Utility to sub-sample keyframe track

626

* @param track - Source track

627

* @param newTimes - New time values

628

* @returns Sub-sampled track

629

*/

630

static subclip(sourceClip: AnimationClip, name: string, startFrame: number, endFrame: number, fps?: number): AnimationClip;

631

}

632

```

633

634

### Animation Object Groups

635

636

System for managing animations across multiple objects sharing similar structure.

637

638

```javascript { .api }

639

/**

640

* Group of objects that can share animation data and playback timing

641

*/

642

class AnimationObjectGroup {

643

/**

644

* Create animation object group

645

* @param objects - Objects to group together

646

*/

647

constructor(...objects: Object3D[]);

648

649

/** UUID for this group */

650

uuid: string;

651

652

/** Statistics about group usage */

653

stats: {

654

bindingsPerObject: number;

655

objects: {

656

total: number;

657

inUse: number;

658

};

659

};

660

661

/**

662

* Add objects to this group

663

* @param objects - Objects to add

664

*/

665

add(...objects: Object3D[]): void;

666

667

/**

668

* Remove objects from group

669

* @param objects - Objects to remove

670

*/

671

remove(...objects: Object3D[]): void;

672

673

/**

674

* Remove all objects from group

675

*/

676

uncache(...objects: Object3D[]): void;

677

}

678

```

679

680

### Property Animation System

681

682

Low-level animation system components for binding tracks to object properties and mixing multiple values.

683

684

```javascript { .api }

685

/**

686

* Binds animation tracks to object properties using property paths

687

*/

688

class PropertyBinding {

689

/**

690

* Create property binding for animation track

691

* @param rootNode - Root object containing the property

692

* @param path - Property path (e.g., '.position', '.rotation.x', '.material.opacity')

693

* @param parsedPath - Pre-parsed property path (internal use)

694

*/

695

constructor(rootNode: Object3D, path: string, parsedPath?: any);

696

697

/** Root object containing the property */

698

rootNode: Object3D;

699

700

/** Property path string */

701

path: string;

702

703

/** Parsed property path components */

704

parsedPath: any;

705

706

/** Target object containing the property */

707

node: any;

708

709

/** Final property being animated */

710

nodeProperty: any;

711

712

/**

713

* Get current property value

714

* @param targetArray - Array to store result in

715

*/

716

getValue(targetArray: ArrayLike<number>): void;

717

718

/**

719

* Set property value from array

720

* @param sourceArray - Array containing new values

721

*/

722

setValue(sourceArray: ArrayLike<number>): void;

723

724

/**

725

* Bind property for animation

726

*/

727

bind(): void;

728

729

/**

730

* Unbind property

731

*/

732

unbind(): void;

733

734

/**

735

* Create property binding from animation track

736

* @param root - Root object

737

* @param track - Keyframe track to bind

738

* @returns Property binding instance

739

*/

740

static create(root: Object3D, track: KeyframeTrack): PropertyBinding;

741

742

/**

743

* Parse property path into components

744

* @param path - Property path string

745

* @returns Parsed path object

746

*/

747

static parseTrackName(path: string): any;

748

749

/**

750

* Find property node in object hierarchy

751

* @param root - Root object to search from

752

* @param nodeName - Name of node to find

753

* @returns Found object or null

754

*/

755

static findNode(root: Object3D, nodeName: string): Object3D | null;

756

}

757

758

/**

759

* Mixes multiple property values for animation blending

760

*/

761

class PropertyMixer {

762

/**

763

* Create property mixer for blending multiple values

764

* @param binding - Property binding to mix values for

765

* @param typeName - Type name for the property values

766

* @param valueSize - Number of components per value

767

*/

768

constructor(binding: PropertyBinding, typeName: string, valueSize: number);

769

770

/** Property binding being mixed */

771

binding: PropertyBinding;

772

773

/** Type name for values */

774

typeName: string;

775

776

/** Number of components per value */

777

valueSize: number;

778

779

/** Buffer for accumulating mixed values */

780

buffer: ArrayLike<number>;

781

782

/** Current cumulative weight */

783

cumulativeWeight: number;

784

785

/** Whether cumulative weight was used */

786

cumulativeWeightAdditive: number;

787

788

/** Whether binding has been applied */

789

useCount: number;

790

791

/** Reference count for this mixer */

792

referenceCount: number;

793

794

/**

795

* Accumulate weighted value into buffer

796

* @param accuIndex - Index in accumulator

797

* @param weight - Blend weight

798

* @param values - Source values array

799

* @param valueOffset - Offset in values array

800

*/

801

accumulate(accuIndex: number, weight: number, values: ArrayLike<number>, valueOffset: number): void;

802

803

/**

804

* Accumulate additive value into buffer

805

* @param accuIndex - Index in accumulator

806

* @param weight - Blend weight

807

* @param values - Source values array

808

* @param valueOffset - Offset in values array

809

*/

810

accumulateAdditive(accuIndex: number, weight: number, values: ArrayLike<number>, valueOffset: number): void;

811

812

/**

813

* Apply accumulated values to property

814

* @param accuIndex - Index in accumulator

815

*/

816

apply(accuIndex: number): void;

817

818

/**

819

* Save current property state

820

* @param accuIndex - Index to save at

821

*/

822

saveOriginalState(accuIndex: number): void;

823

824

/**

825

* Restore saved property state

826

* @param accuIndex - Index to restore from

827

*/

828

restoreOriginalState(accuIndex: number): void;

829

}

830

```

831

832

## Types

833

834

```javascript { .api }

835

// Animation-specific type definitions

836

type AnimationBlendMode = number;

837

type AnimationActionLoopStyles = number;

838

type InterpolationModes = number;

839

840

// Loop constants

841

declare const LoopOnce: 2200;

842

declare const LoopRepeat: 2201;

843

declare const LoopPingPong: 2202;

844

845

// Blend mode constants

846

declare const NormalAnimationBlendMode: 2500;

847

declare const AdditiveAnimationBlendMode: 2501;

848

849

// Interpolation constants

850

declare const InterpolateDiscrete: 2300;

851

declare const InterpolateLinear: 2301;

852

declare const InterpolateSmooth: 2302;

853

```

854

855

## Usage Examples

856

857

**Complex Animation Setup:**

858

859

```javascript

860

import * as THREE from 'three';

861

862

// Create mixer for character

863

const mixer = new THREE.AnimationMixer(character);

864

865

// Load multiple animation clips

866

const idleClip = character.animations.find(clip => clip.name === 'idle');

867

const walkClip = character.animations.find(clip => clip.name === 'walk');

868

const runClip = character.animations.find(clip => clip.name === 'run');

869

870

// Create actions

871

const idleAction = mixer.clipAction(idleClip);

872

const walkAction = mixer.clipAction(walkClip);

873

const runAction = mixer.clipAction(runClip);

874

875

// Configure actions

876

idleAction.play();

877

walkAction.setWeight(0).play();

878

runAction.setWeight(0).play();

879

880

// Animation state management

881

let currentAction = idleAction;

882

883

function transitionTo(newAction, duration = 0.5) {

884

if (currentAction !== newAction) {

885

currentAction.fadeOut(duration);

886

newAction.reset().fadeIn(duration).play();

887

currentAction = newAction;

888

}

889

}

890

891

// Update loop

892

const clock = new THREE.Clock();

893

function animate() {

894

const deltaTime = clock.getDelta();

895

mixer.update(deltaTime);

896

897

requestAnimationFrame(animate);

898

renderer.render(scene, camera);

899

}

900

```