Skip to content

feat: common.attachAutoResizer - #2534

Open
iwoplaza wants to merge 12 commits into
mainfrom
feat/resize-common
Open

iwoplaza wants to merge 12 commits into
mainfrom
feat/resize-common

Conversation

@iwoplaza

@iwoplaza iwoplaza commented May 21, 2026 •

Copy link
Copy Markdown
Collaborator

This PR adds a new common helper called attachAutoResizer which adapts the canvas' internal resolution to match its physical pixel size, with additional safe-guards. It's a web only helper, not to be used in React Native apps.

The examples were updated to use this helper, which replaces the need for the example environment to handle the canvas resizing. This also makes the examples much more portable, as resizing a canvas can be tricky to get right, and now it's solved in every example.

@iwoplaza iwoplaza added this to the 0.11.5 milestone May 21, 2026
@github-actions

github-actions Bot commented May 21, 2026 •

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/tgpu-gen@0a967c1db2b5fadd79721e64557c847e0b11fb45
https://pkg.pr.new/software-mansion/TypeGPU/typegpu@0a967c1db2b5fadd79721e64557c847e0b11fb45
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/cli@0a967c1db2b5fadd79721e64557c847e0b11fb45
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/gl@0a967c1db2b5fadd79721e64557c847e0b11fb45

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented May 21, 2026 •

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased (max 1.28%) ❔ Unknown
0 353 2 1

import * as ... in PR vs import * as ... in target (did bundle size increase?):

Test tsdown
STATIC_common.ts 57.00 kB ($${\color{red}+1.3\%}$$)
common_attachAutoResizer.ts 722 B

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@github-actions

github-actions Bot commented May 21, 2026 •

Copy link
Copy Markdown

Resolution Time Benchmark

---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [1.04, 2.03, 4.43, 6.49, 7.73, 14.50, 25.14, 28.77]
  line [1.01, 2.05, 4.52, 6.60, 8.34, 13.38, 25.48, 26.53]
  line [1.01, 2.05, 4.72, 6.91, 8.61, 13.25, 26.78, 27.47]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.30, 0.54, 0.71, 0.89, 1.15, 1.23, 1.52, 1.63]
  line [0.29, 0.52, 0.71, 0.88, 1.17, 1.26, 1.46, 1.62]
  line [0.30, 0.50, 0.75, 0.93, 1.30, 1.26, 1.56, 1.70]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.84, 2.16, 4.12, 6.93, 12.61, 27.37, 57.64, 118.83]
  line [0.86, 2.37, 3.59, 7.20, 14.42, 28.37, 58.94, 119.49]
  line [0.99, 2.24, 4.16, 7.04, 13.19, 27.22, 60.21, 122.53]
Loading

Comment thread packages/typegpu/src/common/attachAutoResizer.ts Outdated
Comment thread packages/typegpu/src/common/attachAutoResizer.ts Outdated
@iwoplaza
iwoplaza force-pushed the feat/resize-common branch from 64f3189 to 4567fed Compare May 26, 2026 14:41
@iwoplaza
iwoplaza force-pushed the feat/resize-common branch 8 times, most recently from df4e541 to 11345a6 Compare June 17, 2026 17:52
@iwoplaza

Copy link
Copy Markdown
Collaborator Author

@pullfrog Review this one please 🙏

