tokimeki-image-editor 0.2.2 → 0.2.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.
@@ -553,8 +553,14 @@ function handleKeyDown(event) {
553
553
  display: flex;
554
554
  align-items: center;
555
555
  width: 100%;
556
+ overflow-x: auto;
557
+ scrollbar-width: none;
556
558
  }
557
559
 
560
+ .editor-header::-webkit-scrollbar {
561
+ display: none;
562
+ }
563
+
558
564
  .editor-body {
559
565
  display: flex;
560
566
  flex-direction: column;
@@ -1,36 +1,39 @@
1
1
  <script lang="ts">import { _ } from 'svelte-i18n';
2
2
  import { X } from 'lucide-svelte';
3
3
  let { title, onClose, children, actions } = $props();
4
- // Bottom sheet state (mobile)
5
- let sheetHeight = $state(180);
4
+ // Bottom sheet state (mobile) - using transform for GPU acceleration
5
+ const SHEET_MAX_HEIGHT = 400;
6
+ const SHEET_MIN_VISIBLE = 60;
7
+ let sheetOffset = $state(SHEET_MAX_HEIGHT - 180); // How much to hide (0 = fully shown)
6
8
  let isSheetDragging = $state(false);
7
9
  let sheetDragStart = $state(null);
8
- const SHEET_MIN_HEIGHT = 60;
9
- const SHEET_MAX_HEIGHT = 400;
10
+ let panelElement = $state(null);
10
11
  function getEventCoords(event) {
11
12
  if ('touches' in event && event.touches.length > 0) {
12
- return { clientX: event.touches[0].clientX, clientY: event.touches[0].clientY };
13
+ return { clientY: event.touches[0].clientY };
13
14
  }
14
- else if ('clientX' in event) {
15
- return { clientX: event.clientX, clientY: event.clientY };
15
+ else if ('clientY' in event) {
16
+ return { clientY: event.clientY };
16
17
  }
17
- return { clientX: 0, clientY: 0 };
18
+ return { clientY: 0 };
18
19
  }
19
20
  function handleSheetDragStart(event) {
20
21
  event.preventDefault();
21
22
  event.stopPropagation();
22
23
  const coords = getEventCoords(event);
23
24
  isSheetDragging = true;
24
- sheetDragStart = { y: coords.clientY, height: sheetHeight };
25
+ sheetDragStart = { y: coords.clientY, offset: sheetOffset };
25
26
  }
26
27
  function handleSheetDragMove(event) {
27
28
  if (!isSheetDragging || !sheetDragStart)
28
29
  return;
29
30
  event.preventDefault();
30
31
  const coords = getEventCoords(event);
31
- const deltaY = sheetDragStart.y - coords.clientY;
32
- const newHeight = Math.max(SHEET_MIN_HEIGHT, Math.min(SHEET_MAX_HEIGHT, sheetDragStart.height + deltaY));
33
- sheetHeight = newHeight;
32
+ const deltaY = coords.clientY - sheetDragStart.y;
33
+ // Clamp offset: 0 (fully visible) to (SHEET_MAX_HEIGHT - SHEET_MIN_VISIBLE)
34
+ const maxOffset = SHEET_MAX_HEIGHT - SHEET_MIN_VISIBLE;
35
+ const newOffset = Math.max(0, Math.min(maxOffset, sheetDragStart.offset + deltaY));
36
+ sheetOffset = newOffset;
34
37
  }
35
38
  function handleSheetDragEnd() {
36
39
  isSheetDragging = false;
@@ -46,8 +49,9 @@ function handleSheetDragEnd() {
46
49
  />
47
50
 
48
51
  <div
52
+ bind:this={panelElement}
49
53
  class="tool-panel"
50
- style="--sheet-height: {sheetHeight}px"
54
+ style="--sheet-offset: {sheetOffset}px; --sheet-max-height: {SHEET_MAX_HEIGHT}px"
51
55
  >
52
56
  <!-- Drag handle for mobile bottom sheet -->
53
57
  <div
@@ -106,13 +110,15 @@ function handleSheetDragEnd() {
106
110
  bottom: 0;
107
111
  width: auto;
108
112
  min-width: auto;
109
- height: var(--sheet-height, 180px);
110
- max-height: 70vh;
113
+ height: var(--sheet-max-height, 400px);
111
114
  border-radius: 16px 16px 0 0;
112
115
  z-index: 1001;
113
116
  overflow-y: auto;
117
+ overscroll-behavior: contain;
114
118
  padding-top: 0;
115
- transition: height 0.05s ease-out
119
+ transform: translateY(var(--sheet-offset, 0px));
120
+ will-change: transform;
121
+ backdrop-filter: none
116
122
  }
117
123
  }
118
124
 
@@ -128,7 +134,9 @@ function handleSheetDragEnd() {
128
134
  align-items: center;
129
135
  padding: 12px 0 8px;
130
136
  cursor: grab;
131
- touch-action: none
137
+ touch-action: pan-x;
138
+ user-select: none;
139
+ -webkit-user-select: none
132
140
  }
133
141
 
134
142
  .sheet-drag-handle:active {
@@ -122,13 +122,20 @@ let { mode, hasImage, canUndo, canRedo, isStandalone = false, onModeChange, onUn
122
122
  align-items: center;
123
123
  justify-content: center;
124
124
  overflow-x: auto;
125
+ scrollbar-width: none;
125
126
  }
126
127
 
128
+ .toolbar::-webkit-scrollbar {
129
+ display: none;
130
+ }
131
+
127
132
  @media (max-width: 767px) {
128
133
  .toolbar {
129
134
  justify-content: flex-start;
130
- align-items: stretch;
131
- gap: .5rem
135
+ align-items: center;
136
+ gap: .5rem;
137
+ padding: 0 .5rem;
138
+ -webkit-overflow-scrolling: touch
132
139
  }
133
140
  }
134
141
 
@@ -136,6 +143,7 @@ let { mode, hasImage, canUndo, canRedo, isStandalone = false, onModeChange, onUn
136
143
  display: flex;
137
144
  gap: .25rem;
138
145
  align-items: center;
146
+ flex-shrink: 0;
139
147
  }
140
148
 
141
149
  .history-controls {
@@ -146,10 +154,8 @@ let { mode, hasImage, canUndo, canRedo, isStandalone = false, onModeChange, onUn
146
154
  @media (max-width: 767px) {
147
155
 
148
156
  .history-controls {
149
- border-right: none;
150
- padding-right: 0;
151
- border-bottom: 1px solid #444;
152
- padding-bottom: .5rem
157
+ border-right: 1px solid #444;
158
+ padding-right: .5rem
153
159
  }
154
160
  }
155
161
 
@@ -157,6 +163,13 @@ let { mode, hasImage, canUndo, canRedo, isStandalone = false, onModeChange, onUn
157
163
  gap: .5rem;
158
164
  }
159
165
 
166
+ @media (max-width: 767px) {
167
+
168
+ .mode-controls {
169
+ gap: .25rem
170
+ }
171
+ }
172
+
160
173
  .toolbar-btn {
161
174
  display: flex;
162
175
  align-items: center;
@@ -169,6 +182,7 @@ let { mode, hasImage, canUndo, canRedo, isStandalone = false, onModeChange, onUn
169
182
  cursor: pointer;
170
183
  transition: all 0.2s;
171
184
  font-size: 0.9rem;
185
+ flex-shrink: 0;
172
186
  }
173
187
 
174
188
  @media (max-width: 767px) {
@@ -176,9 +190,11 @@ let { mode, hasImage, canUndo, canRedo, isStandalone = false, onModeChange, onUn
176
190
  .toolbar-btn {
177
191
  flex-direction: column;
178
192
  justify-content: center;
179
- font-size: .6rem;
180
- gap: .3rem;
181
- width: 64px
193
+ font-size: .55rem;
194
+ gap: .2rem;
195
+ padding: .4rem .5rem;
196
+ min-width: 48px;
197
+ width: auto
182
198
  }
183
199
  }
184
200
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokimeki-image-editor",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "A image editor for svelte.",
5
5
  "type": "module",
6
6
  "license": "MIT",