A Canvas has a CSS display size and a bitmap backing size. If those differ, the browser scales pixels; the result can look soft or distorted. A high-density display may need more backing pixels for the same CSS box, but allocating blindly at the full device ratio can multiply memory and drawing work. Pointer coordinates arrive in viewport CSS pixels. The scene may use its own units. A correct editor makes every conversion explicit and updates it when layout, zoom, or device pixel ratio changes.
Canvas Pixel Ratio and Pointer Coordinates
Working case
The case map has a CSS box 620 units wide, while its backing bitmap is capped for a high-density tablet. Reviewer 47 taps a defect at scene x=29. The app subtracts the element bounds and maps the remaining CSS position into the scene width before hit testing. When the reviewer zooms the browser, the box changes width and the editor recalculates the mapping. It does not reuse a coordinate scale captured at mount. A pointer placed at the right edge never selects a region outside the scene.
Implementation boundary
function sceneX(clientX, left, cssWidth, sceneWidth) {
if (cssWidth <= 0) return null;
return (clientX - left) * sceneWidth / cssWidth;
}
console.log(sceneX(185, 30, 310, 620));
// Output: 310Define one scene coordinate system and one conversion function from client coordinates through the current element bounds. Do not mix backing pixel coordinates with hit-test coordinates. Resize the backing bitmap when the display size changes, then reset or reapply the drawing transform because a Canvas size assignment clears its contents and context state. Cap the effective pixel ratio and total bitmap area by an explicit memory budget. Redraw from the structured scene after resize. Test transforms, padding, scroll, device rotation, and zoom before trusting pointer placement.
Cost and boundaries
Bitmap allocation grows as width times height times four bytes for a common RGBA surface, before temporary image buffers and compositing overhead. Doubling both pixel dimensions can roughly quadruple that surface cost. Repeated resize also clears and reallocates work. The coordinate conversion is O(1) per pointer event, while redraw cost depends on surface area and mark count. Throttle nonessential pointer previews to frame cadence, but commit the final pointer position accurately. Measure peak memory and tap accuracy on target devices.
Failure trace
A prototype multiplies pointer x by devicePixelRatio twice. The mark appears near the tap but the saved geometry lands farther right, especially after zoom. Another build sets canvas.width on every render, erasing the drawing and reset transform. Test a ratio change, resize from 620 to 310 CSS units, scroll position, device rotation, an empty zero-width box, and taps at all four edges. Verify that the same scene point is selected before and after layout changes.
Verification
- Midpoint taps map to one scene point at multiple display sizes.
- Resize redraws from model state.
- Backing allocation obeys a measured cap.
Practice drill
Use a 620-unit scene and render it in boxes of 620 and 310 CSS units. Map a pointer at each box midpoint back to scene x=310. Cap a high device ratio according to a 47-megabyte bitmap budget and record actual allocation. Resize the element while a mark is selected, redraw from scene state, and confirm the selected ID remains the same. Repeat with browser zoom rather than assuming a fixed viewport.
Decision note
Treat drawing resolution and interaction coordinates as separate conversions with one tested scene space.
Common Mistakes
- Applying device pixel ratio to hit testing twice.
- Saving coordinates in transient CSS pixels.
- Resizing the bitmap on every component render.
Connected lessons
Build Project: accessible inspection map and export and review Web Development: graphics and editor decisions quiz; follow Interactive Graphics and Canvas Boundaries; SVG, Canvas, Scene Model, and Hit Testing; Canvas Origin-Clean Export and Private Assets; Accessible Graphic Controls and Text Equivalents; Page performance: budget the critical path and reserve layout space; Visual Viewport, Keyboard, and Focused Input.