@iwoplaza
iwoplaza force-pushed the feat/resize-common branch from b7bbb8b to 11fccf5 Compare June 17, 2026 20:39

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed changes — adds common.attachAutoResizer, a web helper that adapts the canvas' internal resolution to match its physical pixel size using ResizeObserver, then migrates all docs examples and CLI templates to use it.

  • Add attachAutoResizer helper — new common/attachAutoResizer.ts exports attachAutoResizer() with AttachAutoResizerOptions (root, canvas, optional onResize callback) and returns an AutoResizer with a detach() cleanup method. Internally uses ResizeObserver with a device-pixel-content-box fallback and clamps dimensions to the GPU's maxTextureDimension2D.
  • Migrate ~45 docs examples — each example's index.ts now imports common from typegpu, calls common.attachAutoResizer(), and calls autoResizer.detach() in onCleanup(). Standalone fullScreenTriangle imports are consolidated to common.fullScreenTriangle. Example canvases in index.html gain class="w-full h-full" for CSS-driven sizing.
  • Remove useResizableCanvas — the example-view React hook and its ~80 lines of canvas DOM manipulation are deleted, simplifying the docs app.
  • Trim stackBlitzIndex.ts — the embedded canvas-resize script (~50 lines of ResizeObserver + DOM wrapping) is removed since examples now self-resize.
  • Update CLI templates — both template-vite-simple and template-vite-complex replace manual ResizeObserver setup with common.attachAutoResizer().

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the feat/resize-common branch from 11fccf5 to c59c2a7 Compare June 18, 2026 08:00
@iwoplaza
iwoplaza marked this pull request as ready for review June 18, 2026 08:00

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one minor suggestion inline.

Reviewed changes — adds common.attachAutoResizer, a ResizeObserver-based helper that adapts a canvas' internal resolution to its physical pixel size, with device-pixel-content-box / content-box fallback and maxTextureDimension2D clamping. Replaces duplicate resize logic across all examples, templates, the docs ExampleView component, and the StackBlitz wrapper.

  • New attachAutoResizer helper at packages/typegpu/src/common/attachAutoResizer.ts — observes a canvas, sets canvas.width/canvas.height with DPR awareness and device-limit clamping, returns a { detach } handle. Exported via packages/typegpu/src/common/index.ts under the common namespace.
  • Docs ExampleView.tsx cleanup — removes the useResizableCanvas hook and its DOM-scaffolding logic (~80 lines). Example canvases are now sized via inline Tailwind classes (w-full h-full) and each example manages its own attachAutoResizer lifecycle.
  • StackBlitz wrapper cleanup — removes the inline canvas resize loop (~50 lines) from stackBlitzIndex.ts. Examples in StackBlitz now resize via their own attachAutoResizer calls.
  • Example updates — every example index.html replaces bare <canvas> / data-fit-to-container with <canvas class="w-full h-full" /> (and object-contain where appropriate). Every example index.ts imports common from typegpu, switches fullScreenTriangle → common.fullScreenTriangle, and calls attachAutoResizer with onResize (for animated examples) or without (for requestAnimationFrame loops). Cleanup hooks call autoResizer.detach() before root.destroy().
  • CLI template updates — template-vite-simple and template-vite-complex replace inline ResizeObserver code with common.attachAutoResizer, demonstrating the intended usage.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu/src/common/attachAutoResizer.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new common.attachAutoResizer helper in typegpu to keep a canvas’s internal pixel resolution in sync with its displayed size (including DPR handling), and migrates the CLI templates + docs examples to use it so resizing no longer depends on the docs/StackBlitz “environment” code.

Changes:

  • Added packages/typegpu/src/common/attachAutoResizer.ts and exported it from common.
  • Updated templates and a large set of docs examples to use common.attachAutoResizer() and detach it during cleanup.
  • Simplified docs/StackBlitz canvas-environment resizing logic by removing the previous “wrap/replace canvas + ResizeObserver” approach.

Reviewed changes

