-
-
Notifications
You must be signed in to change notification settings - Fork 657
clipRect: potential issues with transformed containers and scissor state cleanup #1349
Description
Summary
Container.draw() calls renderer.clipRect(bounds.left, bounds.top, bounds.width, bounds.height) for clipping, but there are potential issues with how coordinates and state are handled.
Issues
1. Coordinate space mismatch
clipRect is called before renderer.translate(this.pos.x, this.pos.y) (container.js line 945 vs 949). The bounds values are in absolute/world coordinates from updateBounds(absolute=true), but clipRect operates in the renderer's current transform space, which already includes parent container transforms from their preDraw.
2. WebGL scissor only accounts for translation
The WebGL clipRect manually offsets by currentTransform.tx/ty (webgl_renderer.js line 1483-1484), but ignores scale and rotation. If a parent container is scaled or rotated, the scissor rectangle will be incorrect.
3. No explicit scissor cleanup after container draw
clipRect sets a clip/scissor region but the container's draw() doesn't explicitly clear it. It relies on save()/restore() in preDraw/postDraw:
- Canvas: should work (canvas context save/restore preserves clip state)
- WebGL: scissor state may not be properly restored — the
elsebranch in WebGLclipRectdisablesSCISSOR_TESTwhen the rect matches the canvas size, but nested containers may not trigger this path
Suggested approach
- Add integration tests that exercise
clipRectthroughContainer.draw()with a mock or real renderer - Verify correct behavior with nested containers, scaled/rotated parents, and mixed clipping states
- Consider whether
clipRectshould use local coordinates (applied after the container's own translate) instead of absolute bounds
Related
bounds.isFinite()guard added in Remove game import from Container, default dimensions to Infinity #1348 prevents Infinity/NaN values from reachingclipRect