jellies-draw 0.3.1 → 0.3.3
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.
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
<div class="demo-entry">
|
|
9
9
|
<input type="checkbox" v-model="isCanvasEnabled"/> Enable Canvas
|
|
10
10
|
</div>
|
|
11
|
+
<div class="penetration-test">
|
|
12
|
+
<p>底下可选中的文字:The quick brown fox jumps over the lazy dog. 在 laser 模式下拖一下,应该不选中。</p>
|
|
13
|
+
<button @click="testClickCount++" id="test-button">点我(穿透 click 计数:{{ testClickCount }})</button>
|
|
14
|
+
<p>当前选中字符数:{{ selectionLength }}</p>
|
|
15
|
+
</div>
|
|
11
16
|
<drawing-canvas
|
|
12
17
|
ref="drawingCanvas"
|
|
13
18
|
v-if="isCanvasCreated"
|
|
@@ -29,8 +34,16 @@ export default {
|
|
|
29
34
|
},
|
|
30
35
|
data: () => ({
|
|
31
36
|
isCanvasCreated: false,
|
|
32
|
-
isCanvasVisible: false
|
|
37
|
+
isCanvasVisible: false,
|
|
38
|
+
testClickCount: 0,
|
|
39
|
+
selectionLength: 0
|
|
33
40
|
}),
|
|
41
|
+
mounted() {
|
|
42
|
+
document.addEventListener('selectionchange', () => {
|
|
43
|
+
const sel = window.getSelection()
|
|
44
|
+
this.selectionLength = sel ? sel.toString().length : 0
|
|
45
|
+
})
|
|
46
|
+
},
|
|
34
47
|
computed: {
|
|
35
48
|
isCanvasEnabled: {
|
|
36
49
|
get() {
|
|
@@ -90,4 +103,18 @@ body {
|
|
|
90
103
|
right: 0;
|
|
91
104
|
z-index: 2;
|
|
92
105
|
}
|
|
106
|
+
.penetration-test {
|
|
107
|
+
position: absolute;
|
|
108
|
+
top: 60px;
|
|
109
|
+
left: 20px;
|
|
110
|
+
z-index: 1;
|
|
111
|
+
text-align: left;
|
|
112
|
+
font-size: 18px;
|
|
113
|
+
line-height: 1.7;
|
|
114
|
+
max-width: 600px;
|
|
115
|
+
}
|
|
116
|
+
.penetration-test button {
|
|
117
|
+
font-size: 16px;
|
|
118
|
+
padding: 8px 16px;
|
|
119
|
+
}
|
|
93
120
|
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
2
|
+
<circle cx="12" cy="12" r="10" fill="rgba(243, 59, 41, 0.2)"/>
|
|
3
|
+
<circle cx="12" cy="12" r="6" fill="rgba(243, 59, 41, 0.5)"/>
|
|
4
|
+
<circle cx="12" cy="12" r="3" fill="rgb(255, 110, 90)"/>
|
|
5
|
+
</svg>
|
|
@@ -110,7 +110,10 @@ export default {
|
|
|
110
110
|
}
|
|
111
111
|
},
|
|
112
112
|
_handleKeydown(event) {
|
|
113
|
-
if (!this.hasShortCuts
|
|
113
|
+
if (!this.hasShortCuts) {
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
if (Properties.isCanvasPenetrable && !event.shiftKey) {
|
|
114
117
|
return
|
|
115
118
|
}
|
|
116
119
|
if (event.key === 'Escape') {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import Konva from 'konva';
|
|
2
|
+
import Properties from './properties';
|
|
3
|
+
import laserCursorUrl from '../../assets/laser-cursor.svg';
|
|
2
4
|
|
|
3
5
|
const FADE_DURATION = 700;
|
|
4
|
-
const LASER_WIDTH = 4;
|
|
5
6
|
const DRAG_THRESHOLD = 2;
|
|
6
7
|
const GLOW_COLOR = '243, 59, 41';
|
|
7
8
|
const CORE_COLOR = '255, 110, 90';
|
|
@@ -23,6 +24,7 @@ export default {
|
|
|
23
24
|
_onMouseDown: null,
|
|
24
25
|
_onMouseMove: null,
|
|
25
26
|
_onMouseUp: null,
|
|
27
|
+
_onSelectStart: null,
|
|
26
28
|
_onTick: null,
|
|
27
29
|
|
|
28
30
|
initialize(stage, container) {
|
|
@@ -31,6 +33,7 @@ export default {
|
|
|
31
33
|
this._onMouseDown = this._handleMouseDown.bind(this);
|
|
32
34
|
this._onMouseMove = this._handleMouseMove.bind(this);
|
|
33
35
|
this._onMouseUp = this._handleMouseUp.bind(this);
|
|
36
|
+
this._onSelectStart = this._handleSelectStart.bind(this);
|
|
34
37
|
this._onTick = this._tick.bind(this);
|
|
35
38
|
this.layer = new Konva.Layer({ listening: false });
|
|
36
39
|
this.shape = new Konva.Shape({
|
|
@@ -62,6 +65,11 @@ export default {
|
|
|
62
65
|
window.addEventListener('pointermove', this._onMouseMove, true);
|
|
63
66
|
window.addEventListener('pointerup', this._onMouseUp, true);
|
|
64
67
|
window.addEventListener('pointercancel', this._onMouseUp, true);
|
|
68
|
+
window.addEventListener('selectstart', this._onSelectStart, true);
|
|
69
|
+
this._cursorStyleEl = document.createElement('style');
|
|
70
|
+
this._cursorStyleEl.setAttribute('data-jellies-draw-laser-cursor', '');
|
|
71
|
+
this._cursorStyleEl.textContent = `*, *::before, *::after { cursor: url("${laserCursorUrl}") 12 12, auto !important; }`;
|
|
72
|
+
document.head.appendChild(this._cursorStyleEl);
|
|
65
73
|
this.rafId = requestAnimationFrame(this._onTick);
|
|
66
74
|
},
|
|
67
75
|
|
|
@@ -72,6 +80,11 @@ export default {
|
|
|
72
80
|
window.removeEventListener('pointermove', this._onMouseMove, true);
|
|
73
81
|
window.removeEventListener('pointerup', this._onMouseUp, true);
|
|
74
82
|
window.removeEventListener('pointercancel', this._onMouseUp, true);
|
|
83
|
+
window.removeEventListener('selectstart', this._onSelectStart, true);
|
|
84
|
+
if (this._cursorStyleEl) {
|
|
85
|
+
this._cursorStyleEl.remove();
|
|
86
|
+
this._cursorStyleEl = null;
|
|
87
|
+
}
|
|
75
88
|
if (this.rafId !== null) {
|
|
76
89
|
cancelAnimationFrame(this.rafId);
|
|
77
90
|
this.rafId = null;
|
|
@@ -137,13 +150,23 @@ export default {
|
|
|
137
150
|
}
|
|
138
151
|
this.lastX = pt.x;
|
|
139
152
|
this.lastY = pt.y;
|
|
153
|
+
e.stopPropagation();
|
|
154
|
+
e.preventDefault();
|
|
140
155
|
},
|
|
141
156
|
|
|
142
|
-
_handleMouseUp() {
|
|
157
|
+
_handleMouseUp(e) {
|
|
158
|
+
if (this.hasDragged) {
|
|
159
|
+
e.stopPropagation();
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
}
|
|
143
162
|
this.isPressed = false;
|
|
144
163
|
this.hasDragged = false;
|
|
145
164
|
},
|
|
146
165
|
|
|
166
|
+
_handleSelectStart(e) {
|
|
167
|
+
e.preventDefault();
|
|
168
|
+
},
|
|
169
|
+
|
|
147
170
|
_tick() {
|
|
148
171
|
if (!this.active) return;
|
|
149
172
|
const now = performance.now();
|
|
@@ -170,17 +193,25 @@ export default {
|
|
|
170
193
|
ctx.lineJoin = 'round';
|
|
171
194
|
|
|
172
195
|
ctx.beginPath();
|
|
173
|
-
|
|
196
|
+
let lastX = null;
|
|
197
|
+
let lastY = null;
|
|
174
198
|
for (let i = 0; i < segs.length; i++) {
|
|
175
|
-
|
|
199
|
+
const seg = segs[i];
|
|
200
|
+
if (seg.x1 !== lastX || seg.y1 !== lastY) {
|
|
201
|
+
ctx.moveTo(seg.x1, seg.y1);
|
|
202
|
+
}
|
|
203
|
+
ctx.lineTo(seg.x2, seg.y2);
|
|
204
|
+
lastX = seg.x2;
|
|
205
|
+
lastY = seg.y2;
|
|
176
206
|
}
|
|
177
207
|
|
|
208
|
+
const coreWidth = Properties.strokeWidth || 4;
|
|
178
209
|
ctx.strokeStyle = `rgba(${GLOW_COLOR}, ${opacity * 0.3})`;
|
|
179
|
-
ctx.lineWidth =
|
|
210
|
+
ctx.lineWidth = coreWidth * 2.5;
|
|
180
211
|
ctx.stroke();
|
|
181
212
|
|
|
182
213
|
ctx.strokeStyle = `rgba(${CORE_COLOR}, ${opacity})`;
|
|
183
|
-
ctx.lineWidth =
|
|
214
|
+
ctx.lineWidth = coreWidth;
|
|
184
215
|
ctx.stroke();
|
|
185
216
|
|
|
186
217
|
ctx.restore();
|