Copilot reviewed 147 out of 147 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
packages/typegpu/src/common/index.ts Exports the new auto-resizer helper from common.
packages/typegpu/src/common/attachAutoResizer.ts Implements attachAutoResizer using ResizeObserver.
packages/typegpu-cli/templates/template-vite-simple/src/main.ts Replaces inline ResizeObserver resizing with common.attachAutoResizer.
packages/typegpu-cli/templates/template-vite-complex/src/main.ts Uses common.attachAutoResizer and renames render loop function to frame.
apps/typegpu-docs/src/examples/threejs/varyings/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/threejs/test-reused-functions/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/threejs/test-mismatched-types/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/threejs/simple/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/threejs/compute-particles/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/threejs/compute-particles-snow/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/threejs/compute-geometry/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/threejs/compute-cloth/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/threejs/attractors/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/tests/uniformity/index.ts Uses attachAutoResizer and detaches on cleanup; redraws on resize.
apps/typegpu-docs/src/examples/tests/uniformity/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/tests/texture-test/index.ts Adds attachAutoResizer and detaches on cleanup.
apps/typegpu-docs/src/examples/tests/texture-test/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/tests/sdf-docs-examples/index.ts Adds attachAutoResizer and detaches on cleanup.
apps/typegpu-docs/src/examples/tests/sdf-docs-examples/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/tests/rc-docs-examples/index.ts Adds attachAutoResizer and detaches on cleanup.
apps/typegpu-docs/src/examples/tests/rc-docs-examples/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/tests/log-test/index.ts Imports common, adds attachAutoResizer, detaches on cleanup.
apps/typegpu-docs/src/examples/tests/log-test/index.html Updates canvas tag formatting.
apps/typegpu-docs/src/examples/simulation/wind-map/index.ts Uses attachAutoResizer with square aspect enforcement and redraw.
apps/typegpu-docs/src/examples/simulation/wind-map/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/stable-fluid/index.ts Adds attachAutoResizer, refactors render loop, updates pointer mapping for square canvas.
apps/typegpu-docs/src/examples/simulation/stable-fluid/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/slime-mold/index.ts Adds attachAutoResizer and refactors render call; detaches on cleanup.
apps/typegpu-docs/src/examples/simulation/slime-mold/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts Adds attachAutoResizer, refactors render call; detaches on cleanup.
apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/gravity/index.ts Replaces ResizeObserver with attachAutoResizer for depth texture recreation.
apps/typegpu-docs/src/examples/simulation/gravity/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/game-of-life/input.ts Adjusts input coordinate mapping for square aspect and uses std.saturate.
apps/typegpu-docs/src/examples/simulation/game-of-life/index.ts Adds attachAutoResizer and refactors display draw into render().
apps/typegpu-docs/src/examples/simulation/game-of-life/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/fluid-with-atomics/index.ts Adds attachAutoResizer with square resizing and redraw.
apps/typegpu-docs/src/examples/simulation/fluid-with-atomics/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/fluid-double-buffering/index.ts Adds attachAutoResizer with square resizing and redraw.
apps/typegpu-docs/src/examples/simulation/fluid-double-buffering/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/confetti/index.ts Adds attachAutoResizer and detaches on cleanup.
apps/typegpu-docs/src/examples/simulation/confetti/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simulation/boids/index.ts Refactors to render() + uses attachAutoResizer for square resizing and redraw.
apps/typegpu-docs/src/examples/simulation/boids/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simple/vaporrave/index.ts Refactors draw to render() and uses attachAutoResizer.
apps/typegpu-docs/src/examples/simple/vaporrave/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simple/triangle/index.ts Imports common, uses attachAutoResizer, refactors constants; detaches on cleanup.
apps/typegpu-docs/src/examples/simple/triangle/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simple/stencil/index.ts Replaces ResizeObserver with attachAutoResizer (square + texture recreation).
apps/typegpu-docs/src/examples/simple/stencil/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simple/square/index.ts Uses attachAutoResizer to drive initial render + rerender on resize.
apps/typegpu-docs/src/examples/simple/square/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simple/ripple-cube/post-processing.ts Refactors post-processing to support resizing and exposes a user storage binding group.
apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts Integrates resizable post-processing and uses attachAutoResizer to resize pipelines.
apps/typegpu-docs/src/examples/simple/ripple-cube/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simple/oklab/index.ts Adjusts pointer mapping + uses attachAutoResizer; detaches on cleanup.
apps/typegpu-docs/src/examples/simple/oklab/index.html Wraps canvas/probe markup; updates canvas classes.
apps/typegpu-docs/src/examples/simple/mesh-skinning/index.ts Replaces ResizeObserver with attachAutoResizer to recreate depth/MSAA textures.
apps/typegpu-docs/src/examples/simple/mesh-skinning/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simple/liquid-glass/index.ts Splits render/frame loop and uses attachAutoResizer for square resizing.
apps/typegpu-docs/src/examples/simple/liquid-glass/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/simple/gradient-tiles/index.ts Uses attachAutoResizer for square resizing and redraw.
apps/typegpu-docs/src/examples/simple/gradient-tiles/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/xor-dev-runner/index.ts Imports common, uses attachAutoResizer, detaches on cleanup.
apps/typegpu-docs/src/examples/rendering/xor-dev-runner/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/xor-dev-centrifuge-2/index.ts Imports common, uses attachAutoResizer, detaches on cleanup.
apps/typegpu-docs/src/examples/rendering/xor-dev-centrifuge-2/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/two-boxes/index.ts Replaces ResizeObserver with attachAutoResizer (square + texture recreation).
apps/typegpu-docs/src/examples/rendering/two-boxes/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/suika-sdf/index.ts Replaces ResizeObserver with attachAutoResizer; refactors into render().
apps/typegpu-docs/src/examples/rendering/suika-sdf/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/smoky-triangle/index.ts Refactors draw to render() and uses attachAutoResizer for square resizing.
apps/typegpu-docs/src/examples/rendering/smoky-triangle/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/simple-shadow/index.ts Replaces ResizeObserver with attachAutoResizer, refactors into render() + frame().
apps/typegpu-docs/src/examples/rendering/simple-shadow/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/render-bundles/index.ts Refactors to render() and uses attachAutoResizer to redraw on resize.
apps/typegpu-docs/src/examples/rendering/render-bundles/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/render-bundles-with/index.ts Refactors to render() and uses attachAutoResizer to redraw on resize.
apps/typegpu-docs/src/examples/rendering/render-bundles-with/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/ray-marching/index.ts Uses attachAutoResizer and detaches on cleanup.
apps/typegpu-docs/src/examples/rendering/ray-marching/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/radiance-cascades/index.ts Replaces ResizeObserver with attachAutoResizer + debounce; enforces square.
apps/typegpu-docs/src/examples/rendering/radiance-cascades/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/radiance-cascades-drawing/index.ts Uses attachAutoResizer and switches scene resolution to fixed 1024².
apps/typegpu-docs/src/examples/rendering/radiance-cascades-drawing/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/radiance-cascades-drawing/drawInteraction.ts Updates pointer mapping for square aspect ratio.
apps/typegpu-docs/src/examples/rendering/pom/index.ts Replaces ResizeObserver with attachAutoResizer (depth recreate + redraw).
apps/typegpu-docs/src/examples/rendering/pom/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/point-light-shadow/index.ts Refactors render/frame loops and uses attachAutoResizer (square + texture recreate).
apps/typegpu-docs/src/examples/rendering/point-light-shadow/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/phong-reflection/index.ts Refactors to render() and uses attachAutoResizer (depth recreate + redraw).
apps/typegpu-docs/src/examples/rendering/phong-reflection/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/perlin-noise/index.ts Refactors draw to render() and uses attachAutoResizer for square resizing.
apps/typegpu-docs/src/examples/rendering/perlin-noise/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/os-awards/index.ts Replaces ResizeObserver with attachAutoResizer (depth recreate + redraw).
apps/typegpu-docs/src/examples/rendering/os-awards/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/jelly-switch/index.ts Refactors render loop and uses attachAutoResizer to drive handleResize().
apps/typegpu-docs/src/examples/rendering/jelly-switch/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/jelly-slider/index.ts Refactors render loop and uses attachAutoResizer to drive handleResize().
apps/typegpu-docs/src/examples/rendering/jelly-slider/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/function-visualizer/index.ts Replaces ResizeObserver with attachAutoResizer to recreate MSAA texture.
apps/typegpu-docs/src/examples/rendering/function-visualizer/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/disco/index.ts Splits render/frame and uses attachAutoResizer to redraw on resize.
apps/typegpu-docs/src/examples/rendering/disco/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/cubemap-reflection/index.ts Replaces ResizeObserver with attachAutoResizer and redraws on resize.
apps/typegpu-docs/src/examples/rendering/cubemap-reflection/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/clouds/types.ts Adds aspectRatio to params struct.
apps/typegpu-docs/src/examples/rendering/clouds/index.ts Uses attachAutoResizer, adds aspect-ratio uniform and low-res rendering behavior.
apps/typegpu-docs/src/examples/rendering/clouds/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/caustics/index.ts Refactors draw to render() and uses attachAutoResizer for square resizing.
apps/typegpu-docs/src/examples/rendering/caustics/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/box-raytracing/index.ts Refactors draw to render() and uses attachAutoResizer for square resizing.
apps/typegpu-docs/src/examples/rendering/box-raytracing/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/rendering/3d-fish/index.ts Refactors to render() and uses attachAutoResizer (projection + depth recreation + redraw).
apps/typegpu-docs/src/examples/rendering/3d-fish/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/react/spinning-triangle/index.tsx Adjusts canvas sizing classes in React example.
apps/typegpu-docs/src/examples/react/shifting-gradient/index.tsx Adjusts canvas sizing classes in React example.
apps/typegpu-docs/src/examples/image-processing/selfie-segmentation/index.ts Uses attachAutoResizer and detaches on cleanup.
apps/typegpu-docs/src/examples/image-processing/selfie-segmentation/index.html Converts hidden-video styling to Tailwind classes and updates canvas markup.
apps/typegpu-docs/src/examples/image-processing/image-tuning/index.ts Uses attachAutoResizer to render on resize; detaches on cleanup.
apps/typegpu-docs/src/examples/image-processing/image-tuning/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/image-processing/chroma-keying/index.ts Adds attachAutoResizer and refactors resize behavior via handleResize().
apps/typegpu-docs/src/examples/image-processing/chroma-keying/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/image-processing/camera-thresholding/index.ts Adds attachAutoResizer and refactors resize behavior via handleResize().
apps/typegpu-docs/src/examples/image-processing/camera-thresholding/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/image-processing/blur/index.ts Uses attachAutoResizer for square resizing and redraw.
apps/typegpu-docs/src/examples/image-processing/blur/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/image-processing/background-segmentation/index.ts Refactors to handleResize() and uses attachAutoResizer; detaches on cleanup.
apps/typegpu-docs/src/examples/image-processing/background-segmentation/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/image-processing/ascii-filter/index.ts Refactors to handleResize() and uses attachAutoResizer; detaches on cleanup.
apps/typegpu-docs/src/examples/image-processing/ascii-filter/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/geometry/lines-combinations/index.ts Replaces ResizeObserver with attachAutoResizer (square + texture recreate + redraw).
apps/typegpu-docs/src/examples/geometry/lines-combinations/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/geometry/circles/index.ts Replaces ResizeObserver with attachAutoResizer (square + texture recreate + render).
apps/typegpu-docs/src/examples/geometry/circles/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.ts Adds attachAutoResizer and detaches on cleanup.
apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.html Adjusts layout to flex and updates canvas markup/classes.
apps/typegpu-docs/src/examples/algorithms/jump-flood-voronoi/index.ts Replaces ResizeObserver with attachAutoResizer.
apps/typegpu-docs/src/examples/algorithms/jump-flood-voronoi/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/index.ts Replaces ResizeObserver with attachAutoResizer.
apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/algorithms/genetic-racing/index.ts Adds attachAutoResizer and detaches on cleanup.
apps/typegpu-docs/src/examples/algorithms/genetic-racing/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/examples/algorithms/bitonic-sort/index.ts Switches to common.fullScreenTriangle, adds attachAutoResizer, and detaches on cleanup.
apps/typegpu-docs/src/examples/algorithms/bitonic-sort/index.html Updates canvas markup/classes for new resizing approach.
apps/typegpu-docs/src/components/stackblitz/stackBlitzIndex.ts Removes the StackBlitz-side “resize canvases” environment logic.
apps/typegpu-docs/src/components/ExampleView.tsx Removes the docs-side “replace canvases + ResizeObserver” resizing hook; relies on examples.
Comments suppressed due to low confidence (2)

