-
Notifications
You must be signed in to change notification settings - Fork 21
feat(events): implement pointer capture API for drag-and-drop interactions #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…actory
Separate frame scheduling concerns from canvas creation for better
architectural clarity and simpler custom integrations (e.g., WebXR).
Changes:
- Split IPlatformAdapter into two focused interfaces:
* IFrameScheduler - Frame scheduling (scheduleFrame, onFrame)
* ICanvasFactory - Canvas creation and management
- Update RenderCanvas to depend only on IFrameScheduler
* Rename parameter from platformAdapter to frameScheduler
* RenderCanvas no longer depends on canvas creation methods
- Update createElement factory to accept IFrameScheduler
- Keep IPlatformAdapter as union of both for backward compatibility
Benefits:
- Single Responsibility Principle - each interface has one concern
- RenderCanvas only depends on what it needs (frame scheduling)
- WebXR/custom renderers can provide simple IFrameScheduler without
implementing unused canvas creation methods
- No breaking changes - IPlatformAdapter still works as before
- Better foundation for testing and exotic platforms
Example WebXR usage:
class XRFrameScheduler implements IFrameScheduler {
scheduleFrame() { xrSession.requestAnimationFrame(...) }
onFrame(cb) { ... }
}
new RenderCanvas(new XRFrameScheduler(xrSession))
Fix pointerenter and pointerleave events to fire on entire element hierarchy, not just the direct target. Previously, these events only fired at the primary target element, which was incorrect. They should fire for all elements that are entered or left during pointer movement. Now properly tracks which elements were entered (in new path but not old) and which were left (in old path but not new), firing appropriate events for each.
This commit adds support for injecting custom event bindings into RenderCanvas and introduces BridgeEventBinding for programmatic event injection. Changes: - Add binding parameter to RenderCanvas constructor (defaults to DOMEventBinding) - Add binding parameter to createElement factory function - Implement BridgeEventBinding for programmatic event injection - Add NativeEventBinding.el property for element binding - Add comprehensive test suite for BridgeEventBinding (12 tests) Benefits: - Enables WebXR controller event injection - Clean interface using property setter pattern
This commit enables passing any canvas element (HTMLCanvasElement or OffscreenCanvas) to RenderCanvas via constructor injection, following the established dependency injection pattern (frameScheduler, binding). Changes: - Add canvas parameter to RenderCanvas constructor and createElement factory - Expand el property type to accept both HTMLCanvasElement and OffscreenCanvas - Update CanvasSurface to accept both HTMLCanvasElement and OffscreenCanvas - Rename createOrUpdateEl → ensureCanvasSize (reflects actual behavior) - Guard cursor management with instanceof check for HTMLCanvasElement - Make drawFrame public for manual rendering control - Add JSDoc documentation for constructor and drawFrame Benefits: - Clean dependency injection pattern consistent with other constructor parameters - Manual frame control via public drawFrame method - Cursor management gracefully degrades for OffscreenCanvas - Backwards compatible (canvas parameter is optional)
This commit adds HeadlessCanvas, a React component for rendering Canvas UI to OffscreenCanvas without mounting to the DOM. Changes: - Add HeadlessCanvas component with event injection API - Accept user-provided OffscreenCanvas and custom frameScheduler - Provide injectEvent and injectWheelEvent helpers via onReady callback - Support onFrameEnd callback for texture copying - Export HeadlessCanvas and related types from @canvas-ui/react Benefits: - Enables WebXR layer rendering (XRWebGLLayer texture targets) - Manual frame control with custom schedulers - Programmatic event injection for XR controllers - No DOM coupling for headless environments Use cases: - WebXR UI panels rendered to quad layers - Custom render loop integration
getBoundingClientRect() only exists on HTMLCanvasElement, not OffscreenCanvas. Skip popup positioning for OffscreenCanvas since it has no DOM position.
…crolling Implement proper wheel event bubbling behavior in RenderScrollView to enable nested scrolling scenarios where parent scrollers can handle events when the inner scroller reaches its scroll bounds. Changes: - RenderScrollView: only call preventDefault() when scroll actually occurs (when _setScrollOffset() returns true), allowing events to bubble to parent when at scroll bounds (top/bottom for vertical, left/right for horizontal) - Add 6 comprehensive integration tests covering preventDefault behavior at all scroll bounds and nested ScrollView scenarios - BridgeEventBinding: add preventDefault/stopPropagation mocks to wheel events for test support, plus stub pointer capture methods for compatibility Tests verify: - preventDefault called when scrolling within bounds - preventDefault NOT called when at top/bottom/left/right bounds - Nested ScrollViews: inner at bounds allows outer to scroll All tests passing (10 passed: 4 existing + 6 new)
…tions Adds DOM-standard pointer capture API to enable proper event routing during drag-and-drop and similar interactions. When a pointer is captured, events are routed directly to the capturing component instead of using hit testing, allowing components to continue receiving events even when the pointer moves outside their bounds. Key changes: - Add setPointerCapture/releasePointerCapture/hasPointerCapture to RenderObject - Update SyntheticEventManager to check for captured pointers before hit testing - Support independent capture tracking for multiple pointers (multi-touch) - Add comprehensive test suite with 12 tests covering capture scenarios - Clean up BridgeEventBinding by removing deprecated element capture stubs
894f3c0 to
0600cf9
Compare
|
Hi @myers Seeing your high-quality work and interest in the project got us thinking—would you be interested in becoming a collaborator and joining the core team? It would mean you get write access to the repo, so you can help us triage issues, review other PRs, and push your own branches directly. No pressure or major time commitment is expected, just more freedom to help out when you have the time and inspiration! If that sounds good to you, just give me a shout here, and I'll send the invite over. If not, no worries at all! We're thrilled with your contribution either way and hope to see you around the project again soon. 😄 |
Sure, I would be happy to be a collaborator and part of the team. |
Hello! 您好
This PR builds on the work in #35 (HeadlessCanvas). It depends on BridgeEventBinding from #32.
This PR adds DOM-standard pointer capture API to enable proper event routing during drag-and-drop and similar interactions. When a pointer is captured, events are routed directly to the capturing component instead of using hit testing, allowing components to continue receiving events even when the pointer moves outside their bounds.
This is useful for implementing slider components where you want to track pointer movement even when the cursor goes outside the slider's bounds.
Changes: