@checksub_team/peaks_timeline 1.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Defines the {@link KeyboardHandler} class.
5
+ *
6
+ * @module keyboard-handler
7
+ */
8
+
9
+ define([], function() {
10
+ 'use strict';
11
+
12
+ var nodes = ['OBJECT', 'TEXTAREA', 'INPUT', 'SELECT', 'OPTION'];
13
+
14
+ var keys = ['Spacebar', ' ', 'Tab', 'ArrowLeft', 'ArrowRight', 'Delete'];
15
+
16
+ /**
17
+ * Configures keyboard event handling.
18
+ *
19
+ * @class
20
+ * @alias KeyboardHandler
21
+ *
22
+ * @param {EventEmitter} eventEmitter
23
+ */
24
+
25
+ function KeyboardHandler(eventEmitter) {
26
+ this.eventEmitter = eventEmitter;
27
+
28
+ this._handleKeyEvent = this._handleKeyEvent.bind(this);
29
+
30
+ this._ctrlCmdPressed = false;
31
+
32
+ document.addEventListener('keydown', this._handleKeyEvent);
33
+ document.addEventListener('keypress', this._handleKeyEvent);
34
+ document.addEventListener('keyup', this._handleKeyEvent);
35
+ }
36
+
37
+ KeyboardHandler.prototype.isCtrlCmdPressed = function handleKeyEvent() {
38
+ return this._ctrlCmdPressed;
39
+ };
40
+
41
+ /**
42
+ * Keyboard event handler function.
43
+ *
44
+ * @note Arrow keys only triggered on keydown, not keypress.
45
+ *
46
+ * @param {KeyboardEvent} event
47
+ * @private
48
+ */
49
+
50
+ KeyboardHandler.prototype._handleKeyEvent = function handleKeyEvent(event) {
51
+ if (nodes.indexOf(event.target.nodeName) === -1) {
52
+ if (keys.indexOf(event.code) > -1) {
53
+ event.preventDefault();
54
+ }
55
+
56
+ if (event.type === 'keydown' || event.type === 'keypress') {
57
+ if ((event.ctrlKey || event.metaKey) && !this._ctrlCmdPressed) {
58
+ this.eventEmitter.emit('keyboard.ctrlCmdDown');
59
+ this._ctrlCmdPressed = true;
60
+ }
61
+ switch (event.code) {
62
+ case 'Spacebar':
63
+ case ' ':
64
+ this.eventEmitter.emit('keyboard.space');
65
+ break;
66
+
67
+ case 'Tab':
68
+ this.eventEmitter.emit('keyboard.tab');
69
+ break;
70
+ }
71
+ }
72
+ else if (event.type === 'keyup') {
73
+ if (!(event.ctrlKey || event.metaKey) && this._ctrlCmdPressed) {
74
+ this.eventEmitter.emit('keyboard.ctrlCmdUp');
75
+ this._ctrlCmdPressed = false;
76
+ }
77
+ switch (event.code) {
78
+ case 'ArrowLeft':
79
+ if (event.shiftKey) {
80
+ this.eventEmitter.emit('keyboard.shift_left');
81
+ }
82
+ else {
83
+ this.eventEmitter.emit('keyboard.left');
84
+ }
85
+ break;
86
+
87
+ case 'ArrowRight':
88
+ if (event.shiftKey) {
89
+ this.eventEmitter.emit('keyboard.shift_right');
90
+ }
91
+ else {
92
+ this.eventEmitter.emit('keyboard.right');
93
+ }
94
+ break;
95
+
96
+ case 'Delete':
97
+ case 'Backspace':
98
+ this.eventEmitter.emit('keyboard.delete');
99
+ break;
100
+ }
101
+ }
102
+ }
103
+ };
104
+
105
+ KeyboardHandler.prototype.destroy = function() {
106
+ document.removeEventListener('keydown', this._handleKeyEvent);
107
+ document.removeEventListener('keypress', this._handleKeyEvent);
108
+ document.removeEventListener('keyup', this._handleKeyEvent);
109
+ };
110
+
111
+ return KeyboardHandler;
112
+ });
@@ -0,0 +1,312 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Defines the {@link LineIndicator} class.
5
+ *
6
+ * @module line-indicator
7
+ */
8
+
9
+ define([
10
+ 'konva',
11
+ './utils'
12
+ ], function(
13
+ Konva,
14
+ Utils) {
15
+ 'use strict';
16
+
17
+ /**
18
+ * Creates a Konva.Stage that displays a representation of each line.
19
+ *
20
+ * @class
21
+ * @alias LineIndicator
22
+ *
23
+ * @param {Peaks} peaks
24
+ * @param {WaveformOverview|WaveformZoomView} view
25
+ */
26
+
27
+ function LineIndicator(peaks, view, container) {
28
+ this._peaks = peaks;
29
+ this._view = view;
30
+ this._container = container;
31
+
32
+ this._width = this._peaks.options.lineIndicatorWidth;
33
+ this._height = this._view.getHeight();
34
+
35
+ this._indicatorRadius = this._width / 4;
36
+
37
+ this._stage = new Konva.Stage({
38
+ container: container,
39
+ width: this._width,
40
+ height: this._height
41
+ });
42
+ this._layer = new Konva.Layer();
43
+ this._stage.add(this._layer);
44
+
45
+ this._indicators = {};
46
+
47
+ this._layer.add(
48
+ new Konva.Line({
49
+ points: [this._width, 0, this._width, this._height],
50
+ stroke: 'gray',
51
+ strokeWidth: 1,
52
+ listening: false
53
+ })
54
+ );
55
+
56
+ this._layer.draw();
57
+
58
+ if (this._peaks.options.enableLineIndicatorContextMenu) {
59
+ this._createContextMenu();
60
+ }
61
+ }
62
+
63
+ LineIndicator.prototype._showMenu = function(menu) {
64
+ menu.style.display = 'block';
65
+ var containerRect = this._stage.container().getBoundingClientRect();
66
+
67
+ menu.style.top = containerRect.top
68
+ + this._stage.getPointerPosition().y
69
+ - menu.offsetHeight + 'px';
70
+ menu.style.left = containerRect.left + this._stage.getPointerPosition().x + 6 + 'px';
71
+ };
72
+
73
+ LineIndicator.prototype._createIndicator = function(line) {
74
+ var indicator = new Konva.Circle({
75
+ x: this._width / 2,
76
+ y: line.getY() + (line.lineHeight() / 2),
77
+ radius: this._indicatorRadius,
78
+ fill: this._peaks.options.lineIndicatorColor,
79
+ strokeWidth: 0,
80
+ lineId: line.getId()
81
+ });
82
+
83
+ var self = this;
84
+
85
+ indicator.on('mouseover', function() {
86
+ indicator.fill(self._peaks.options.lineIndicatorSelected);
87
+ indicator.draw();
88
+ });
89
+
90
+ indicator.on('mouseout', function() {
91
+ indicator.fill(self._peaks.options.lineIndicatorColor);
92
+ indicator.draw();
93
+ });
94
+
95
+ return indicator;
96
+ };
97
+
98
+ LineIndicator.prototype.addIndicator = function(line) {
99
+ if (!this._indicators[line.getId()]) {
100
+ var indicator = this._createIndicator(line);
101
+
102
+ this._layer.add(indicator);
103
+
104
+ this._indicators[line.getId()] = {
105
+ indicator: indicator,
106
+ line: line
107
+ };
108
+ }
109
+ };
110
+
111
+ LineIndicator.prototype.removeIndicator = function(lineId, keepInList) {
112
+ if (this._indicators[lineId]) {
113
+ if (this._indicators[lineId].indicator) {
114
+ this._indicators[lineId].indicator.destroy();
115
+ }
116
+ if (!keepInList) {
117
+ delete this._indicators[lineId];
118
+ }
119
+ else {
120
+ this._indicators[lineId].indicator = null;
121
+ }
122
+ }
123
+ };
124
+
125
+ LineIndicator.prototype.updateIndicator = function(lineId) {
126
+ if (this._indicators[lineId]) {
127
+ var y = this._indicators[lineId].line.getY()
128
+ + (this._indicators[lineId].line.lineHeight() / 2);
129
+
130
+ if (y + this._indicatorRadius > 0 && y - this._indicatorRadius < this._height) {
131
+ // The indicator is visible
132
+ if (!this._indicators[lineId].indicator) {
133
+ this._indicators[lineId].indicator = this._createIndicator(this._indicators[lineId].line);
134
+ this._layer.add(this._indicators[lineId].indicator);
135
+ }
136
+ else {
137
+ this._indicators[lineId].indicator.y(y);
138
+ }
139
+ }
140
+ else {
141
+ // The indicator is out of the view, we remove it
142
+ this.removeIndicator(lineId, true);
143
+ }
144
+ }
145
+ };
146
+
147
+ LineIndicator.prototype.updateIndicators = function() {
148
+ for (var lineId in this._indicators) {
149
+ if (Utils.objectHasProperty(this._indicators, lineId)) {
150
+ this.updateIndicator(lineId);
151
+ }
152
+ }
153
+ };
154
+
155
+ LineIndicator.prototype.draw = function() {
156
+ this._layer.draw();
157
+ };
158
+
159
+ LineIndicator.prototype._createContextMenu = function() {
160
+ var menu = document.createElement('div');
161
+ var addLine = document.createElement('button');
162
+ var addLineAbove = document.createElement('button');
163
+ var addLineBelow = document.createElement('button');
164
+ var deleteLine = document.createElement('button');
165
+ var currentIndicator = null;
166
+ var self = this;
167
+
168
+ menu.style.display = 'none';
169
+ menu.style.position = 'absolute';
170
+ menu.style.backgroundColor = 'white';
171
+ menu.style.boxShadow = '0 0 5px grey';
172
+ menu.style.borderRadius = '3px';
173
+ menu.style.zIndex = 2;
174
+
175
+ addLine.style.display = 'none';
176
+ addLine.style.border = 'none';
177
+ addLine.style.margin = '0';
178
+ addLine.style.width = '100%';
179
+ addLine.style.backgroundColor = 'white';
180
+ addLine.style.padding = '10px';
181
+
182
+ addLine.textContent = 'Add first line';
183
+
184
+ addLine.onmouseover = function() {
185
+ this.style.backgroundColor = 'lightgray';
186
+ };
187
+
188
+ addLine.onmouseout = function() {
189
+ this.style.backgroundColor = 'white';
190
+ };
191
+
192
+ addLineAbove.style.display = 'none';
193
+ addLineAbove.style.border = 'none';
194
+ addLineAbove.style.margin = '0';
195
+ addLineAbove.style.width = '100%';
196
+ addLineAbove.style.backgroundColor = 'white';
197
+ addLineAbove.style.padding = '10px';
198
+
199
+ addLineAbove.textContent = 'Add line above';
200
+
201
+ addLineAbove.onmouseover = function() {
202
+ this.style.backgroundColor = 'lightgray';
203
+ };
204
+
205
+ addLineAbove.onmouseout = function() {
206
+ this.style.backgroundColor = 'white';
207
+ };
208
+
209
+ addLineBelow.style.display = 'none';
210
+ addLineBelow.style.border = 'none';
211
+ addLineBelow.style.margin = '0';
212
+ addLineBelow.style.width = '100%';
213
+ addLineBelow.style.backgroundColor = 'white';
214
+ addLineBelow.style.padding = '10px';
215
+
216
+ addLineBelow.textContent = 'Add line below';
217
+
218
+ addLineBelow.onmouseover = function() {
219
+ this.style.backgroundColor = 'lightgray';
220
+ };
221
+
222
+ addLineBelow.onmouseout = function() {
223
+ this.style.backgroundColor = 'white';
224
+ };
225
+
226
+ deleteLine.style.display = 'none';
227
+ deleteLine.style.border = 'none';
228
+ deleteLine.style.margin = '0';
229
+ deleteLine.style.width = '100%';
230
+ deleteLine.style.backgroundColor = 'white';
231
+ deleteLine.style.padding = '10px';
232
+
233
+ deleteLine.textContent = 'Delete line';
234
+
235
+ deleteLine.onmouseover = function() {
236
+ this.style.backgroundColor = 'lightgray';
237
+ };
238
+
239
+ deleteLine.onmouseout = function() {
240
+ this.style.backgroundColor = 'white';
241
+ };
242
+
243
+ menu.appendChild(addLine);
244
+ menu.appendChild(addLineAbove);
245
+ menu.appendChild(addLineBelow);
246
+ menu.appendChild(deleteLine);
247
+ this._container.appendChild(menu);
248
+
249
+ addLine.addEventListener('click', function() {
250
+ self._peaks.emit('line.add', 0);
251
+ self.draw();
252
+ });
253
+
254
+ addLineAbove.addEventListener('click', function() {
255
+ var line = self._indicators[currentIndicator.getAttr('lineId')].line;
256
+
257
+ self._peaks.emit('line.add', Number(line.getPosition()));
258
+ self.draw();
259
+ });
260
+
261
+ addLineBelow.addEventListener('click', function() {
262
+ var line = self._indicators[currentIndicator.getAttr('lineId')].line;
263
+
264
+ self._peaks.emit('line.add', Number(line.getPosition()) + 1);
265
+ self.draw();
266
+ });
267
+
268
+ deleteLine.addEventListener('click', function() {
269
+ var line = self._indicators[currentIndicator.getAttr('lineId')].line;
270
+
271
+ self._peaks.emit('line.remove', Number(line.getPosition()));
272
+ self.draw();
273
+ });
274
+
275
+ window.addEventListener('click', function() {
276
+ // hide menu
277
+ menu.style.display = 'none';
278
+ });
279
+
280
+ this._stage.on('contextmenu', function(e) {
281
+ // prevent default behavior
282
+ e.evt.preventDefault();
283
+
284
+ if (e.target === self._stage && Object.keys(self._indicators).length === 0) {
285
+ // if we are on empty place of the stage
286
+ // we will show the possibility to add a first line
287
+ addLine.style.display = 'block';
288
+ addLineAbove.style.display = 'none';
289
+ addLineBelow.style.display = 'none';
290
+ deleteLine.style.display = 'none';
291
+
292
+ // show menu
293
+ self._showMenu(menu);
294
+ }
295
+ else if (e.target !== self._stage) {
296
+ currentIndicator = e.target;
297
+
298
+ addLine.style.display = 'none';
299
+ addLineAbove.style.display = 'block';
300
+ addLineBelow.style.display = 'block';
301
+ deleteLine.style.display = 'block';
302
+
303
+ deleteLine.disabled = !self._indicators[currentIndicator.getAttr('lineId')].line.isEmpty();
304
+
305
+ // show menu
306
+ self._showMenu(menu);
307
+ }
308
+ });
309
+ };
310
+
311
+ return LineIndicator;
312
+ });