@netless/fastboard-ui 1.0.0-canary.0 → 1.0.0-canary.10
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/dist/index.css +888 -0
- package/dist/index.d.ts +95 -69
- package/dist/index.js +7338 -2009
- package/dist/index.mjs +7342 -2011
- package/dist/index.svelte.mjs +10001 -3775
- package/package.json +6 -3
- package/src/actions/scroll.ts +1 -1
- package/src/actions/tippy.ts +9 -5
- package/src/behaviors/apps.ts +4 -38
- package/src/components/Button/Button.svelte +4 -1
- package/src/components/Button/Button.svelte.d.ts +2 -2
- package/src/components/Fastboard/Fastboard.scss +2 -3
- package/src/components/Fastboard/Fastboard.svelte +11 -4
- package/src/components/Fastboard/{Fastboard.svelte.ts → Fastboard.svelte.d.ts} +1 -1
- package/src/components/Fastboard/ReplayFastboard.svelte +13 -3
- package/src/components/Fastboard/{ReplayFastboard.svelte.ts → ReplayFastboard.svelte.d.ts} +2 -1
- package/src/components/Icons/Curve.svelte +10 -0
- package/src/components/Icons/CurveDashed.svelte +16 -0
- package/src/components/Icons/Eraser.svelte +35 -1
- package/src/components/Icons/EraserFilled.svelte +2 -2
- package/src/components/Icons/PencilEraser.svelte +16 -0
- package/src/components/Icons/PencilEraserFilled.svelte +16 -0
- package/src/components/Icons/index.ts +11 -0
- package/src/components/PageControl/PageControl.svelte +2 -2
- package/src/components/Toolbar/README.md +1 -1
- package/src/components/Toolbar/Toolbar.scss +5 -5
- package/src/components/Toolbar/Toolbar.svelte +24 -10
- package/src/components/Toolbar/Toolbar.svelte.d.ts +18 -1
- package/src/components/Toolbar/components/Contents.scss +14 -3
- package/src/components/Toolbar/components/Contents.svelte +191 -22
- package/src/components/Toolbar/components/PencilEraserSize.svelte +27 -0
- package/src/components/Toolbar/components/Shapes.svelte +1 -0
- package/src/components/Toolbar/components/Slider.svelte +0 -1
- package/src/components/Toolbar/components/StrokeColor.svelte +1 -0
- package/src/components/Toolbar/components/TextColor.svelte +1 -0
- package/src/components/Toolbar/components/constants.ts +32 -4
- package/src/components/Toolbar/components/helper.ts +1 -1
- package/src/components/ZoomControl/ZoomControl.svelte +5 -3
- package/src/components/theme.scss +11 -4
- package/src/helpers/index.ts +72 -48
- package/src/index.ts +8 -4
- package/src/style.scss +4 -0
- package/src/typings.ts +16 -6
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/index.svelte.mjs.map +0 -1
|
@@ -3,22 +3,23 @@
|
|
|
3
3
|
import type { Writable } from "svelte/store";
|
|
4
4
|
import type { Placement } from "tippy.js";
|
|
5
5
|
import type { Language, Theme } from "../../../typings";
|
|
6
|
-
import type { Shape } from "./constants";
|
|
7
|
-
import { applianceShapes, shapesIcon, shapesIconActive } from "./constants";
|
|
6
|
+
import type { Shape, Eraser } from "./constants";
|
|
7
|
+
import { eraserIcon, eraserIconActive, applianceShapes, shapesIcon, shapesIconActive } from "./constants";
|
|
8
8
|
import { writable } from "svelte/store";
|
|
9
9
|
import { scrollHeight } from "../../../actions/height";
|
|
10
10
|
import { scrollTop } from "../../../actions/scroll";
|
|
11
|
+
import { tippy_hide_all } from "../../../actions/tippy";
|
|
11
12
|
import { clamp } from "../../helpers";
|
|
12
13
|
import { i18n } from "./constants";
|
|
13
|
-
import {
|
|
14
|
+
import { stockedApps } from "../../../behaviors";
|
|
14
15
|
import { tooltip } from "./helper";
|
|
15
16
|
import Icons from "../../Icons";
|
|
16
17
|
import Button from "../../Button";
|
|
17
18
|
import StrokeWidth from "./StrokeWidth.svelte";
|
|
18
19
|
import StrokeColor from "./StrokeColor.svelte";
|
|
20
|
+
import PencilEraserSize from "./PencilEraserSize.svelte";
|
|
19
21
|
import TextColor from "./TextColor.svelte";
|
|
20
22
|
import Shapes from "./Shapes.svelte";
|
|
21
|
-
import { tippy_hide_all } from "../../../actions/tippy";
|
|
22
23
|
|
|
23
24
|
export let app: FastboardApp | null | undefined = null;
|
|
24
25
|
export let theme: Theme = "light";
|
|
@@ -27,15 +28,19 @@
|
|
|
27
28
|
export let scroll_height: Writable<number>;
|
|
28
29
|
export let computed_height = 0;
|
|
29
30
|
export let scrollable = false;
|
|
31
|
+
export let hide_dotted = false;
|
|
30
32
|
export let hide_apps = false;
|
|
33
|
+
export let eraser_type: "delete" | "pencil" | "both" = "both";
|
|
31
34
|
|
|
32
35
|
const name = "fastboard-toolbar";
|
|
33
36
|
|
|
34
37
|
let last_shape: Shape = "rectangle";
|
|
38
|
+
let last_eraser: Eraser = "pencilEraser";
|
|
35
39
|
|
|
36
40
|
let pencil_panel: HTMLDivElement;
|
|
37
41
|
let text_panel: HTMLDivElement;
|
|
38
42
|
let shapes_panel: HTMLDivElement;
|
|
43
|
+
let eraser_panel: HTMLDivElement;
|
|
39
44
|
let apps_panel: HTMLDivElement;
|
|
40
45
|
|
|
41
46
|
let btn_props: { name: string; theme: Theme; disabled: boolean; placement: Placement };
|
|
@@ -47,10 +52,14 @@
|
|
|
47
52
|
selector: tooltip(t.selector, hotkeys?.changeToSelector),
|
|
48
53
|
pencil: tooltip(t.pencil, hotkeys?.changeToPencil),
|
|
49
54
|
eraser: tooltip(t.eraser, hotkeys?.changeToEraser),
|
|
55
|
+
pencilEraser: tooltip(t.pencilEraser, hotkeys?.changeToPencilEraser),
|
|
56
|
+
eraserForPanel: tooltip(t.eraser, hotkeys?.changeToEraser),
|
|
57
|
+
pencilEraserForPanel: tooltip(t.pencilEraser, hotkeys?.changeToPencilEraser),
|
|
50
58
|
text: tooltip(t.text, hotkeys?.changeToText),
|
|
51
59
|
};
|
|
52
60
|
$: memberState = app?.memberState;
|
|
53
61
|
$: appliance = $memberState?.currentApplianceName;
|
|
62
|
+
$: dotted = $memberState?.dottedLine;
|
|
54
63
|
$: shape = $memberState?.shapeType;
|
|
55
64
|
$: status = app?.appsStatus;
|
|
56
65
|
|
|
@@ -60,6 +69,10 @@
|
|
|
60
69
|
last_shape = shape;
|
|
61
70
|
}
|
|
62
71
|
|
|
72
|
+
$: if (["pencilEraser", "eraser"].includes(appliance as Appliance)) {
|
|
73
|
+
last_eraser = appliance as "pencilEraser" | "eraser";
|
|
74
|
+
}
|
|
75
|
+
|
|
63
76
|
$: max_scroll = scrollable ? $scroll_height + (32 + 8) * 2 - computed_height : 0;
|
|
64
77
|
|
|
65
78
|
let top = writable(0);
|
|
@@ -83,6 +96,12 @@
|
|
|
83
96
|
function text() {
|
|
84
97
|
app?.setAppliance("text");
|
|
85
98
|
}
|
|
99
|
+
function set_dotted() {
|
|
100
|
+
app?.toggleDottedLine(true);
|
|
101
|
+
}
|
|
102
|
+
function unset_dotted() {
|
|
103
|
+
app?.toggleDottedLine(false);
|
|
104
|
+
}
|
|
86
105
|
function select_last_shape() {
|
|
87
106
|
if (applianceShapes.includes(last_shape as Appliance)) {
|
|
88
107
|
app?.setAppliance(last_shape as Appliance);
|
|
@@ -90,9 +109,15 @@
|
|
|
90
109
|
app?.setAppliance("shape", last_shape as Exclude<Shape, Appliance>);
|
|
91
110
|
}
|
|
92
111
|
}
|
|
93
|
-
function
|
|
112
|
+
function select_last_eraser() {
|
|
113
|
+
app?.setAppliance(last_eraser);
|
|
114
|
+
}
|
|
115
|
+
function select_eraser() {
|
|
94
116
|
app?.setAppliance("eraser");
|
|
95
117
|
}
|
|
118
|
+
function select_pencil_eraser() {
|
|
119
|
+
app?.setAppliance("pencilEraser");
|
|
120
|
+
}
|
|
96
121
|
function clear() {
|
|
97
122
|
app?.cleanCurrentScene();
|
|
98
123
|
}
|
|
@@ -104,51 +129,120 @@
|
|
|
104
129
|
</Button>
|
|
105
130
|
{/if}
|
|
106
131
|
<div class="{name}-scrollable" class:scrollable use:scrollHeight={scroll_height} use:scrollTop={top}>
|
|
107
|
-
<Button
|
|
132
|
+
<Button
|
|
133
|
+
class="clicker"
|
|
134
|
+
active={appliance === "clicker"}
|
|
135
|
+
{...btn_props}
|
|
136
|
+
on:click={clicker}
|
|
137
|
+
content={c.clicker}
|
|
138
|
+
>
|
|
108
139
|
{#if appliance === "clicker"}
|
|
109
140
|
<Icons.ClickFilled {theme} active />
|
|
110
141
|
{:else}
|
|
111
142
|
<Icons.Click {theme} />
|
|
112
143
|
{/if}
|
|
113
144
|
</Button>
|
|
114
|
-
<Button
|
|
145
|
+
<Button
|
|
146
|
+
class="selector"
|
|
147
|
+
active={appliance === "selector"}
|
|
148
|
+
{...btn_props}
|
|
149
|
+
on:click={selector}
|
|
150
|
+
content={c.selector}
|
|
151
|
+
>
|
|
115
152
|
{#if appliance === "selector"}
|
|
116
153
|
<Icons.SelectorFilled {theme} active />
|
|
117
154
|
{:else}
|
|
118
155
|
<Icons.Selector {theme} />
|
|
119
156
|
{/if}
|
|
120
157
|
</Button>
|
|
121
|
-
<Button
|
|
158
|
+
<Button
|
|
159
|
+
class="pencil"
|
|
160
|
+
active={appliance === "pencil"}
|
|
161
|
+
{...btn_props}
|
|
162
|
+
on:click={pencil}
|
|
163
|
+
content={c.pencil}
|
|
164
|
+
menu={pencil_panel}
|
|
165
|
+
>
|
|
122
166
|
{#if appliance === "pencil"}
|
|
123
167
|
<Icons.PencilFilled {theme} active />
|
|
124
168
|
{:else}
|
|
125
169
|
<Icons.Pencil {theme} />
|
|
126
170
|
{/if}
|
|
127
171
|
</Button>
|
|
128
|
-
<Button
|
|
172
|
+
<Button
|
|
173
|
+
class="text"
|
|
174
|
+
active={appliance === "text"}
|
|
175
|
+
{...btn_props}
|
|
176
|
+
on:click={text}
|
|
177
|
+
content={c.text}
|
|
178
|
+
menu={text_panel}
|
|
179
|
+
>
|
|
129
180
|
{#if appliance === "text"}
|
|
130
181
|
<Icons.TextFilled {theme} active />
|
|
131
182
|
{:else}
|
|
132
183
|
<Icons.Text {theme} />
|
|
133
184
|
{/if}
|
|
134
185
|
</Button>
|
|
135
|
-
<Button
|
|
186
|
+
<Button
|
|
187
|
+
class="shapes"
|
|
188
|
+
active={appliance === last_shape || (appliance === "shape" && shape === last_shape)}
|
|
189
|
+
{...btn_props}
|
|
190
|
+
on:click={select_last_shape}
|
|
191
|
+
content={t.shapes}
|
|
192
|
+
menu={shapes_panel}
|
|
193
|
+
>
|
|
136
194
|
{#if appliance === last_shape || (appliance === "shape" && shape === last_shape)}
|
|
137
195
|
<svelte:component this={shapesIconActive[last_shape]} {theme} active />
|
|
138
196
|
{:else}
|
|
139
197
|
<svelte:component this={shapesIcon[last_shape]} {theme} />
|
|
140
198
|
{/if}
|
|
141
199
|
</Button>
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
200
|
+
{#if eraser_type === "delete"}
|
|
201
|
+
<Button
|
|
202
|
+
class="eraser"
|
|
203
|
+
active={appliance === "eraser"}
|
|
204
|
+
{...btn_props}
|
|
205
|
+
on:click={select_eraser}
|
|
206
|
+
content={c.eraser}
|
|
207
|
+
menu={eraser_panel}
|
|
208
|
+
>
|
|
209
|
+
{#if appliance === "eraser"}
|
|
210
|
+
<Icons.EraserFilled {theme} active />
|
|
211
|
+
{:else}
|
|
212
|
+
<Icons.Eraser {theme} />
|
|
213
|
+
{/if}
|
|
214
|
+
</Button>
|
|
215
|
+
{:else if eraser_type === "pencil"}
|
|
216
|
+
<Button
|
|
217
|
+
class="eraser"
|
|
218
|
+
active={appliance === "pencilEraser"}
|
|
219
|
+
{...btn_props}
|
|
220
|
+
on:click={select_pencil_eraser}
|
|
221
|
+
content={c.pencilEraser}
|
|
222
|
+
menu={eraser_panel}
|
|
223
|
+
>
|
|
224
|
+
{#if appliance === "pencilEraser"}
|
|
225
|
+
<Icons.PencilEraserFilled {theme} active />
|
|
226
|
+
{:else}
|
|
227
|
+
<Icons.PencilEraser {theme} />
|
|
228
|
+
{/if}
|
|
229
|
+
</Button>
|
|
230
|
+
{:else}
|
|
231
|
+
<Button
|
|
232
|
+
class="eraser"
|
|
233
|
+
active={appliance === last_eraser}
|
|
234
|
+
{...btn_props}
|
|
235
|
+
on:click={select_last_eraser}
|
|
236
|
+
content={t[last_eraser]}
|
|
237
|
+
menu={eraser_panel}
|
|
238
|
+
>
|
|
239
|
+
{#if appliance === last_eraser}
|
|
240
|
+
<svelte:component this={eraserIconActive[last_eraser]} {theme} active />
|
|
241
|
+
{:else}
|
|
242
|
+
<svelte:component this={eraserIcon[last_eraser]} {theme} />
|
|
243
|
+
{/if}
|
|
244
|
+
</Button>
|
|
245
|
+
{/if}
|
|
152
246
|
{#if !hide_apps}
|
|
153
247
|
<Button class="apps" {...btn_props} content={t.apps} menu={apps_panel} menu_placement="right-end">
|
|
154
248
|
<Icons.Apps {theme} />
|
|
@@ -163,6 +257,31 @@
|
|
|
163
257
|
|
|
164
258
|
<div class="{name}-panel-wrapper" style="display:none">
|
|
165
259
|
<div class="{name}-panel pencil" bind:this={pencil_panel}>
|
|
260
|
+
{#if !hide_dotted}
|
|
261
|
+
<div class="{name}-panel-btns">
|
|
262
|
+
<Button
|
|
263
|
+
class="pencil"
|
|
264
|
+
active={appliance === "pencil" && !dotted}
|
|
265
|
+
{...btn_props}
|
|
266
|
+
on:click={unset_dotted}
|
|
267
|
+
placement="top"
|
|
268
|
+
content={t.solid}
|
|
269
|
+
>
|
|
270
|
+
<Icons.Curve {theme} active={appliance === "pencil" && !dotted} />
|
|
271
|
+
</Button>
|
|
272
|
+
<Button
|
|
273
|
+
class="pencil"
|
|
274
|
+
active={appliance === "pencil" && dotted}
|
|
275
|
+
{...btn_props}
|
|
276
|
+
on:click={set_dotted}
|
|
277
|
+
placement="top"
|
|
278
|
+
content={t.dashed}
|
|
279
|
+
>
|
|
280
|
+
<Icons.CurveDashed {theme} active={appliance === "pencil" && dotted} />
|
|
281
|
+
</Button>
|
|
282
|
+
</div>
|
|
283
|
+
<div class="{name}-panel-divider" />
|
|
284
|
+
{/if}
|
|
166
285
|
<StrokeWidth {app} {theme} {disabled} />
|
|
167
286
|
<div class="{name}-panel-divider" />
|
|
168
287
|
<StrokeColor {app} {theme} {disabled} />
|
|
@@ -177,8 +296,58 @@
|
|
|
177
296
|
<div class="{name}-panel-divider" />
|
|
178
297
|
<StrokeColor {app} {theme} {disabled} />
|
|
179
298
|
</div>
|
|
180
|
-
<div class="{name}-panel
|
|
181
|
-
{#
|
|
299
|
+
<div class="{name}-panel eraser" bind:this={eraser_panel}>
|
|
300
|
+
{#if eraser_type === "both"}
|
|
301
|
+
<div class="{name}-panel-btns">
|
|
302
|
+
<Button
|
|
303
|
+
class="eraser"
|
|
304
|
+
active={appliance === "pencilEraser"}
|
|
305
|
+
{...btn_props}
|
|
306
|
+
on:click={select_pencil_eraser}
|
|
307
|
+
placement="top"
|
|
308
|
+
content={c.pencilEraserForPanel}
|
|
309
|
+
>
|
|
310
|
+
{#if appliance === "pencilEraser"}
|
|
311
|
+
<Icons.PencilEraserFilled {theme} active />
|
|
312
|
+
{:else}
|
|
313
|
+
<Icons.PencilEraser {theme} />
|
|
314
|
+
{/if}
|
|
315
|
+
</Button>
|
|
316
|
+
<Button
|
|
317
|
+
class="eraser"
|
|
318
|
+
active={appliance === "eraser"}
|
|
319
|
+
{...btn_props}
|
|
320
|
+
on:click={select_eraser}
|
|
321
|
+
placement="top"
|
|
322
|
+
content={c.eraserForPanel}
|
|
323
|
+
>
|
|
324
|
+
{#if appliance === "eraser"}
|
|
325
|
+
<Icons.EraserFilled {theme} active />
|
|
326
|
+
{:else}
|
|
327
|
+
<Icons.Eraser {theme} />
|
|
328
|
+
{/if}
|
|
329
|
+
</Button>
|
|
330
|
+
<Button class="clear" {...btn_props} on:click={clear} placement="top" content={t.clear}>
|
|
331
|
+
<Icons.Clear {theme} />
|
|
332
|
+
</Button>
|
|
333
|
+
</div>
|
|
334
|
+
{#if appliance === "pencilEraser"}
|
|
335
|
+
<div class="{name}-panel-divider" />
|
|
336
|
+
<PencilEraserSize {app} {theme} {disabled} />
|
|
337
|
+
{/if}
|
|
338
|
+
{:else}
|
|
339
|
+
<div class="{name}-panel-btns">
|
|
340
|
+
<Button class="clear" {...btn_props} on:click={clear} placement="top" content={t.clear}>
|
|
341
|
+
<Icons.Clear {theme} />
|
|
342
|
+
</Button>
|
|
343
|
+
</div>
|
|
344
|
+
{#if eraser_type === "pencil"}
|
|
345
|
+
<PencilEraserSize {app} {theme} {disabled} />
|
|
346
|
+
{/if}
|
|
347
|
+
{/if}
|
|
348
|
+
</div>
|
|
349
|
+
<div class="{name}-panel apps" style="--n:{$stockedApps.length}" bind:this={apps_panel}>
|
|
350
|
+
{#each $stockedApps as netless_app}
|
|
182
351
|
{@const { icon, label, kind, onClick } = netless_app}
|
|
183
352
|
{@const state = $status && $status[kind]}
|
|
184
353
|
{@const on_click = () => {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { FastboardApp } from "@netless/fastboard-core";
|
|
3
|
+
import type { Theme } from "../../../typings";
|
|
4
|
+
import Slider from "./Slider.svelte";
|
|
5
|
+
|
|
6
|
+
export let app: FastboardApp | null | undefined = null;
|
|
7
|
+
export let theme: Theme = "light";
|
|
8
|
+
export let disabled = false;
|
|
9
|
+
|
|
10
|
+
$: memberState = app?.memberState;
|
|
11
|
+
$: value = $memberState?.pencilEraserSize ?? 1;
|
|
12
|
+
|
|
13
|
+
$: props = { value, theme, disabled };
|
|
14
|
+
|
|
15
|
+
function set_pencil_eraser_size({ detail: value }: CustomEvent<number>) {
|
|
16
|
+
app?.setPencilEraserSize(value);
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<Slider
|
|
21
|
+
class="fastboard-toolbar-slider pencil-eraser-size"
|
|
22
|
+
{...props}
|
|
23
|
+
min={1}
|
|
24
|
+
max={3}
|
|
25
|
+
step={1}
|
|
26
|
+
on:change={set_pencil_eraser_size}
|
|
27
|
+
/>
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
}
|
|
66
66
|
</script>
|
|
67
67
|
|
|
68
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
68
69
|
<div class="fastboard-toolbar-shapes {theme}" on:click={set_appliance_or_shape}>
|
|
69
70
|
{#each shapes as key (key)}
|
|
70
71
|
{@const is_selected = appliance === "shape" ? shape === key : appliance === key}
|
|
@@ -24,11 +24,10 @@ export const shapes = [
|
|
|
24
24
|
"speechBalloon",
|
|
25
25
|
] as const;
|
|
26
26
|
|
|
27
|
-
export type Shape = typeof shapes[number];
|
|
27
|
+
export type Shape = (typeof shapes)[number];
|
|
28
28
|
|
|
29
29
|
export const applianceShapes = shapes.slice(0, 4) as Appliance[];
|
|
30
30
|
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
31
|
export const shapesIcon: Record<Shape, any> = {
|
|
33
32
|
rectangle: Icons.Rectangle,
|
|
34
33
|
ellipse: Icons.Circle,
|
|
@@ -40,7 +39,6 @@ export const shapesIcon: Record<Shape, any> = {
|
|
|
40
39
|
speechBalloon: Icons.Balloon,
|
|
41
40
|
};
|
|
42
41
|
|
|
43
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
42
|
export const shapesIconActive: Record<Shape, any> = {
|
|
45
43
|
rectangle: Icons.RectangleBolded,
|
|
46
44
|
ellipse: Icons.CircleBolded,
|
|
@@ -52,28 +50,58 @@ export const shapesIconActive: Record<Shape, any> = {
|
|
|
52
50
|
speechBalloon: Icons.BalloonBolded,
|
|
53
51
|
};
|
|
54
52
|
|
|
53
|
+
export const erasers = ["eraser", "pencilEraser"] as const;
|
|
54
|
+
|
|
55
|
+
export type Eraser = (typeof erasers)[number];
|
|
56
|
+
|
|
57
|
+
export const eraserIcon: Record<Eraser, any> = {
|
|
58
|
+
eraser: Icons.Eraser,
|
|
59
|
+
pencilEraser: Icons.PencilEraser,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const eraserIconActive: Record<Eraser, any> = {
|
|
63
|
+
eraser: Icons.EraserFilled,
|
|
64
|
+
pencilEraser: Icons.PencilEraserFilled,
|
|
65
|
+
};
|
|
66
|
+
|
|
55
67
|
export const i18n: I18nData<
|
|
56
|
-
|
|
68
|
+
| "clicker"
|
|
69
|
+
| "selector"
|
|
70
|
+
| "pencil"
|
|
71
|
+
| "pencilEraser"
|
|
72
|
+
| "text"
|
|
73
|
+
| "shapes"
|
|
74
|
+
| "eraser"
|
|
75
|
+
| "clear"
|
|
76
|
+
| "apps"
|
|
77
|
+
| "solid"
|
|
78
|
+
| "dashed"
|
|
57
79
|
> = {
|
|
58
80
|
en: {
|
|
59
81
|
clicker: "clicker",
|
|
60
82
|
selector: "selector",
|
|
61
83
|
pencil: "pencil",
|
|
62
84
|
eraser: "eraser",
|
|
85
|
+
pencilEraser: "eraser",
|
|
63
86
|
text: "text",
|
|
64
87
|
shapes: "shapes",
|
|
65
88
|
clear: "clear",
|
|
66
89
|
apps: "apps",
|
|
90
|
+
solid: "solid",
|
|
91
|
+
dashed: "dashed",
|
|
67
92
|
},
|
|
68
93
|
"zh-CN": {
|
|
69
94
|
clicker: "点击",
|
|
70
95
|
selector: "选择",
|
|
71
96
|
pencil: "铅笔",
|
|
72
97
|
eraser: "橡皮",
|
|
98
|
+
pencilEraser: "板擦",
|
|
73
99
|
text: "文字",
|
|
74
100
|
shapes: "形状",
|
|
75
101
|
clear: "清屏",
|
|
76
102
|
apps: "Apps",
|
|
103
|
+
solid: "实线",
|
|
104
|
+
dashed: "虚线",
|
|
77
105
|
},
|
|
78
106
|
};
|
|
79
107
|
|
|
@@ -57,8 +57,10 @@
|
|
|
57
57
|
|
|
58
58
|
$: camera = app?.camera;
|
|
59
59
|
$: scale = $camera?.scale ?? 1;
|
|
60
|
-
$: plus_disabled = disabled || next_scale(scale, 1)
|
|
61
|
-
$: minus_disabled = disabled || next_scale(scale, -1)
|
|
60
|
+
$: plus_disabled = disabled || next_scale(scale, 1) <= scale;
|
|
61
|
+
$: minus_disabled = disabled || next_scale(scale, -1) >= scale;
|
|
62
|
+
|
|
63
|
+
$: display_scale = clamp(Math.round(scale * 100), 30, 300);
|
|
62
64
|
|
|
63
65
|
function plus() {
|
|
64
66
|
app?.moveCamera({ scale: next_scale(scale, 1), centerX: 0, centerY: 0 });
|
|
@@ -83,7 +85,7 @@
|
|
|
83
85
|
{#if $camera == null}
|
|
84
86
|
…
|
|
85
87
|
{:else}
|
|
86
|
-
{
|
|
88
|
+
{display_scale}%
|
|
87
89
|
{/if}
|
|
88
90
|
</span>
|
|
89
91
|
<Button class="minus" {name} {theme} disabled={minus_disabled} on:click={minus} content={t.minus}>
|
|
@@ -7,6 +7,7 @@ $themes: (
|
|
|
7
7
|
active-color: $blue-6,
|
|
8
8
|
bg-color: color.change(white, $alpha: 0.9),
|
|
9
9
|
hover-bg-color: $blue-1,
|
|
10
|
+
active-bg-color: $blue-1,
|
|
10
11
|
border-color: $grey-1,
|
|
11
12
|
),
|
|
12
13
|
dark: (
|
|
@@ -14,6 +15,7 @@ $themes: (
|
|
|
14
15
|
active-color: $blue-7,
|
|
15
16
|
bg-color: color.change($grey-10, $alpha: 0.9),
|
|
16
17
|
hover-bg-color: $grey-8,
|
|
18
|
+
active-bg-color: $grey-8,
|
|
17
19
|
border-color: $grey-8,
|
|
18
20
|
),
|
|
19
21
|
);
|
|
@@ -58,7 +60,7 @@ $themes: (
|
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
@mixin btn($size: 24px, $padding: 0) {
|
|
63
|
+
@mixin btn($size: 24px, $padding: 0, $radius: 4px) {
|
|
62
64
|
appearance: none;
|
|
63
65
|
cursor: pointer;
|
|
64
66
|
margin: 0;
|
|
@@ -67,7 +69,7 @@ $themes: (
|
|
|
67
69
|
width: $size;
|
|
68
70
|
height: $size;
|
|
69
71
|
background-color: transparent;
|
|
70
|
-
border-radius:
|
|
72
|
+
border-radius: $radius;
|
|
71
73
|
font-size: 0;
|
|
72
74
|
line-height: 1;
|
|
73
75
|
flex-shrink: 0;
|
|
@@ -85,8 +87,13 @@ $themes: (
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
@each $name, $theme in $themes {
|
|
88
|
-
&.#{$name}:not(:disabled)
|
|
89
|
-
|
|
90
|
+
&.#{$name}:not(:disabled) {
|
|
91
|
+
&:hover {
|
|
92
|
+
background-color: read($theme, "hover-bg-color");
|
|
93
|
+
}
|
|
94
|
+
&.is-active {
|
|
95
|
+
background-color: read($theme, "active-bg-color");
|
|
96
|
+
}
|
|
90
97
|
}
|
|
91
98
|
}
|
|
92
99
|
}
|