Skip to content

Commit b26caee

Browse files
committed
Improve key event handling, work in progress.
1 parent 2f4f003 commit b26caee

6 files changed

Lines changed: 193 additions & 66 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.character == 'space')
290+
if (event.keyCode == 'space')
291291
layer.selected = !layer.selected;
292292
}
293293
</script>

src/browser/DomEvent.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ var DomEvent = {
6262
// Remove target offsets from page coordinates
6363
return DomEvent.getPoint(event).subtract(
6464
DomElement.getOffset(DomEvent.getElement(event), true));
65+
},
66+
67+
preventDefault: function(event) {
68+
if (event.preventDefault) {
69+
event.preventDefault();
70+
} else {
71+
// IE
72+
event.returnValue = false;
73+
}
74+
},
75+
76+
stopPropagation: function(event) {
77+
if (event.stopPropagation) {
78+
event.stopPropagation();
79+
} else {
80+
event.cancelBubble = true;
81+
}
6582
}
6683
};
6784

src/load.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,21 @@ var sources = [
6262
'src/color/Gradient.js',
6363
'src/color/GradientStop.js',
6464

65+
'src/browser/DomElement.js',
66+
'src/browser/DomEvent.js',
67+
68+
'src/ui/Event.js',
69+
'src/ui/KeyEvent.js',
70+
'src/ui/Key.js',
71+
6572
'src/tool/ToolEvent.js',
6673
'src/tool/ToolHandler.js',
6774
'src/tool/Tool.js',
6875

69-
'src/browser/DomElement.js',
70-
'src/browser/DomEvent.js',
71-
7276
'src/util/CanvasProvider.js',
7377
'src/util/Numerical.js',
7478
'src/util/PaperScript.js',
75-
'src/util/BlendMode.js',
76-
77-
'src/ui/Key.js'
79+
'src/util/BlendMode.js'
7880
];
7981

8082
// Load unit tests after library if asked to do so

src/ui/Event.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Paper.js
3+
*
4+
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
5+
* based on Scriptographer.org and designed to be largely API compatible.
6+
* http://paperjs.org/
7+
* http://scriptographer.org/
8+
*
9+
* Distributed under the MIT license. See LICENSE file for details.
10+
*
11+
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
12+
* http://lehni.org/ & http://jonathanpuckey.com/
13+
*
14+
* All rights reserved.
15+
*/
16+
17+
var Event = this.Event = Base.extend({
18+
initialize: function(event) {
19+
this.event = event;
20+
},
21+
22+
// PORT: Add to Sg
23+
preventDefault: function() {
24+
DomEvent.preventDefault(this.event);
25+
},
26+
27+
stopPropagation: function() {
28+
DomEvent.stopPropagation(this.event);
29+
},
30+
31+
stop: function() {
32+
this.stopPropagation();
33+
this.preventDefault();
34+
},
35+
36+
getModifiers: function() {
37+
return Key.modifiers;
38+
}
39+
});

src/ui/Key.js

