jellies-draw 0.1.8 → 0.1.9

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jellies-draw",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "A drawer for jellies",
5
5
  "private": false,
6
6
  "main": "./src/index.js",
@@ -1,7 +1,12 @@
1
1
  <template>
2
2
  <div
3
3
  ref="container"
4
- class="container"
4
+ :class="[
5
+ 'container',
6
+ {
7
+ 'container-penetrable': isCanvasPenetrable
8
+ }
9
+ ]"
5
10
  >
6
11
  <div
7
12
  ref="whiteboard"
@@ -26,7 +31,7 @@ export default {
26
31
  props: {
27
32
  backgroundColor: {
28
33
  type: String,
29
- default: 'transparent'
34
+ default: 'penetrable'
30
35
  }
31
36
  },
32
37
  computed: {
@@ -38,6 +43,14 @@ export default {
38
43
  },
39
44
  isCrosshairCursorActive() {
40
45
  return (Properties.isUsingDrawingTool && !Properties.isUsingText)
46
+ },
47
+ isCanvasPenetrable() {
48
+ return Properties.isCanvasPenetrable
49
+ }
50
+ },
51
+ watch: {
52
+ isCanvasPenetrable() {
53
+ this.$emit('penetrable-updated', this.isCanvasPenetrable)
41
54
  }
42
55
  },
43
56
  mounted() {
@@ -65,6 +78,11 @@ export default {
65
78
  .container {
66
79
  width: 100%;
67
80
  height: 100%;
81
+ position: relative;
82
+ z-index: 9999; /* 确保画板在最上层 */
83
+ }
84
+ .container-penetrable {
85
+ pointer-events: none;
68
86
  }
69
87
  .cursor-crosshair {
70
88
  cursor: crosshair;
@@ -2,7 +2,10 @@
2
2
  <div
3
3
  :class="[
4
4
  'wrapper',
5
- { active: isActive }
5
+ {
6
+ active: isActive,
7
+ locked: isLocked
8
+ }
6
9
  ]">
7
10
  <button
8
11
  :class="[
@@ -24,11 +27,15 @@ export default {
24
27
  },
25
28
  shortCut: {
26
29
  type: Number,
27
- default: 1
30
+ default: null
28
31
  },
29
32
  isActive: {
30
33
  type: Boolean,
31
34
  default: false
35
+ },
36
+ isLocked: {
37
+ type: Boolean,
38
+ default: false
32
39
  }
33
40
  },
34
41
  methods: {
@@ -93,6 +100,17 @@ button {
93
100
  .wrapper.active > span {
94
101
  color: #399af4;
95
102
  }
103
+ .wrapper.locked {
104
+ background-color: #399af4;
105
+ color: #fff;
106
+ }
107
+ .wrapper.locked:hover {
108
+ margin-top: 3px;
109
+ box-shadow: none;
110
+ }
111
+ .wrapper.locked > span {
112
+ color: #fff;
113
+ }
96
114
  .tool-ellipse:before {
97
115
  content: "\e654";
98
116
  }
@@ -4,8 +4,9 @@
4
4
  v-for="tool, index in tools"
5
5
  :key="tool"
6
6
  :action="tool"
7
- :short-cut="(index + 1) % 10"
7
+ :short-cut="toolShortCut(index)"
8
8
  :is-active="currentTool === tool"
9
+ :is-locked="isCurrentToolLocked && currentTool === tool"
9
10
  @action-applied="applyAction"
10
11
  />
11
12
  <input
@@ -51,6 +52,18 @@ export default {
51
52
  'image',
52
53
  'eraser',
53
54
  'clear'
55
+ ],
56
+ toolsCanBeLocked: [
57
+ 'selector',
58
+ 'rectangle',
59
+ 'ellipse',
60
+ 'arrow',
61
+ 'line'
62
+ ],
63
+ toolsCanBeUsedContinuously: [
64
+ 'pen',
65
+ 'text',
66
+ 'eraser'
54
67
  ]
55
68
  }
56
69
  },
@@ -62,17 +75,41 @@ export default {
62
75
  set(newTool) {
63
76
  Properties.tool = newTool;
64
77
  }
78
+ },
79
+ isCurrentToolLocked: {
80
+ get() {
81
+ return Properties.isToolLocked;
82
+ },
83
+ set(isLocked) {
84
+ Properties.isToolLocked = isLocked;
85
+ }
86
+ },
87
+ latestTool: {
88
+ get() {
89
+ return Properties.latestTool;
90
+ },
91
+ set(newTool) {
92
+ Properties.latestTool = newTool;
93
+ }
94
+ },
95
+ isCanvasPenetrable: {
96
+ get() {
97
+ return Properties.isCanvasPenetrable;
98
+ },
99
+ set(isCanvasPenetrable) {
100
+ Properties.isCanvasPenetrable = isCanvasPenetrable;
101
+ }
65
102
  }
66
103
  },
67
104
  watch: {
68
- currentTool(newTool) {
69
- this.currentTool = newTool;
70
- },
71
105
  hasShortCuts(hasShortCuts) {
72
106
  Canvas.hasShortCuts = hasShortCuts
73
107
  }
74
108
  },
75
109
  methods: {
110
+ toolShortCut(index) {
111
+ return Properties.isUsingText || Properties.isCanvasPenetrable ? null : (index + 1) % 10
112
+ },
76
113
  applyAction(action) {
77
114
  if (action === 'image') {
78
115
  this.$refs.fileSelector.click()
@@ -80,13 +117,27 @@ export default {
80
117
  if (action === 'clear') {
81
118
  Tools.clear.clear()
82
119
  }
120
+ if (this.currentTool !== action &&
121
+ (
122
+ (this.toolsCanBeLocked.includes(this.currentTool) && this.isCurrentToolLocked) ||
123
+ this.toolsCanBeUsedContinuously.includes(this.currentTool)
124
+ )
125
+ ) {
126
+ this.latestTool = {
127
+ 'tool': this.currentTool,
128
+ 'isToolLocked': this.isCurrentToolLocked
129
+ }
130
+ }
131
+ this.isCurrentToolLocked = this.toolsCanBeLocked.includes(action) && this.currentTool === action
83
132
  this.currentTool = action
133
+ this.isCanvasPenetrable = this.currentTool === 'selector' && this.isCurrentToolLocked
84
134
  this.releaseInstantTool()
85
135
  },
86
136
  releaseInstantTool() {
87
137
  if (this.currentTool === 'image' || this.currentTool === 'clear') {
88
138
  setTimeout(() => {
89
- this.currentTool = 'selector'
139
+ Properties.tool = Properties.latestTool.tool
140
+ Properties.isToolLocked = Properties.latestTool.isToolLocked
90
141
  }, 300)
91
142
  }
92
143
  },
@@ -96,7 +147,7 @@ export default {
96
147
  event.target.value = ''
97
148
  },
98
149
  handleShortCutKey(event) {
99
- if (this.hasShortCuts && this.currentTool !== 'text') {
150
+ if (this.hasShortCuts && this.currentTool !== 'text' && !this.isCanvasPenetrable) {
100
151
  const key = event.key
101
152
  const index = parseInt(key, 10)
102
153
  if (index >= 0 && index < this.tools.length) {
@@ -10,6 +10,7 @@ export default {
10
10
  container: null,
11
11
  resizeHandler: null,
12
12
  keydownHandler: null,
13
+ keyupHandler: null,
13
14
  pointerDownHandler: null,
14
15
  pointerMoveHandler: null,
15
16
  pointerUpHandler: null,
@@ -29,6 +30,7 @@ export default {
29
30
  this.layer = new Konva.Layer();
30
31
  this.stage.add(this.layer);
31
32
  document.addEventListener('keydown', this.keydownHandler);
33
+ document.addEventListener('keyup', this.keyupHandler);
32
34
  Transformer.initialize();
33
35
  Histories.record();
34
36
  this.stage.on('pointerdown', this.pointerDownHandler);
@@ -39,6 +41,7 @@ export default {
39
41
  generateEventHandlers() {
40
42
  this.resizeHandler = this._handleResize.bind(this);
41
43
  this.keydownHandler = this._handleKeydown.bind(this);
44
+ this.keyupHandler = this._handleKeyup.bind(this);
42
45
  this.pointerDownHandler = this.handlePointerDown.bind(this);
43
46
  this.pointerMoveHandler = this.handlePointerMove.bind(this);
44
47
  this.pointerUpHandler = this.handlePointerUp.bind(this);
@@ -54,6 +57,7 @@ export default {
54
57
  this.stage.off('pointerup', this.pointerUpHandler);
55
58
  this.stage.off('click tap', this.clickHandler);
56
59
  document.removeEventListener('keydown', this.keydownHandler);
60
+ document.removeEventListener('keyup', this.keyupHandler);
57
61
  this.stage.clear()
58
62
  this.stage = null;
59
63
  window.removeEventListener('resize', this.resizeHandler);
@@ -66,7 +70,7 @@ export default {
66
70
  }
67
71
  },
68
72
  _handleKeydown(event) {
69
- if (!this.hasShortCuts) {
73
+ if (!this.hasShortCuts || Properties.isCanvasPenetrable) {
70
74
  return
71
75
  }
72
76
  if (event.key === 'Escape') {
@@ -77,6 +81,20 @@ export default {
77
81
  if (!this.isEditingText) {
78
82
  this._handleKeyShortCuts(event);
79
83
  }
84
+ } else if (event.altKey) {
85
+ Properties.isCanvasPenetrable = true;
86
+ }
87
+ },
88
+ _handleKeyup(event) {
89
+ if (event.key === 'Alt') {
90
+ Properties.isCanvasPenetrable = false;
91
+ if (Properties.tool === 'selector') {
92
+ Properties.isToolLocked = false;
93
+ Properties.latestTool = {
94
+ 'tool': 'selector',
95
+ 'isToolLocked': false
96
+ }
97
+ }
80
98
  }
81
99
  },
82
100
  _handleKeyShortCuts(event) {
@@ -10,8 +10,14 @@ export default new Vue({
10
10
  fontSizeSelected: 20,
11
11
  strokeWidthSelected: 4,
12
12
  toolSelected: 'pen',
13
+ toolLatestSelected: {
14
+ 'tool': 'pen',
15
+ 'isToolLocked': false
16
+ },
13
17
  isTextNodesSelected: false,
14
- isMassivelyAssigningProperties: false
18
+ isMassivelyAssigningProperties: false,
19
+ isToolLocked: false,
20
+ isCanvasPenetrable: false
15
21
  }
16
22
  },
17
23
  computed: {
@@ -75,6 +81,14 @@ export default new Vue({
75
81
  this.toolSelected = newTool;
76
82
  }
77
83
  },
84
+ latestTool: {
85
+ get() {
86
+ return this.toolLatestSelected;
87
+ },
88
+ set(newTool) {
89
+ this.toolLatestSelected = newTool;
90
+ }
91
+ },
78
92
  isUsingText() {
79
93
  return this.tool === 'text' || this.isTextNodesSelected;
80
94
  },
@@ -85,6 +99,9 @@ export default new Vue({
85
99
  watch: {
86
100
  toolSelected() {
87
101
  this.refreshNodesStatus()
102
+ if (this.tool === 'selector' && this.isToolLocked) {
103
+ this.isCanvasPenetrable = true;
104
+ }
88
105
  }
89
106
  },
90
107
  methods: {
@@ -30,7 +30,10 @@ export default {
30
30
  }
31
31
  },
32
32
  finish() {
33
- Properties.tool = 'selector'
33
+ if (!Properties.isToolLocked) {
34
+ Properties.tool = Properties.latestTool.tool
35
+ Properties.isToolLocked = Properties.latestTool.isToolLocked
36
+ }
34
37
  this.temporalShape = null
35
38
  },
36
39
  bindEvents(newArrow) {
@@ -35,7 +35,10 @@ export default {
35
35
  }
36
36
  },
37
37
  finish() {
38
- Properties.tool = 'selector'
38
+ if (!Properties.isToolLocked) {
39
+ Properties.tool = Properties.latestTool.tool
40
+ Properties.isToolLocked = Properties.latestTool.isToolLocked
41
+ }
39
42
  this.temporalShape = null
40
43
  },
41
44
  _checkEllipseAndChangeToVertex(newEllipse) {
@@ -26,7 +26,10 @@ export default {
26
26
  }
27
27
  },
28
28
  finish() {
29
- Properties.tool = 'selector'
29
+ if (!Properties.isToolLocked) {
30
+ Properties.tool = Properties.latestTool.tool
31
+ Properties.isToolLocked = Properties.latestTool.isToolLocked
32
+ }
30
33
  this.temporalShape = null
31
34
  },
32
35
  generate({ x, y, scaleX, scaleY, points, stroke, strokeWidth }) {
@@ -33,7 +33,10 @@ export default {
33
33
  }
34
34
  },
35
35
  finish() {
36
- Properties.tool = 'selector'
36
+ if (!Properties.isToolLocked) {
37
+ Properties.tool = Properties.latestTool.tool
38
+ Properties.isToolLocked = Properties.latestTool.isToolLocked
39
+ }
37
40
  this.temporalShape = null
38
41
  },
39
42
  _checkRectangleAndChangeToCell(newRectangle) {