Обнаружение ctrl+z (и других комбинаций управления) в paper.js

Я пытаюсь включить команды редактирования в своем приложении paper.js (например, CTRL+z для отмены).

Обнаружение отдельных буквенных клавиш прекрасно работает, и я могу обнаруживать клавиши-модификаторы, удерживаемые во время событий мыши, но у меня возникают проблемы с написанием обработчика событий, который определяет комбинации CTRL и буквенных клавиш.

Основываясь на примерах, приведенных в Fabric.js, я ожидаю, что ключ обработчик, который выглядит примерно так:

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

Однако это не работает! Как ни странно, условный блок никогда не срабатывает. Чтобы исследовать это, я написал следующий диагностический обработчик...

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

... и попробовал его с различными вводами с клавиатуры с некоторыми интересными результатами:

Только клавиша CTRL

   Key: control
   Control: true

только ключ z

Key: z
Control: false

Клавиша z нажата, удерживая CTRL

Key: 
Control: true

Эти результаты показывают, что строка, возвращаемая event.key, отличается в зависимости от того, удерживается ли модификатор управления при нажатии другой клавиши. Здесь происходит что-то странное!

Исходя из этого, как я могу обнаружить, что обе эти клавиши нажаты одновременно?


person Aaron Heuckroth    schedule 18.06.2015    source источник


Ответы (3)


Вот несколько ванильных решений Javascript, которые должны вам помочь:

Решение 1

Проверьте, какой код клавиши был нажат, и если клавиша Shift нажата, используя собственный объект события.

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

Решение 2

Сохраните глобальную переменную для определения, нажата ли клавиша Shift, и используйте ее в обработчике нажатия клавиши. Вам также потребуется сбросить его с помощью обработчика событий keyup.

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;
    }
};
person skyline3000    schedule 18.06.2015
comment
Проблема здесь в том, что строка, возвращаемая event.key, на самом деле отличается в зависимости от того, удерживается ли CTRL. Shift намного проще (и это было первое, что я реализовал!), потому что он не меняет значение key. Даже если вы создадите глобальное логическое значение для CTRL и сопоставите его с событиями keyUp/keyDown, вы все равно не сможете обнаружить символ CTRL+Z, ища event.key == 'z', потому что z никогда не будет возвращено event.key до тех пор, пока CTRL держал. Теоретически вы могли бы сделать свой глобальный булев CTRL переключателем каждый раз, когда нажимается эта клавиша, но это было бы странно. :) - person Aaron Heuckroth; 18.06.2015
comment
Вот почему я бы рекомендовал использовать which или keyCode, а не key, как в моем примере. Каждый ключ представлен уникальным номером. Эти атрибуты сейчас считаются устаревшими, но в зависимости от того, какие браузеры вам могут понадобиться для поддержки, они будут наиболее универсальными, и все будущие браузеры будут поддерживать их для устаревших целей. - person skyline3000; 18.06.2015
comment
Если бы я писал простой обработчик JavaScript, я был бы склонен с вами согласиться! В этом случае я пытаюсь придерживаться обработчиков событий, предоставляемых библиотекой paper.js, которые не дают вам прямого доступа к keyCodes, порожденным обработчиком событий. Но вы правы, в этом случае вам действительно нужен event.keyCode, если он доступен! - person Aaron Heuckroth; 19.06.2015

TL;DR: вы можете использовать event.key.charCodeAt(0) для обнаружения странных кодов символов, возвращаемых CTRL+Z и другими CTRL. + комбинации клавиш.


Как оказалось, комбинация CTRL+z — это специальный.

Ключ, возвращаемый в этом случае...

Клавиша z, удерживая контроль

Key: 
Control: true

... выглядит как пустая строка, потому что код клавиши, передаваемый обработчику события, соответствует специальной комбинации CTRL+z, результатом которой является непечатаемый символ.

Чтобы обнаружить этот специальный символ, я модифицировал диагностический обработчик...

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

... и проверил те же комбинации клавиш, что и раньше:

Только клавиша CTRL

 Key: control
 Control: true
 KeyCode: 99

только ключ z

 Key: z
 Control: false
 KeyCode: 122

Клавиша z нажата, удерживая CTRL

 Key: 
 Control: true
 KeyCode: 26

Это означает, что специальные комбинации клавиш CTRL могут быть обнаружены с помощью обработчика событий, подобного этому:

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

Следует отметить, что этот подход не будет работать для обнаружения клавиши управления сам по себе, поскольку 99 НЕ является символом для CTRL, а скорее для "c", первого символа в строке "control", возвращаемой event.key . Для этого вы все равно захотите использовать event.modifiers.control.

person Aaron Heuckroth    schedule 18.06.2015

function onKeyDown(event) {
if (event.event.ctrlKey && event.key == "z") {
    //do something
   }
}

Это должно работать.

person K. Symbol    schedule 26.06.2018