Animations-Demo — Einblenden eines Overlay-Bildes über einem Hintergrund.

Demonstriert eine Zwei-Ebenen-Animation, bei der ein Overlay-Bild von links über ein Hintergrundbild in den Frame gleitet. Zeigt die Kombination mehrerer Eingabebilder und die Animation ihrer relativen Positionen.

BG
BG — Animations-Demo — Einblenden eines Overlay-Bildes über einem Hintergrund.
OVERLAY
OVERLAY — Animations-Demo — Einblenden eines Overlay-Bildes über einem Hintergrund.
OUTPUT
OUTPUT — Animations-Demo — Einblenden eines Overlay-Bildes über einem Hintergrund.
JavaScript
// Animation demo — slide-in of an overlay image over a background.
// anim_slide_in.js
//!INPUT: BG
//!INPUT: OVERLAY
//!OUTPUT: OUTPUT
//!PARAM: STEPS:integer=30,min=1,max=200
//!PARAM: HOLD_MS:integer=500,min=0,max=10000

// Composes a 2-input animation:
//   1. Hold the BG image for HOLD_MS milliseconds
//   2. Slide OVERLAY in from the left edge (negative offset → 0)
//      over STEPS frames, then hold for HOLD_MS milliseconds.
//
// The Animation container's canvas matches BG's resolution. Each
// frame is a fresh BG clone with OVERLAY blended on top at the
// current X-offset. Off-canvas portions of OVERLAY are silently
// clipped by the engine's blend op + the animation's own clipper.

const bg      = Engine.loadImage(BG);
const overlay = Engine.loadImage(OVERLAY);

const anim = Engine.animation(bg.width, bg.height, { loop: 0 });

// Initial hold on the bare background.
anim.addFrame(bg, { delay: HOLD_MS });

// Slide-in: overlay slides from left edge to its rest position
// roughly centered vertically.
const restY = Math.floor((bg.height - overlay.height) / 2);
const startX = -overlay.width;
const endX = Math.floor((bg.width - overlay.width) / 2);

for (let s = 0; s < STEPS; s++) {
  const t = s / (STEPS - 1);
  const x = Math.round(startX + (endX - startX) * t);
  const composed = bg.clone().blendAt(overlay, px(x, restY), 1.0);
  anim.addFrame(composed, { delay: 33 });   // ~30 fps
  composed.free();
}

// Final hold on the resting frame.
const final = bg.clone().blendAt(overlay, px(endX, restY), 1.0);
anim.addFrame(final, { delay: HOLD_MS });
final.free();

// saveAPNG would also work; saveWebP lossy keeps the gallery asset
// small (~85 % smaller than APNG) at visually identical quality.
anim.saveWebP(OUTPUT, { lossy: true, quality: 85 });
anim.free();
bg.free();
overlay.free();

// © 2026 Michael Lechner · mlc OpticScript · https://mlcgo.eu · Elastic License 2.0