Skip to content

Commit 742c9da

Browse files
committed
More work on key handling and rename KeyEvent#keyCode -> KeyEvent#key.
1 parent 9f47942 commit 742c9da

4 files changed

Lines changed: 64 additions & 32 deletions

File tree

examples/Animated/Flock.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@
287287

288288
var layer = document.activeLayer;
289289
function onKeyDown(event) {
290-
if (event.keyCode == 'space')
290+
if (event.key == 'space')
291291
layer.selected = !layer.selected;
292292
}
293293
</script>

src/paper.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ Base.inject({
118118
});
119119
},
120120

121+
camelize: function(str) {
122+
return str.replace(/-(\w)/g, function(all, chr) {
123+
return chr.toUpperCase();
124+
});
125+
},
126+
121127
formatNumber: function(num) {
122128
return (Math.round(num * 100000) / 100000).toString();
123129
}

src/ui/Key.js

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@ var Key = this.Key = new function() {
2424
13: 'enter',
2525
16: 'shift',
2626
17: 'control',
27-
19: 'option', // was alt
28-
20: 'capsLock',
27+
18: 'option',
28+
19: 'pause',
29+
20: 'caps-lock',
2930
27: 'escape',
3031
32: 'space',
32+
35: 'end',
33+
36: 'home',
3134
37: 'left',
3235
38: 'up',
3336
39: 'right',
@@ -44,54 +47,69 @@ var Key = this.Key = new function() {
4447
capsLock: false
4548
},
4649

47-
keyCodes = {},
48-
downCode,
49-
downTimer;
50+
// Since only keypress gets proper keyCodes that are actually representing
51+
// characters, we need to perform a little trickery here to use these codes
52+
// in onKeyDown/Up: keydown is used to store the downCode and handle
53+
// modifiers and special keys such as arrows, space, etc, keypress fires the
54+
// actual onKeyDown event and maps the keydown keyCode to the keypress
55+
// charCode so keyup can do the right thing too.
56+
charCodeMap = {}, // keyCode -> charCode mappings for pressed keys
57+
downCode; // The last keyCode from keydown
5058

51-
function handleKey(down, code, event) {
52-
var character = String.fromCharCode(code),
53-
keyCode = keys[code] || character.toLowerCase(),
59+
function handleKey(down, keyCode, charCode, event) {
60+
var character = String.fromCharCode(charCode),
61+
key = keys[keyCode] || character.toLowerCase(),
5462
handler = down ? 'onKeyDown' : 'onKeyUp';
55-
console.log(handler, keyCode, character);
56-
if (modifiers[keyCode] !== undefined) {
57-
modifiers[keyCode] = down;
58-
} else if (paper.tool && paper.tool[handler]) {
63+
if (paper.tool && paper.tool[handler]) {
5964
// Call the onKeyDown or onKeyUp handler if present
6065
// When the handler function returns false, prevent the
6166
// default behaviour of the key event:
6267
// PORT: Add to Sg
63-
var keyEvent = new KeyEvent(down, keyCode, character, event);
68+
var keyEvent = new KeyEvent(down, key, character, event);
6469
if (paper.tool[handler](keyEvent) === false) {
6570
keyEvent.preventDefault();
6671
}
6772
}
6873
}
6974

70-
// Since only keypress gest proper keyCodes that are actually representing
71-
// characters, we need to add a little timeout to keydown events to see if
72-
// they are follow immediately by a keypress, and if so, map the keyCode
73-
// from the keydown to the one from keypress, so keyup still knows what
74-
// code has now been released.
7575
DomEvent.add(document, {
7676
keydown: function(event) {
77-
var code = downCode = event.which || event.keyCode;
78-
downTimer = setTimeout(function() {
79-
keyCodes[code] = code;
80-
handleKey(true, code, event);
81-
}, 1);
77+
downCode = event.which || event.keyCode;
78+
// If the keyCode is in keys, it needs to be handled by keydown and
79+
// won't fire a keypress after.
80+
var key = keys[downCode],
81+
name;
82+
if (key) {
83+
// Do not fire handleKey for modifiers, but for other keys such
84+
// ass arrows, delete, backspace, etc.
85+
if (modifiers[name = Base.camelize(key)] !== undefined) {
86+
modifiers[name] = true;
87+
} else {
88+
// No char code for special keys, but mark as pressed
89+
charCodeMap[downCode] = 0;
90+
handleKey(true, downCode, null, event);
91+
}
92+
}
8293
},
8394

8495
keypress: function(event) {
85-
clearTimeout(downTimer);
8696
var code = event.which || event.keyCode;
87-
keyCodes[downCode] = code;
88-
handleKey(true, code, event);
97+
// Link the downCode from keydown with the code form keypress, so
98+
// keyup can retrieve that code again.
99+
charCodeMap[downCode] = code;
100+
handleKey(true, downCode, code, event);
89101
},
90102

91103
keyup: function(event) {
92-
var code = event.which || event.keyCode;
93-
handleKey(false, keyCodes[code], event);
94-
delete keyCodes[code];
104+
var code = event.which || event.keyCode,
105+
key = keys[code],
106+
name;
107+
if (key && modifiers[name = Base.camelize(key)] !== undefined) {
108+
modifiers[name] = false
109+
} else if (charCodeMap[code] !== undefined) {
110+
handleKey(false, code, charCodeMap[code], event);
111+
delete charCodeMap[code];
112+
}
95113
}
96114
});
97115

src/ui/KeyEvent.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@
1616

1717
var KeyEvent = this.KeyEvent = Event.extend(new function() {
1818
return {
19-
initialize: function(down, keyCode, character, event) {
19+
initialize: function(down, key, character, event) {
2020
this.base(event);
2121
this.type = down ? 'key-down' : 'key-up';
22-
this.keyCode = keyCode;
22+
this.key = key;
2323
this.character = character;
24+
},
25+
26+
toString: function() {
27+
return '{ type: ' + this.type
28+
+ ', key: ' + this.key
29+
+ ', character: ' + this.character
30+
+ ', modifiers: ' + this.modifiers
31+
+ ' }';
2432
}
2533
};
2634
});

0 commit comments

Comments
 (0)