Skip to content

Add an experimental Pixi renderer for the canvas - #9509

Draft
kube wants to merge 1 commit into
claude/canvas-renderer-interfacefrom
claude/canvas-pixi-renderer
Draft

Add an experimental Pixi renderer for the canvas#9509
kube wants to merge 1 commit into
claude/canvas-renderer-interfacefrom
claude/canvas-pixi-renderer

Conversation

@kube

@kube kube commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Important

Experimental
Opt-in through the Renderer viewport setting.

Summary

Before this PR, the canvas had one renderer, React Flow. Every node is a DOM element and every hover, selection or playback frame re-renders the React tree, so nets of a thousand nodes stutter during playback.

Adds a Pixi.js renderer behind the canvas contract, chosen from Viewport settings > Renderer. It draws the same nets, tools, settings and playback animation as React Flow on a GPU canvas. Playback animation runs on the Pixi ticker as buffer writes instead of React re-renders.

9509.mp4

Links

Changes

Settings

  • canvasRenderer user setting with a Renderer row in the viewport settings dialog

    Values are react-flow and pixi, default React Flow.
    Row carries an Experimental chip.

Renderer shell

  • PixiCanvas mounts a Pixi Application inside a DOM host

    Host owns gestures, cursor, place-state tooltip, minimap and viewport controls.
    Declared as arch-docs layer ui.views.canvas.pixi.

  • Viewport store with React Flow's zoom limits and wheel factor

    Implements CanvasController, so the shared viewport controls and recenter hook work unchanged.

  • SVG minimap and DOM tooltip

    Minimap drag pans the view.
    Tooltip shows the token state of the hovered place when frames exist.

  • Colours come from the Panda tokens on .petrinaut-root, labels from a bitmap font installed from Inter Variable once it has loaded
  • pixi.js and @pixi/react added as dependencies and Vite externals

Drawing

  • Nodes drawn with Graphics and BitmapText

    Compact and classic places and transitions, component instances, selection and hover outlines, dimming, token badges and firing bolts follow the React Flow visuals.

  • Arcs as one merged ribbon mesh with per-vertex width and colour

    Straight, square, bezier and adaptive bezier paths match the React Flow styles.
    Read arcs are dashed, inhibitor arcs get their disc, weights get labels, selected arcs get halos.

  • Firing animation writes buffers on the ticker

    A frame store mirrors the execution frame source.
    PixiAnimator drives pulse, flash and bolt timelines with useTick and updates token badges.

Interaction

  • Gestures handled on the DOM host with hit testing against scene geometry

    Pan by drag, middle button or Space, wheel zoom, node drag with snapping, partial or full box selection per setting, connect from handles with validation, click to place.

  • Same semantics as React Flow

    Every gesture ends in a useCanvasInteractions call, so selection, snapping and connection rules stay shared.

Known issues

  • Needs WebGL

    Pixi 8 has no canvas fallback, so a browser without WebGL gets no drawing. React Flow stays the default.

  • Bitmap font labels differ slightly from DOM text

    Weight and anti-aliasing are not identical to the React Flow nodes.

Next steps

  • Compare both renderers on large nets before deciding on a default

Test coverage

  • Existing canvas-scene.test.ts and canvas-viewport.test.ts:

    Scene and viewport math the renderer consumes. No renderer-specific automated tests.

  • Headless Playwright script against the production build:

    Drag, connect, box select, click to place, wheel zoom and pan, playback animation, minimap and tooltip.

How to test

  • Open Petrinaut preview on Vercel
  • Viewport controls > Settings > Renderer > Pixi
  • Load example > SIR
  • Add places, transitions and a component instance, connect ports, select and box select, drag with snap to grid
  • Viewport controls > Settings > switch arc style and compact nodes, toggle minimap
  • Simulate > Run, play back
  • Expect arcs to pulse and transitions to flash as with React Flow
  • Viewport controls > Settings > Renderer > React Flow
  • Expect same net and selection

@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Sep 3, 2026 11:52pm UTC
petrinaut Ready Ready Preview Sep 3, 2026 11:52pm UTC
petrinaut-docs Ready Ready Preview Sep 3, 2026 11:52pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
hashdotdesign-tokens Ignored Ignored Preview Sep 3, 2026 11:52pm UTC

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

1 participant