Skip to content

Conversation

@halletj
Copy link

@halletj halletj commented Sep 26, 2025

Add origEvent Property to Expose Original DOM Events

🎯 Overview

This PR adds access to the original DOM events (MouseEvent, TouchEvent, PointerEvent) that trigger joystick interactions. Developers can now access native event properties like button, buttons, clientX, clientY, pressure, force, and other event-specific data.

🚀 Motivation

Many developers need access to the original DOM events to:

  • Detect which mouse button was used (left, right, middle)
  • Access touch pressure/force data for advanced interactions
  • Get precise cursor/touch coordinates
  • Implement custom event handling logic
  • Support advanced input scenarios (e.g., right-click for different actions)

Previously, this information was lost during event processing, limiting the library's flexibility for advanced use cases.

📋 Changes Made

Core Implementation (src/collection.js)

  • Added nipple.origEvent = evt in all event processing functions:
    • processOnStart() - Stores original event when joystick interaction begins
    • processOnMove() - Updates original event during movement (multiple locations for different code paths)
    • processOnEnd() - Stores original event when interaction ends
  • Added origEvent: nipple.origEvent to move event data object to maintain consistency with existing data structure

TypeScript Definitions (types/index.d.ts)

  • Added origEvent: Event to JoystickOutputData interface
  • Added origEvent: Event to Joystick interface
  • Updated event handler signatures to accept JoystickOutputData | Joystick to reflect actual implementation where:
    • Move events pass JoystickOutputData objects
    • Start/End/Pressure events pass Joystick instances

Example Updates

  • Added context menu prevention to all example files to improve testing experience with right-click interactions
  • Updated codepen-demo.html pressure event handler to work with new data structure

🔧 Usage Examples

Accessing Original Events

// Mouse button detection
manager.on('start', function(evt, nipple) {
    console.log('Button pressed:', nipple.origEvent.button); // 0=left, 1=middle, 2=right
    console.log('Buttons state:', nipple.origEvent.buttons); // Bitmask of pressed buttons
});

// Touch pressure/force
manager.on('move', function(evt, data) {
    console.log('Touch pressure:', data.origEvent.force || data.origEvent.pressure);
    console.log('Touch coordinates:', data.origEvent.clientX, data.origEvent.clientY);
});

// Event type detection
manager.on('end', function(evt, nipple) {
    console.log('Event type:', nipple.origEvent.type); // 'mouseup', 'touchend', 'pointerup'
});

TypeScript Usage

manager.on('start', (evt, data) => {
    // TypeScript now correctly types data as JoystickOutputData | Joystick
    if ('origEvent' in data) {
        const originalEvent: Event = data.origEvent;
        // Access any native event properties
    }
});

🧪 Testing

  • ✅ All existing functionality preserved
  • ✅ Build passes successfully
  • ✅ TypeScript definitions validated
  • ✅ Examples updated and tested
  • ✅ Context menu disabled in examples for better right-click testing

📊 Impact

  • ✅ Backward Compatible: No breaking changes to existing API
  • ✅ Minimal Overhead: Only stores reference to existing event object
  • ✅ Consistent: Available across all event types (start, move, end, pressure)
  • ✅ Type Safe: Full TypeScript support with proper type definitions

🔍 Implementation Details

The implementation stores the original DOM event in the nipple instance and ensures it's available in all event callbacks:

  1. Start/End/Pressure Events: Pass nipple instance → access via nipple.origEvent
  2. Move Events: Pass data object → access via data.origEvent (copied from nipple.origEvent)

This approach maintains consistency with the existing event system while providing access to the original event data.


Files Changed:

  • src/collection.js - Core implementation (+10 lines)
  • types/index.d.ts - TypeScript definitions (+6 lines)
  • example/*.html - Context menu prevention for better testing (+20 lines total)

Total: +36 lines added, minimal changes for maximum functionality gain.

@yoannmoinet
Copy link
Owner

yoannmoinet commented Sep 26, 2025

Thanks for the PR and the very detailed description.

I'm currently in the process of rewriting the whole code base.
And I do have this in there, part of the API:

initial: evt,
raw: processedEvt,

The rewrite fixes a lot of bugs and greatly improve performances as well as redefines the developer experience of the repo entirely.

I've been working on it on and off the past year or so.
But lately I've got some other personal stuffs going on that made it difficult to finish the rewrite.
But I will get to it at some point.

I'm really not that far from the finish line tbh, here's the PR if you wanna tag along.

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.

2 participants