Skip to content
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

Releasing a binding when another activates #156

Open
ashconnell opened this issue Jul 10, 2020 · 1 comment
Open

Releasing a binding when another activates #156

ashconnell opened this issue Jul 10, 2020 · 1 comment
Assignees
Labels
Request Feature request or idea related issues.

Comments

@ashconnell
Copy link

ashconnell commented Jul 10, 2020

I'm building an 3D editor in the browser and attempting to use the following bindings:

  • w a s d to move the camera forward/back/strafe-left/strafe-right
  • shift to move the camera down
  • space to move the camera up
  • mod + z to undo changes
  • shift + mod + z to redo changes

The problem i'm facing is that moving the camera down (shift) and the redo function (shift + mod + z) conflict with each other:

KeyboardJS.bind(
  'shift',
  () => console.log('camera: move down'),
  () => console.log('camera: stop moving down')
)
KeyboardJS.bind('mod + shift + z', () => console.log('redo'))

Typically with undo/redo, when redoing something you would hold down mod + shift and then tap z multiple times to redo a bunch of changes in the editor. The problem is that the shift keydown bind (for moving the camera down) triggers immediately and his keyup event doesn't happen until you release all the keys. This results in the camera moving downward while you're redoing a bunch of changes.

I think something like KeyboardJS.releaseBind('shift') would be useful, as we could put it in the mod + shift + z binding to immediately fire the keyup event for the shift binding, effectively cancelling it.

KeyboardJS.bind(
  'shift',
  () => console.log('camera: move down'),
  () => console.log('camera: stop moving down')
)
KeyboardJS.bind('mod+shift+z', () => {
  KeyboardJS.releaseBind('shift')
  console.log('redo')
})

I can't seem to find any workarounds in the mean time, do you have any thoughts on this?

By the way, KeyboardJS is the most robust library i've found so far for browser based editors and games. The others (mousetrap, hotkeys etc) are all missing essential features for this use-case, for example releasing keys on window blur, cmd keyup events etc. Kudos to you for building such a useful package.

@ashconnell
Copy link
Author

ashconnell commented Jul 10, 2020

Just to follow up, i've essentially done this to resolve the issue in user land:

import Keyboard from 'keyboardjs'

export class Input {
  constructor(editor, controls) {
    this.editor = editor
    this.controls = controls
    Keyboard.bind('shift', this.onCrouch, this.onCrouchRelease)
    Keyboard.bind('shift + mod + z', this.onRedo)
    // ...etc
  }

  onCrouch = event => {
    event.preventRepeat()
    if (event.metaKey) return
    this.controls.axis.y = -1
  }

  onCrouchRelease = () => {
    this.controls.axis.y = 0
  }

  onRedo = () => {
    this.onCrouchRelease() // cancel crouch
    this.editor.redo()
  }

  // ...etc
}

Although it works, I think it would make the api cohesive if you could configure things like cancelling and preventRepeat as binding options, eg:

import Keyboard from 'keyboardjs'

export class Input {
  constructor(editor, controls) {
    this.editor = editor
    this.controls = controls
    Keyboard.bind('shift', this.onCrouch, this.onCrouchRelease, {
      preventRepeat: true,
      noMeta: true,
    })
    Keyboard.bind('shift + mod + z', this.onRedo, null, {
      cancels: ['shift'],
    })
    // ...etc
  }

  onCrouch = () => {
    this.controls.axis.y = -1
  }

  onCrouchRelease = () => {
    this.controls.axis.y = 0
  }

  onRedo = () => {
    this.editor.redo()
  }

  // ...etc
}

Anyways, just my two cents and some food for thought.

@RobertWHurst RobertWHurst added the Request Feature request or idea related issues. label Jul 16, 2020
@RobertWHurst RobertWHurst self-assigned this May 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Request Feature request or idea related issues.
Projects
None yet
Development

No branches or pull requests

2 participants