tokimeki-image-editor 0.2.0 → 0.2.1

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.
@@ -14,6 +14,10 @@ const colorPresets = ['#FF6B6B', '#FFA94D', '#FFD93D', '#6BCB77', '#4D96FF', '#9
14
14
  // Drawing state
15
15
  let isDrawing = $state(false);
16
16
  let currentAnnotation = $state(null);
17
+ // Panning state (Space + drag)
18
+ let isSpaceHeld = $state(false);
19
+ let isPanning = $state(false);
20
+ let panStart = $state(null);
17
21
  // Helper to get coordinates from mouse or touch event
18
22
  function getEventCoords(event) {
19
23
  if ('touches' in event && event.touches.length > 0) {
@@ -82,16 +86,41 @@ onMount(() => {
82
86
  }
83
87
  };
84
88
  });
89
+ // Keyboard handlers for panning (Space + drag)
90
+ function handleKeyDown(event) {
91
+ if (event.code === 'Space' && !isSpaceHeld) {
92
+ isSpaceHeld = true;
93
+ event.preventDefault();
94
+ }
95
+ }
96
+ function handleKeyUp(event) {
97
+ if (event.code === 'Space') {
98
+ isSpaceHeld = false;
99
+ isPanning = false;
100
+ panStart = null;
101
+ }
102
+ }
85
103
  function handleMouseDown(event) {
86
104
  if (!canvas || !image)
87
105
  return;
88
106
  if ('button' in event && event.button !== 0)
89
107
  return;
90
108
  const coords = getEventCoords(event);
109
+ event.preventDefault();
110
+ // Start panning if space is held
111
+ if (isSpaceHeld) {
112
+ isPanning = true;
113
+ panStart = {
114
+ x: coords.clientX,
115
+ y: coords.clientY,
116
+ offsetX: viewport.offsetX,
117
+ offsetY: viewport.offsetY
118
+ };
119
+ return;
120
+ }
91
121
  const imagePoint = toImageCoords(coords.clientX, coords.clientY);
92
122
  if (!imagePoint)
93
123
  return;
94
- event.preventDefault();
95
124
  if (currentTool === 'eraser') {
96
125
  // Find and remove annotation at click point
97
126
  const canvasPoint = { x: coords.clientX, y: coords.clientY };
@@ -136,9 +165,20 @@ function handleMouseDown(event) {
136
165
  // This absorbs micro-movements of the mouse
137
166
  const MIN_POINT_DISTANCE = 3;
138
167
  function handleMouseMove(event) {
168
+ const coords = getEventCoords(event);
169
+ // Handle panning
170
+ if (isPanning && panStart && onViewportChange) {
171
+ event.preventDefault();
172
+ const dx = coords.clientX - panStart.x;
173
+ const dy = coords.clientY - panStart.y;
174
+ onViewportChange({
175
+ offsetX: panStart.offsetX + dx,
176
+ offsetY: panStart.offsetY + dy
177
+ });
178
+ return;
179
+ }
139
180
  if (!isDrawing || !currentAnnotation || !canvas || !image)
140
181
  return;
141
- const coords = getEventCoords(event);
142
182
  const imagePoint = toImageCoords(coords.clientX, coords.clientY);
143
183
  if (!imagePoint)
144
184
  return;
@@ -165,6 +205,12 @@ function handleMouseMove(event) {
165
205
  }
166
206
  }
167
207
  function handleMouseUp(event) {
208
+ // Stop panning
209
+ if (isPanning) {
210
+ isPanning = false;
211
+ panStart = null;
212
+ return;
213
+ }
168
214
  if (!isDrawing || !currentAnnotation) {
169
215
  isDrawing = false;
170
216
  return;
@@ -295,12 +341,15 @@ let currentAnnotationCanvas = $derived.by(() => {
295
341
  <svelte:window
296
342
  onmousemove={handleMouseMove}
297
343
  onmouseup={handleMouseUp}
344
+ onkeydown={handleKeyDown}
345
+ onkeyup={handleKeyUp}
298
346
  />
299
347
 
300
348
  <!-- Overlay -->
301
349
  <div
302
350
  bind:this={containerElement}
303
351
  class="annotation-tool-overlay"
352
+ class:panning={isSpaceHeld}
304
353
  onmousedown={handleMouseDown}
305
354
  role="button"
306
355
  tabindex="-1"
@@ -565,6 +614,14 @@ let currentAnnotationCanvas = $derived.by(() => {
565
614
  user-select: none;
566
615
  }
567
616
 
617
+ .annotation-tool-overlay.panning {
618
+ cursor: grab;
619
+ }
620
+
621
+ .annotation-tool-overlay.panning:active {
622
+ cursor: grabbing;
623
+ }
624
+
568
625
  .annotation-tool-svg {
569
626
  width: 100%;
570
627
  height: 100%;
@@ -732,7 +789,6 @@ let currentAnnotationCanvas = $derived.by(() => {
732
789
  }
733
790
 
734
791
  .control-group .value {
735
- color: var(--primary-color, #63b97b);
736
792
  font-weight: 600;
737
793
  }
738
794
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokimeki-image-editor",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "A image editor for svelte.",
5
5
  "type": "module",
6
6
  "license": "MIT",