Detecting ctrl+z (and other control combos) in paper.js

3.6k views Asked by At

I'm trying to enable editing commands in my paper.js application (such as CTRL+z for 'undo').

Detecting individual letter keys works great, and I can detect modifier keys that are held during mouse events, but I'm having trouble writing an event handler that detects combinations of CTRL and letter keys.

Based on the examples given by fabric.js, what I would expect is a key handler that looks something like this:

function onKeyDown(event) {
    if (event.key == 'z' && event.modifiers.control){
       //do a thing!
    }
}

However, this doesn't work! Weirdly enough, the conditional block never fires. To investigate this, I wrote the following diagnostic handler...

function onKeyDown(event) {
    console.log(event.key);
    console.log(event.modifiers.control);
}

... and tried it out with various keyboard inputs with some interesting results:

CTRL key only

   Key: control
   Control: true

z key only

Key: z
Control: false

z key pressed while holding CTRL

Key: 
Control: true

These results suggest that the string returned by event.key is different depending on whether the control modifier is held down when another key is typed. Something weird is happening here!

Based on this, how can I detect both of these keys being pressed at the same time?

3

There are 3 answers

0
Aaron Heuckroth On BEST ANSWER

TL;DR: You can use event.key.charCodeAt(0) to detect the strange character codes returned by CTRL+Z and other CTRL+key combinations.


As it turns out, the CTRL+z combination is special.

The key being returned in this case...

z key while holding control

Key: 
Control: true

... looks like an empty string, because the keycode being passed to the event handler corresponds to the special CTRL+z combination, which results in an unprintable character.

To detect this special character, I modfiied the diagnostic handler...

 function onKeyDown(event){
     console.log("Key: " + event.key);
     console.log("Control: " + event.modifiers.control);
     console.log("KeyCode: " + event.key.charCodeAt(0));
 }

... and tested the same keyboard combinations as before:

CTRL key only

 Key: control
 Control: true
 KeyCode: 99

z key only

 Key: z
 Control: false
 KeyCode: 122

z key pressed while holding CTRL

 Key: 
 Control: true
 KeyCode: 26

This means that the special CTRL key combinations can be detected using an event handler like this:

function onKeyDown(event) {
    if (event.key.charCodeAt(0) == 26){ // detect the special CTRL-Z code
        // do a thing! 
    }
}

It should be noted that this approach will not work for detecting the control key on its own, since 99 is NOT the character for CTRL, but rather for "c", the first character in the string "control" returned by event.key. For that, you'll still want to use event.modifiers.control.

3
skyline3000 On

Here are a couple of vanilla Javascript solutions that should help you:

Solution 1

Check which keycode was pressed down and if the shiftkey is down using native the event object.

function handleKeyDown(evt) {
    if (evt.which === 90 && evt.shiftKey) {
        // do a thing!
    }
};

Solution 2

Keep a global variable for the detecting if the shift key is down and use that in your keydown handler. You'll also need to reset it with a keyup event handler.

var shiftKeyDown = false;

function handleKeyDown(evt) {
    if (evt.which === 17) {
        shiftKeyDown = true;
    } else if (evt.which === 90 && shiftKeyDown) {
        // do a thing!
    }
};

function handleKeyUp(evt) {
    if (evt.which === 17) {
        shiftKeyDown = false;
    }
};
0
K. Symbol On
function onKeyDown(event) {
if (event.event.ctrlKey && event.key == "z") {
    //do something
   }
}

This should work.