Skip to content

Releases: AlfredBateman/CanvasLint

CanvasLint 1.1.0

Choose a tag to compare

@AlfredBateman AlfredBateman released this 18 Oct 11:52

CanvasLint records what a web page draws on a canvas (the drawing area games, charts and drawing apps use) and shows it in a DevTools panel. You can drag along a timeline like scrubbing a video, pick any moment, and see the canvas as it was and the drawing instructions that made it.

What's new in 1.1.0

  • Recording is now per canvas and per animation frame, so several canvases and several tabs work, each tab with its own history. The old approach that guessed where a drawing started and ended is gone.
  • Capture starts before the page's own scripts run.
  • New: seven lint checks on the frame you are viewing (blurry on high-DPI screens, a setting set to the value it already has, save() and restore() that don't pair up, repeated getImageData without willReadFrequently, a shadow in a busy frame, drawImage at fractional positions, and a frame identical to the one before, which is a guess).
  • New: a State inspector that shows the canvas's settings after the selected command and what that command changed.
  • New: export a canvas's recording to a file and import it again.
  • A redesigned panel with dark and light themes and keyboard control.
  • Replay fixes: a clip or the current path no longer leaks from one frame into another, Path2D replays correctly, and a bad setLineDash no longer stops the rest of a frame.
  • Pause, Resume and Reset now reach the page.
  • Faster capture. On my benchmark page (7,034 mostly numeric commands per frame, idle machine, medians of 3 runs of 30 s) a frame takes 4.10 ms with the extension and 3.76 ms without it, and the worker spends 1.69 ms of CPU per page frame. This is one load; strings, gradients and images were not measured. Details in docs/PERF.md.

What it cannot do yet

  • If a page draws one canvas onto another (drawImage with a canvas as the source), that part is not replayed and the panel says so. Apps that cache layers this way, such as Excalidraw's scene canvas, replay empty or incomplete.
  • Each frame is replayed from a blank canvas; what earlier frames left behind is not carried over.
  • Gradients and patterns replay as transparent, and newer canvas methods such as roundRect are not drawn.
  • Only 2D canvases are captured: no WebGL or WebGPU, and no canvases inside iframes or web workers.
  • Only the frame you are viewing is linted, not the whole history.
  • The history cap is per tab (10,000 frames or about 32 MiB).
  • A page restored with the browser's Back button records nothing more until you reload it.
  • The panel is slower than before the lint pass and the redesign.

The full list is in the README.

Install

  1. Download canvas-lint-v1.1.0.zip below and unzip it.
  2. Open chrome://extensions in Chrome 114 or newer.
  3. Turn on Developer mode (top right).
  4. Click Load unpacked and select the unzipped folder.
  5. Open a page that uses a canvas, open DevTools on that tab and switch to the CanvasLint panel.

The extension itself sends nothing anywhere: what it records stays in memory unless you press Export. See the Privacy section of the README.

Canvas-Lint v1.0.0

Choose a tag to compare

@AlfredBateman AlfredBateman released this 27 Sep 19:12

CanvasLint is a Manifest V3 Chrome extension that lets you scrub through HTML5 Canvas 2D draw calls the way the Network panel lets you scrub through requests. It records every CanvasRenderingContext2D call a page makes, replays them into a DevTools panel, and lets you drag a slider through the command history to see exactly what the canvas looked like at any point.

Install

  1. Download canvas-lint-v1.0.0.zip below.
  2. Unzip it.
  3. Open chrome://extensions in Chrome.
  4. Enable Developer mode (top right toggle).
  5. Click Load unpacked and select the unzipped folder.

Before you rely on this

This is mid-build software, not a finished tool. The capture pipeline, ring buffer, and basic replay work, but several things don't yet — no render-block parser, no live panel updates, one capture buffer shared across all open tabs, and the pause/resume/reset controls don't currently reach the page. Full details are in the README's Known Limitations section — read it before you depend on this for anything beyond casual debugging.