forked from paperjs/paper.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKey.js
More file actions
153 lines (143 loc) · 4.37 KB
/
Copy pathKey.js
File metadata and controls
153 lines (143 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
* http://lehni.org/ & http://jonathanpuckey.com/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
/**
* @name Key
* @namespace
*/
var Key = new function() {
// TODO: Make sure the keys are called the same as in Scriptographer
// Missing: tab, cancel, clear, page-down, page-up, comma, minus, period,
// slash, etc etc etc.
var keys = {
8: 'backspace',
9: 'tab',
13: 'enter',
16: 'shift',
17: 'control',
18: 'option',
19: 'pause',
20: 'caps-lock',
27: 'escape',
32: 'space',
35: 'end',
36: 'home',
37: 'left',
38: 'up',
39: 'right',
40: 'down',
46: 'delete',
91: 'command',
93: 'command', // WebKit right command button
224: 'command' // Gecko command button
},
// Use Base.merge to convert into a Base object, for #toString()
modifiers = Base.merge({
shift: false,
control: false,
option: false,
command: false,
capsLock: false,
space: false
}),
// Since only keypress gets proper keyCodes that are actually representing
// characters, we need to perform a little trickery here to use these codes
// in onKeyDown/Up: keydown is used to store the downCode and handle
// modifiers and special keys such as arrows, space, etc, keypress fires the
// actual onKeyDown event and maps the keydown keyCode to the keypress
// charCode so keyup can do the right thing too.
charCodeMap = {}, // keyCode -> charCode mappings for pressed keys
keyMap = {}, // Map for currently pressed keys
downCode; // The last keyCode from keydown
function handleKey(down, keyCode, charCode, event) {
var character = String.fromCharCode(charCode),
key = keys[keyCode] || character.toLowerCase(),
type = down ? 'keydown' : 'keyup',
view = View._focused,
scope = view && view.isVisible() && view._scope,
tool = scope && scope._tool;
keyMap[key] = down;
if (tool && tool.responds(type)) {
// Call the onKeyDown or onKeyUp handler if present
tool.fire(type, new KeyEvent(down, key, character, event));
if (view)
view.draw(true);
}
}
DomEvent.add(document, {
keydown: function(event) {
var code = event.which || event.keyCode;
// If the keyCode is in keys, it needs to be handled by keydown and
// not in keypress after (arrows for example wont be triggering
// a keypress, but space would).
var key = keys[code], name;
if (key) {
// Detect modifiers and mark them as pressed
if ((name = Base.camelize(key)) in modifiers)
modifiers[name] = true;
// No char code for special keys, but mark as pressed
charCodeMap[code] = 0;
handleKey(true, code, null, event);
// Do not set downCode as we handled it already. Space would
// be handled twice otherwise, once here, once in keypress.
} else {
downCode = code;
}
},
keypress: function(event) {
if (downCode != null) {
var code = event.which || event.keyCode;
// Link the downCode from keydown with the code form keypress,
// so keyup can retrieve that code again.
charCodeMap[downCode] = code;
handleKey(true, downCode, code, event);
downCode = null;
}
},
keyup: function(event) {
var code = event.which || event.keyCode,
key = keys[code], name;
// Detect modifiers and mark them as released
if (key && (name = Base.camelize(key)) in modifiers)
modifiers[name] = false;
if (charCodeMap[code] != null) {
handleKey(false, code, charCodeMap[code], event);
delete charCodeMap[code];
}
}
});
return /** @lends Key */{
modifiers: modifiers,
/**
* Checks whether the specified key is pressed.
*
* @param {String} key One of: 'backspace', 'enter', 'shift', 'control',
* 'option', 'pause', 'caps-lock', 'escape', 'space', 'end', 'home',
* 'left', 'up', 'right', 'down', 'delete', 'command'
* @return {Boolean} {@true if the key is pressed}
*
* @example
* // Whenever the user clicks, create a circle shaped path. If the
* // 'a' key is pressed, fill it with red, otherwise fill it with blue:
* function onMouseDown(event) {
* var path = new Path.Circle(event.point, 10);
* if (Key.isDown('a')) {
* path.fillColor = 'red';
* } else {
* path.fillColor = 'blue';
* }
* }
*/
isDown: function(key) {
return !!keyMap[key];
}
};
};