Layers & Frames

OpenGPEX organizes content into Frames (artboards) containing Layers (visual elements). This page explains the data model, layer types, and how they map to the normalized state architecture.


Frames (Artboards)

A Frame is a top-level canvas container with its own:

  • Dimensions (width × height in pixels)
  • Background color (or transparent)
  • Camera state (pan, zoom level)
  • Layer stack (ordered collection of layers)

You can have multiple frames in a single project — useful for designing multiple views or sizes simultaneously.


Layer Types

Type Description Use Case
Bitmap Raster pixel data (photos, paintings) Most common layer type
Text Editable vector text with font styling Headlines, labels
Group Container holding child layers Organizational hierarchy
Adjustment Non-destructive filter (brightness, contrast) Color correction
Mask Alpha channel controlling parent visibility Selective reveal/hide

Layer Properties

Every layer has these core properties:

interface Layer {
  id: string;           // Unique identifier
  name: string;         // User-visible label
  type: LayerType;      // bitmap | text | group | adjustment | mask
  visible: boolean;     // Eye toggle
  locked: boolean;      // Prevent edits
  opacity: number;      // 0.0 – 1.0
  blendMode: string;    // normal, multiply, screen, overlay, etc.

  // Geometry (local coordinate space)
  x: number;            // Position X
  y: number;            // Position Y
  width: number;        // Display width
  height: number;       // Display height
  rotation: number;     // Degrees
  scaleX: number;       // Horizontal scale
  scaleY: number;       // Vertical scale

  // Assets
  assetId?: string;     // SHA-256 hash → CAS blob store
  masks?: MaskDescriptor[];  // Attached clip masks
}

Z-Order and the order Array

Layers render bottom-to-top based on their position in the order array:

order: ["layer-bg", "layer-photo", "layer-text"]
         ▲                                  ▲
         Bottom (drawn first)               Top (drawn last, visible on top)

To move a layer up or down, you only rearrange the order array — the layer objects themselves are not touched.


Normalized State Mapping

Frames and layers both use the NormalizedState<T> pattern:

// State tree shape
state.frames = {
  byId: {
    "frame-1": {
      id: "frame-1",
      width: 1920,
      height: 1080,
      layers: {
        byId: {
          "layer-bg": { id: "layer-bg", type: "bitmap", ... },
          "layer-text": { id: "layer-text", type: "text", ... },
        },
        order: ["layer-bg", "layer-text"],
      },
    },
  },
  order: ["frame-1"],
};

This structure provides O(1) lookups and minimal undo patches. See State Management for details.


Common Operations

Operation Action Undo Behavior
Add layer actions.addLayers() Remove on undo
Delete layer actions.removeLayers() Restore on undo
Move layer (Z-order) Rearrange order array Swap back on undo
Duplicate layer actions.adv.duplicateLayer() Remove clone on undo
Merge down actions.adv.mergeDown() Restore both layers
Group layers actions.adv.groupLayers() Ungroup on undo

Non-Destructive Editing

OpenGPEX preserves original pixel data at all times:

  1. Original asset stored in CAS (Content-Addressable Storage) by SHA-256 hash
  2. Layer metadata (position, scale, rotation, masks) stored as lightweight numbers
  3. Rendering combines asset + metadata on-the-fly — original is never modified
  4. Undo simply reverts metadata patches — no need to restore pixel data

Next Steps


Last updated: 2026-06-14