Lines changed: 85 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,103 @@
1-
var Key = new function() {
1+
/*
2+
* Paper.js
3+
*
4+
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
5+
* based on Scriptographer.org and designed to be largely API compatible.
6+
* http://paperjs.org/
7+
* http://scriptographer.org/
8+
*
9+
* Distributed under the MIT license. See LICENSE file for details.
10+
*
11+
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
12+
* http://lehni.org/ & http://jonathanpuckey.com/
13+
*
14+
* All rights reserved.
15+
*/
16+
17+
var Key = this.Key = new function() {
218
// TODO: make sure the keys are called the same as in Scriptographer
319
// Missing: tab, cancel, clear, pause, page-down, page-up, end, home, comma,
420
// minus, period, slash, etc etc etc.
21+
522
var keys = {
6-
'8': 'backspace',
7-
'13': 'enter',
8-
'16': 'shift',
9-
'17': 'control',
10-
'19': 'option', // was alt
11-
'20': 'capsLock',
12-
'27': 'escape',
13-
'32': 'space',
14-
'37': 'left',
15-
'38': 'up',
16-
'39': 'right',
17-
'40': 'down',
18-
'46': 'delete',
19-
'91': 'command'
23+
8: 'backspace',
24+
13: 'enter',
25+
16: 'shift',
26+
17: 'control',
27+
19: 'option', // was alt
28+
20: 'capsLock',
29+
27: 'escape',
30+
32: 'space',
31+
37: 'left',
32+
38: 'up',
33+
39: 'right',
34+
40: 'down',
35+
46: 'delete',
36+
91: 'command'
2037
},
38+
2139
modifiers = {
2240
shift: false,
2341
control: false,
2442
option: false,
2543
command: false,
2644
capsLock: false
2745
},
28-
activeKeys = {};
29-
30-
Event.add(document, Base.each(['keyDown', 'keyUp'], function(type) {
31-
var toolHandler = 'on' + Base.capitalize(type),
32-
keyDown = type === 'keyDown';
33-
this[type.toLowerCase()] = function(event) {
34-
var code = event.which || event.keyCode,
35-
key = keys[code] || String.fromCharCode(code).toLowerCase();
36-
activeKeys[key] = keyDown;
37-
38-
// If the key is a modifier, update the modifiers:
39-
if (modifiers[key] !== undefined)
40-
modifiers[key] = keyDown;
41-
42-
// Call the onKeyDown or onKeyUp handler if present:
43-
// TODO: don't call the key handler if the key is a modifier?
44-
if (paper.tool && paper.tool[toolHandler]) {
45-
// TODO: Introduce a class for this?
46-
var keyEvent = {
47-
type: keyDown ? 'key-down' : 'key-up',
48-
keyCode: code,
49-
character: key,
50-
modifiers: modifiers,
51-
// 'preventDefault: event.preventDefault' throws
52-
// an error in Safari when called, so we have to wrap
53-
// it into a function.
54-
// PORT: Add to Sg
55-
preventDefault: function() {
56-
if (event.preventDefault) {
57-
event.preventDefault();
58-
} else {
59-
event.returnValue = false;
60-
}
61-
}
62-
};
63-
var res = paper.tool[toolHandler](keyEvent);
64-
// PORT: Add to Sg
65-
// When the handler function returns false, prevent the
66-
// default behaviour of the key event:
67-
if (res === false)
68-
keyEvent.preventDefault();
46+
47+
keyCodes = {},
48+
downCode,
49+
downTimer;
50+
51+
function handleKey(down, code, event) {
52+
var character = String.fromCharCode(code),
53+
keyCode = keys[code] || character.toLowerCase(),
54+
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]) {
59+
// Call the onKeyDown or onKeyUp handler if present
60+
// When the handler function returns false, prevent the
61+
// default behaviour of the key event:
62+
// PORT: Add to Sg
63+
var keyEvent = new KeyEvent(down, keyCode, character, event);
64+
if (paper.tool[handler](keyEvent) === false) {
65+
keyEvent.preventDefault();
6966
}
70-
};
71-
}, {}));
72-
67+
}
68+
}
69+
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.
75+
DomEvent.add(document, {
76+
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);
82+
},
83+
84+
keypress: function(event) {
85+
clearTimeout(downTimer);
86+
var code = event.which || event.keyCode;
87+
keyCodes[downCode] = code;
88+
handleKey(true, code, event);
89+
},
90+
91+
keyup: function(event) {
92+
var code = event.which || event.keyCode;
93+
handleKey(false, keyCodes[code], event);
94+
delete keyCodes[code];
95+
}
96+
});
97+
7398
return {
7499
modifiers: modifiers,
100+
75101
isDown: function(key) {
76102
return !!activeKeys[key];
77103
}

src/ui/KeyEvent.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Paper.js
3+
*
4+
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
5+
* based on Scriptographer.org and designed to be largely API compatible.
6+
* http://paperjs.org/
7+
* http://scriptographer.org/
8+
*
9+
* Distributed under the MIT license. See LICENSE file for details.
10+
*
11+
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
12+
* http://lehni.org/ & http://jonathanpuckey.com/
13+
*
14+
* All rights reserved.
15+
*/
16+
17+
var KeyEvent = this.KeyEvent = Event.extend(new function() {
18+
var keys = {
19+
8: 'backspace',
20+
13: 'enter',
21+
16: 'shift',
22+
17: 'control',
23+
19: 'option', // was alt
24+
20: 'capsLock',
25+
27: 'escape',
26+
32: 'space',
27+
37: 'left',
28+
38: 'up',
29+
39: 'right',
30+
40: 'down',
31+
46: 'delete',
32+
91: 'command'
33+
};
34+
35+
return {
36+
initialize: function(down, keyCode, character, event) {
37+
this.base(event);
38+
this.type = down ? 'key-down' : 'key-up';
39+
this.keyCode = keyCode;
40+
this.character = character;
41+
}
42+
};
43+
});

0 commit comments

Comments
 (0)