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
|
-
|
|
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
|
-
|
|
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 {
|
|
13
|
+
return { clientY: event.touches[0].clientY };
|
|
13
14
|
}
|
|
14
|
-
else if ('
|
|
15
|
-
return {
|
|
15
|
+
else if ('clientY' in event) {
|
|
16
|
+
return { clientY: event.clientY };
|
|
16
17
|
}
|
|
17
|
-
return {
|
|
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,
|
|
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 =
|
|
32
|
-
|
|
33
|
-
|
|
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: {
|
|
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,
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
150
|
-
padding-right:
|
|
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: .
|
|
180
|
-
gap: .
|
|
181
|
-
|
|
193
|
+
font-size: .55rem;
|
|
194
|
+
gap: .2rem;
|
|
195
|
+
padding: .4rem .5rem;
|
|
196
|
+
min-width: 48px;
|
|
197
|
+
width: auto
|
|
182
198
|
}
|
|
183
199
|
}
|
|
184
200
|
|