HW

2D Animations Guide

Overview

The 2D animation system provides a simplified API for 2D scenes with position, angle, opacity, and scale animations.

Key Differences from 3D

  • Angles instead of rotations: Uses degrees for rotation angles
  • Vector2 instead of Vector3: 2D positions use x and y components
  • Scale support: 2D models can be scaled
  • Simpler camera: Pan, zoom, and rotation instead of full 3D camera control
  • No quaternions: Direct angle interpolation using shortest-arc

Basic 2D Animation

import { reconcileScene2D, reconcile_animationState2D, NodeMain2D, Vector2, SceneObject2D } from 'hw-ts-parametric-sequencer/2d';

const object = new SceneObject2D('sprite1', {});

const scene = [
  new NodeMain2D({
    name: 'move-sprite',
    chapter: 'intro',
    sceneObject: object,
    time: { type: 'absolute', value: 0 },
    duration: 2,
    position: { type: 'absolute', value: new Vector2(100, 50) },
    rotation: { type: 'relative', value: 90 }, // degrees
    opacity: 1.0,
    scale: 1.5
  })
];

// Reconcile the scene once
const reconciled = reconcileScene2D(scene);

// Your animation loop
let startTime = Date.now();
function animate() {
  requestAnimationFrame(animate);
  
  const currentTime = (Date.now() - startTime) / 1000;
  const state = reconcile_animationState2D(reconciled, currentTime);
  
  state.models.forEach((modelState, modelID) => {
    // Update your 2D rendering
    drawSprite(modelID, {
      x: modelState.position.x,
      y: modelState.position.y,
      angle: modelState.rotation,
      opacity: modelState.opacity,
      scale: modelState.scale
    });
  });
}
animate();

Camera Animation

import { NodeCamera2D, Vector2 } from 'hw-ts-parametric-sequencer/2d';

const cameraNode = new NodeCamera2D({
  name: 'camera-pan',
  chapter: 'intro',
  time: { type: 'absolute', value: 0 },
  duration: 2,
  pan: new Vector2(50, 0), // Pan right
  zoom: 1.2, // Zoom in
  rotation: 15 // Rotate 15 degrees
});

Relative Timing

You can start animations relative to other animations. For example, start a camera animation 0.5 seconds after a model animation starts:

// Start camera animation 0.5 seconds after model animation starts
const cameraNode = new NodeCamera2D({
  name: 'camera-follow',
  chapter: 'intro',
  time: {
    type: 'relative',
    value: {
      offset: 0.5,
      side: 'Start',
      parentID: 'move-sprite'
    }
  },
  duration: 1.5,
  pan: new Vector2(0, 0),
  zoom: 1.0,
  rotation: 0
});

Reveal and Hide Animations

import { NodeBasicReveal2D, NodeBasicHide2D, Vector2 } from 'hw-ts-parametric-sequencer/2d';

// Reveal a sprite with fade-in
const reveal = new NodeBasicReveal2D({
  name: 'reveal-sprite',
  chapter: 'intro',
  sceneObject: object,
  time: { type: 'absolute', value: 0 },
  duration: 1,
  startingPosition: new Vector2(-100, 0),
  startingRotation: 0
});

// Hide a sprite with fade-out
const hide = new NodeBasicHide2D({
  name: 'hide-sprite',
  chapter: 'outro',
  sceneObject: object,
  time: { type: 'absolute', value: 5 },
  duration: 1,
  offsetPosition: new Vector2(0, -50), // Move down while hiding
  offsetRotation: 180 // Rotate while hiding
});

Marker-Based Positioning

Position an object relative to a marker on another object:

import { NodeToMarkerPosition2D } from 'hw-ts-parametric-sequencer/2d';

// Position an object relative to a marker on another object
const marker = parentObject.getMarker('attachment-point');
const attachNode = new NodeToMarkerPosition2D({
  name: 'attach-part',
  chapter: 'assembly',
  sceneObject: partObject,
  time: { type: 'absolute', value: 2 },
  marker: marker,
  offset_position: new Vector2(0, 0),
  offset_rotation: 0
});