Deformations

Simple animations with updateTransform: pulsing scale, rotation, and vertical offset.

Transport

You are viewing: Browser (WASM) · Switch

In the browser, use a canvas with id vulfram-canvas.

Key steps

1. Create the base model.

2. Accumulate time inside the loop.

3. Update position, rotation, and scale every frame.

Full example

ts
import {
  initEngine,
  createWorld,
  createWindow,
  createEntity,
  createCamera,
  createLight,
  createGeometry,
  createMaterial,
  createModel,
  createTexture,
  updateTransform,
  tick,
} from '@vulfram/engine';
import { initWasmTransport, transportWasm } from '@vulfram/transport-wasm';

const WINDOW_ID = 1;

async function boot() {
  await initWasmTransport();
  initEngine({ transport: transportWasm });
  createWorld(WINDOW_ID);
  createWindow(WINDOW_ID, {
    title: 'Deformations',
    size: [1100, 700],
    position: [0, 0],
    canvasId: 'vulfram-canvas',
  });

  const camera = createEntity(WINDOW_ID);
  updateTransform(WINDOW_ID, camera, { position: [0, 2.5, 8], rotation: [0, 0, 0, 1], scale: [1, 1, 1] });
  createCamera(WINDOW_ID, camera, { kind: 'perspective', near: 0.1, far: 100.0 });

  const light = createEntity(WINDOW_ID);
  updateTransform(WINDOW_ID, light, { position: [2, 5, 6], rotation: [0, 0, 0, 1], scale: [1, 1, 1] });
  createLight(WINDOW_ID, light, { kind: 'point', intensity: 16, range: 30 });

  const texId = createTexture(WINDOW_ID, { source: { type: 'color', color: [0.4, 0.8, 0.9, 1] }, srgb: true });
  const matId = createMaterial(WINDOW_ID, {
    kind: 'standard',
    options: {
      type: 'standard',
      content: {
        baseColor: [1, 1, 1, 1],
        surfaceType: 'opaque',
        baseTexId: texId,
        baseSampler: 'linear-clamp',
        flags: 0,
      },
    },
  });
  const geomId = createGeometry(WINDOW_ID, { type: 'primitive', shape: 'cube' });

  const cube = createEntity(WINDOW_ID);
  createModel(WINDOW_ID, cube, { geometryId: geomId, materialId: matId, castShadow: true, receiveShadow: true });

  let last = performance.now();
  let t = 0;
  function frame(now: number) {
    const delta = now - last;
    last = now;
    t += delta / 1000;

    const angle = t * 1.5;
    const half = angle * 0.5;
    const q: [number, number, number, number] = [0, Math.sin(half), 0, Math.cos(half)];
    const scale = 0.8 + Math.sin(t * 2.1) * 0.2;

    updateTransform(WINDOW_ID, cube, {
      position: [0, Math.sin(t) * 0.4, 0],
      rotation: q,
      scale: [scale, scale * 1.2, scale],
    });

    tick(now, delta);
    requestAnimationFrame(frame);
  }
  requestAnimationFrame(frame);
}

boot().catch(console.error);
Live demo canvas