mwg API
    Preparing search index...

    Interface ViewportOptions

    A view onto a world larger than the screen.

    The camera does not move: it moves the world under a fixed viewport, which is what a renderer actually wants. world is the container to put the map and its inhabitants in; anything that should stay put on screen (the HUD, a dialogue box) goes outside it. The same answers "does rotation turn the camera or the world": the layer turns, once, about the view centre - never a per-tile transform, which is what keeps rotated tiles seamless and the per-frame cost flat regardless of map size.

    Positions are in world units. At zoom = 3 a 16px tile is 48 screen pixels.

    Rotation has two APIs sharing one angle: setRotationStep/rotate turn in the whole steps a grid closes on (item 285 - four quarter turns for a square map, six 60-degree steps for a hex one), while rotateTo/animateRotationTo turn to any angle at all (item 286), animating smoothly between two steps rather than only landing on them. toScreen/ toWorld/view's culling box already work at any angle, not only a step's whole multiple, so free rotation needed no change to either.

    import { Camera, createCamera } from '@datamoc/mw_games/two-d/render';
    import type { Container2D } from '@datamoc/mw_games/two-d/render';

    declare const stage: Container2D;
    declare const hero: { x: number; y: number };

    const camera = createCamera({ zoom: 3, deadzone: 0.3, pixelPerfectTileSize: 16 });
    stage.addChild(camera.world);
    camera.follow(hero);

    function onFrame(dt: number): void {
    camera.update(dt);
    }
    interface ViewportOptions {
        deadzone?: number;
        grid?: "square" | "hex";
        height: number;
        pixelPerfectTileSize?: number;
        width: number;
        x: number;
        y: number;
        zoom?: number;
    }

    Hierarchy (View Summary)

    Index
    deadzone?: number

    How much of the screen the target may drift across before the camera follows, 0 to 1.

    0 pins the target to the centre, which is precise but makes the world lurch on every step. 0.3 lets it wander through the middle third, which reads far calmer in a grid-based game where movement is in whole tiles.

    grid?: "square" | "hex"

    The grid whose symmetry rotate/setRotationStep step in: 'square' (the default) turns in four quarter turns, 'hex' in six 60-degree steps, because a hex lattice comes back onto itself every 60 degrees. Only the step count depends on this; the layer and its inverse mapping are the same shape either way.

    height: number
    pixelPerfectTileSize?: number

    When set, zoom snaps to the nearest value at which one world unit of this size lands on a whole number of screen pixels - a tile's own width or height, typically.

    apply() already rounds the whole camera's screen offset to a whole pixel, which stops pixel art shimmering as the camera moves, but at a fractional zoom each tile's own edge still lands on a different sub-pixel offset depending on its position, so nearest-neighbour sampling rounds one tile's edge column one way and its neighbour's the other - a thin seam between tiles that camera-level rounding alone cannot fix. Snapping zoom itself so tile-size × zoom is always a whole number closes the gap at its source, without a per-tile sampling flag.

    width: number
    x: number

    this viewport's own rectangle of the screen, in pixels

    y: number
    zoom?: number

    screen pixels per world unit