apps/typegpu-docs/src/examples/rendering/suika-sdf/index.html:5

  • <canvas ... /> is not a void element in HTML. The self-closing form will cause the following <link>/<style> tags to be parsed inside the canvas element when inserted via innerHTML. Use an explicit closing tag.
    apps/typegpu-docs/src/examples/image-processing/background-segmentation/index.html:5
  • <canvas ... /> is not a void element in HTML. The following <video> tag will be parsed as a child of the canvas when this markup is injected via innerHTML. Use </canvas>.
<canvas class="w-full h-full object-contain" />
<video
  autoplay
  playsinline
  class="absolute top-0 left-0 w-px h-px opacity-0 pointer-events-none"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/typegpu/src/common/attachAutoResizer.ts
Comment thread packages/typegpu/src/common/attachAutoResizer.ts
Comment thread apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts
Comment thread apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts
Comment thread apps/typegpu-docs/src/examples/simple/oklab/index.html
Comment thread apps/typegpu-docs/src/examples/threejs/compute-geometry/index.html
Comment thread apps/typegpu-docs/src/examples/image-processing/selfie-segmentation/index.html Outdated
Comment thread apps/typegpu-docs/src/examples/simple/ripple-cube/post-processing.ts Outdated

@aleksanderkatan aleksanderkatan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread apps/typegpu-docs/src/examples/rendering/xor-dev-runner/index.html Outdated
Comment thread apps/typegpu-docs/src/examples/algorithms/bitonic-sort/index.html Outdated
const resizeObserver = new ResizeObserver(() => {
canvasRatioUniform.write(canvas.width / canvas.height);
redraw();
const autoResizer = common.attachAutoResizer({

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were three examples intentionally excluded from this change?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Three.js handles resizing on its own

Comment thread apps/typegpu-docs/src/examples/tests/texture-test/index.ts Outdated
Comment thread apps/typegpu-docs/src/examples/tests/sdf-docs-examples/index.ts
Comment thread apps/typegpu-docs/src/examples/tests/rc-docs-examples/index.ts Outdated
Comment thread apps/typegpu-docs/src/examples/tests/log-test/index.ts Outdated
@iwoplaza
iwoplaza force-pushed the feat/resize-common branch from c59c2a7 to 2d2827f Compare October 2, 2026 12:32

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

One example can still create 0-sized textures on collapse. Otherwise the attachAutoResizer rewrite and example migrations look good.

Reviewed changes — incremental delta since the prior pullfrog review (the branch was rebased onto main, so this covers the net changes over c59c2a7..2d2827f).

  • Hardened attachAutoResizer — physical size now resolves through devicePixelContentBoxSize → contentBoxSize (array or legacy single object) * dpr → contentRect * dpr, dimensions are rounded and clamped to [1, maxSize], device limits are read behind a try/catch for non-WebGPU roots, and observe() gained a bare-observe final fallback.
  • Example test harness — commonMocks.ts now stubs a global ResizeObserver that emits an initial 256x256 entry, so the migrated examples' resize path runs under test.
  • Canvas markup fix — all example index.html files converted self-closing <canvas ... /> to explicit <canvas ...></canvas>, which otherwise nested following nodes inside the canvas when injected via innerHTML.
  • Newly-added examples migrated — texture-gl, triangle-gl, triplanar-mapping, trippy-raymarching, global-illumination, and monocular-light-injection now use common.attachAutoResizer; several examples were split into scene.ts modules exposing onResize/onCleanup.
  • Prior review feedback — the redundant | undefined concern was discussed; the branch retains it intentionally (exact optional properties).

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the feat/resize-common branch from 2d2827f to 2b8e882 Compare October 6, 2026 11:28

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — minor suggestions inline.

Reviewed changes — incremental delta since the prior pullfrog review (range-diff 2d2827f..2b8e882; the branch was rebased, so this isolates the net change).

  • Migrated tests/triangle-targets — the example now calls common.attachAutoResizer; its one-shot draws moved into a render() that recreates secondTexture at the current canvas size and forces a 1:1 canvas, replacing the previous clientWidth * devicePixelRatio sizing.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread apps/typegpu-docs/src/examples/tests/triangle-targets/index.html Outdated
Comment thread apps/typegpu-docs/src/components/landing-examples/HoverExampleLive.tsx Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No new issues in this delta — prior review threads remain open.

Reviewed changes — incremental delta since the prior pullfrog review (range-diff 2b8e882..19645d6). Only commit 19645d6 ("Using onResize") introduces new content; the branch was rebased, so the other commits match the previously reviewed tree.

  • Switched the landing HoverExampleLive wrapper from common.attachAutoResizer (with autoResize: false) to useConfigureContext's built-in onResize, routing the example's onResize through a ref and invoking it once after async setup completes.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — incremental delta since the prior pullfrog review (19645d6..8a0c65e), commit 8a0c65e ("Address review comments").

  • Clamped jump-flood-distance's updateDimensions() with Math.max(1, ...), so a collapsed canvas yields a 1x1 render target instead of 0-sized textures.
  • Converted tests/triangle-targets/index.html's self-closing <canvas ... /> to an explicit <canvas ...></canvas>.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu-cli/templates/template-vite-bare/src/main.ts
canvas,
onResize() {
recreateResources();
clearCanvas();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
clearCanvas();
clearCanvas();
updateBrushSize();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

object-contain does not work well with fullscreen

Screen.Recording.2026-10-22.at.13.56.44.mov

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this, I am accounting for this now in the examples 👌

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stackblitz examples are now 300x150

Image

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because common.attachAutoResizer isn't published yet, and Stackblitz uses the pinned published version of typegpu


// Adjusting the resolution when the physical size of the canvas changes,
// and re-rendering the content.
common.attachAutoResizer({

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we to pin higher TypeGPU in package.json?

</div>

<canvas></canvas>
<canvas class="w-full h-full object-contain"></canvas>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

camera position changed

Image

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the preview to the bottom-left so it doesn't intersect with the controls. Otherwise, I think the change is harmless.

image

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one missed letterbox fix inline.

Reviewed changes — incremental delta since the prior pullfrog review (2d47878e5..79fd07ec3), commit 79fd07ec3 ("Fix pointer mapping in letterboxed examples").

  • Corrected pointer mapping into the object-contain square — liquid-glass (updatePosition) and radiance-cascades' drag controller (canvasToUV) now map clientX/clientY into the centered drawn square via Math.min(rect.width, rect.height) plus the (rect.width - size) / 2 center offset, instead of the full element box.
  • fluid-with-atomics cell mapping rewritten — the offsetX * devicePixelRatio helper (pointerCellFromCanvasOffset) is replaced by pointerCellFromClient, which maps into the drawn square and is now shared by both mouse and touch handlers.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread apps/typegpu-docs/src/examples/rendering/jelly-slider/index.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — incremental delta since the prior pullfrog review (79fd07ec3..4853241), commit 4853241e5 ("Fix pointer mapping in letterboxed jelly-slider example").

  • Fixed the missed letterbox mapping in jelly-slider — EventHandler.updateTargetMouseX (events.ts) now maps clientX into the centered drawn square via Math.min(rect.width, rect.height) and the (rect.width - size) / 2 offset, matching liquid-glass, radiance-cascades, and fluid-with-atomics, instead of normalizing over the full element box. Resolves the prior review's single inline thread.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

- Make attachAutoResizer more robust (rounding, contentBoxSize shapes,
  observe() without options, roots without a WebGPU device)
- Use explicit closing tags for <canvas> and <video>
- Keep the 1:1 aspect ratio in bitonic-sort and sdf-docs-examples
- Remove the resizer from log-test
- Use integer sizes and destroy stale textures in ripple-cube
- Forward onResize from the Jelly Slider landing example, and make it
  required for landing examples
- Only recreate blur textures in background-segmentation when the video
  frame size changes
Map pointer coordinates into the centered square drawn by object-contain
in liquid-glass, radiance-cascades and fluid-with-atomics.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

( ◦°^°◦) Ahoy, mateys! I re-reviewed the lone new commit on this here PR — a cosmetic move of the camera preview from starboard to port in two camera examples — and found nary a bug. All prior pullfrog threads be resolved, so I hoist the green flag.

Reviewed changes — incremental delta since the prior pullfrog review (4853241e5..a87aad1a3), commit a87aad1a3 ("Move camera preview to bottom-left in camera examples"). The branch was rebased onto newer main, so the range-diff also carries base-branch noise (the @typegpu/sort → @typegpu/algorithm rename); the only PR-authored change is this commit.

  • Repositioned the camera preview — image-processing/ascii-filter/index.html and image-processing/camera-thresholding/index.html now anchor the <video> preview at left: 10px instead of right: 10px, keeping it clear of the example controls. This is a deliberate response to the human reviewer's open "camera position changed" thread.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The appjs-venue example now recreates its render targets from onResize with hard-coded mipLevelCount: 2, which is invalid once the canvas collapses to the helper's 1x1 minimum.

Reviewed changes — incremental delta since the prior pullfrog review (a87aad1a3..0a967c1), commit 0a967c1 ("Use common.attachAutoResizer in App.js Venue example, update brush size on resize in jump-flood-distance").

  • Migrated appjs-venue to common.attachAutoResizer — canvas markup switched from data-fit-to-container to w-full h-full; the draw body was split out of frame() into render(); render-target recreation moved from the per-frame size check into onResize; and autoResizer.detach() was added to onCleanup().
  • Recomputed brush size on resize in jump-flood-distance — updateBrushSize() is now called from the onResize callback, so the brush radius follows the resized texture dimensions instead of staying at its initial value.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

canvas,
onResize() {
targets.destroy();
targets = createRenderTargets();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new onResize recreates the targets on every observed size, but createRenderTargets() requests mipLevelCount: 2 for normal and depth. attachAutoResizer clamps the canvas to a minimum of 1x1, and a 1x1 texture supports only a single mip level, so collapsing the example (narrow panel, hidden preview) creates invalid textures and the example stops rendering. The previous per-frame path never hit this because it returned early when the canvas was 0-sized.

Technical details
# `mipLevelCount: 2` exceeds the mip limit for a clamped 1x1 canvas

## Affected sites
- `apps/typegpu-docs/src/examples/advanced/appjs-venue/index.ts:512` — newly calls `createRenderTargets()` from `onResize`.
- `apps/typegpu-docs/src/examples/advanced/appjs-venue/index.ts:392` — `normal` created with `mipLevelCount: 2`.
- `apps/typegpu-docs/src/examples/advanced/appjs-venue/index.ts:393` — `depth` created with `mipLevelCount: 2`.
- `packages/typegpu/src/common/attachAutoResizer.ts:84` — clamps the canvas to `Math.max(1, ...)`.

## Required outcome
- Recreating render targets when the canvas collapses to 1x1 must not request more mip levels than the texture size supports (`floor(log2(max(width, height))) + 1`).

## Suggested approach (optional)
- Derive the mip count from the target size, e.g. `Math.min(2, Math.floor(Math.log2(Math.max(width, height))) + 1)`, or skip target recreation while the reported size is below 2x2.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants