@netless/fastboard-react 0.2.13-canary.0 → 0.3.0-canary.2
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/README.md +49 -0
- package/dist/index.d.ts +11 -140
- package/dist/index.js +73 -2130
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -2129
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -23
- package/src/Fastboard.tsx +12 -0
- package/src/PageControl.tsx +11 -0
- package/src/RedoUndo.tsx +8 -0
- package/src/Toolbar.tsx +8 -0
- package/src/ZoomControl.tsx +11 -0
- package/src/hooks.tsx +53 -0
- package/src/index.tsx +19 -0
- package/src/style.scss +3 -26
- package/src/behaviors/style.ts +0 -4
- package/src/components/Fastboard.scss +0 -46
- package/src/components/Fastboard.tsx +0 -108
- package/src/components/PageControl/PageControl.scss +0 -84
- package/src/components/PageControl/PageControl.tsx +0 -101
- package/src/components/PageControl/hooks.ts +0 -24
- package/src/components/PageControl/index.ts +0 -2
- package/src/components/PlayerControl/PlayerControl.scss +0 -146
- package/src/components/PlayerControl/PlayerControl.tsx +0 -131
- package/src/components/PlayerControl/components/Button.tsx +0 -44
- package/src/components/PlayerControl/hooks.ts +0 -88
- package/src/components/PlayerControl/icons/Loading.tsx +0 -13
- package/src/components/PlayerControl/icons/Pause.tsx +0 -13
- package/src/components/PlayerControl/icons/Play.tsx +0 -13
- package/src/components/PlayerControl/icons/index.ts +0 -10
- package/src/components/PlayerControl/index.ts +0 -2
- package/src/components/RedoUndo/RedoUndo.scss +0 -56
- package/src/components/RedoUndo/RedoUndo.tsx +0 -76
- package/src/components/RedoUndo/hooks.ts +0 -18
- package/src/components/RedoUndo/index.ts +0 -2
- package/src/components/ReplayFastboard.tsx +0 -36
- package/src/components/Toolbar/Content.tsx +0 -89
- package/src/components/Toolbar/Toolbar.scss +0 -343
- package/src/components/Toolbar/Toolbar.tsx +0 -84
- package/src/components/Toolbar/components/ApplianceButtons.tsx +0 -108
- package/src/components/Toolbar/components/AppsButton.tsx +0 -134
- package/src/components/Toolbar/components/Button.tsx +0 -45
- package/src/components/Toolbar/components/ColorBox.tsx +0 -55
- package/src/components/Toolbar/components/CutLine.tsx +0 -8
- package/src/components/Toolbar/components/PencilButton.tsx +0 -66
- package/src/components/Toolbar/components/ShapesButton.tsx +0 -135
- package/src/components/Toolbar/components/Slider.tsx +0 -26
- package/src/components/Toolbar/components/TextButton.tsx +0 -62
- package/src/components/Toolbar/components/UpDownButtons.tsx +0 -49
- package/src/components/Toolbar/components/assets/cocos.png +0 -0
- package/src/components/Toolbar/components/assets/collapsed.png +0 -0
- package/src/components/Toolbar/components/assets/countdown.png +0 -0
- package/src/components/Toolbar/components/assets/expanded.png +0 -0
- package/src/components/Toolbar/components/assets/geogebra.png +0 -0
- package/src/components/Toolbar/components/assets/vscode.png +0 -0
- package/src/components/Toolbar/const.ts +0 -32
- package/src/components/Toolbar/hooks.ts +0 -89
- package/src/components/Toolbar/icons/Apps.tsx +0 -16
- package/src/components/Toolbar/icons/Arrow.tsx +0 -13
- package/src/components/Toolbar/icons/Circle.tsx +0 -13
- package/src/components/Toolbar/icons/Clean.tsx +0 -16
- package/src/components/Toolbar/icons/Clicker.tsx +0 -19
- package/src/components/Toolbar/icons/Collapse.tsx +0 -13
- package/src/components/Toolbar/icons/Diamond.tsx +0 -13
- package/src/components/Toolbar/icons/Down.tsx +0 -13
- package/src/components/Toolbar/icons/Eraser.tsx +0 -16
- package/src/components/Toolbar/icons/Expand.tsx +0 -13
- package/src/components/Toolbar/icons/Laser.tsx +0 -21
- package/src/components/Toolbar/icons/Line.tsx +0 -13
- package/src/components/Toolbar/icons/Loading.tsx +0 -13
- package/src/components/Toolbar/icons/Pencil.tsx +0 -16
- package/src/components/Toolbar/icons/Rectangle.tsx +0 -13
- package/src/components/Toolbar/icons/Selector.tsx +0 -13
- package/src/components/Toolbar/icons/SpeechBalloon.tsx +0 -17
- package/src/components/Toolbar/icons/Star.tsx +0 -17
- package/src/components/Toolbar/icons/Text.tsx +0 -13
- package/src/components/Toolbar/icons/Triangle.tsx +0 -13
- package/src/components/Toolbar/icons/Up.tsx +0 -13
- package/src/components/Toolbar/icons/index.ts +0 -42
- package/src/components/Toolbar/index.ts +0 -2
- package/src/components/ZoomControl/ZoomControl.scss +0 -84
- package/src/components/ZoomControl/ZoomControl.tsx +0 -96
- package/src/components/ZoomControl/hooks.ts +0 -50
- package/src/components/ZoomControl/index.ts +0 -2
- package/src/components/hooks.ts +0 -66
- package/src/components/tippy-util.ts +0 -8
- package/src/i18n/en.json +0 -31
- package/src/i18n/index.ts +0 -29
- package/src/i18n/zh-CN.json +0 -32
- package/src/icons/Left.tsx +0 -15
- package/src/icons/Minus.tsx +0 -15
- package/src/icons/Plus.tsx +0 -15
- package/src/icons/Redo.tsx +0 -19
- package/src/icons/Reset.tsx +0 -17
- package/src/icons/Right.tsx +0 -15
- package/src/icons/Undo.tsx +0 -19
- package/src/icons/WhiteboardAdd.tsx +0 -26
- package/src/icons/index.tsx +0 -11
- package/src/index.ts +0 -12
- package/src/internal/helpers.ts +0 -31
- package/src/internal/hooks.ts +0 -23
- package/src/internal/index.ts +0 -2
- package/src/theme.ts +0 -36
- package/src/typings.ts +0 -15
- package/src/vanilla/index.tsx +0 -28
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Eraser = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path
|
|
11
|
-
fill={stroke}
|
|
12
|
-
d="m14.333 5.183.165.007c.494.037.978.245 1.356.623l2.333 2.333a2.15 2.15 0 0 1 0 3.04l-5.833 5.834a3.8 3.8 0 0 1-5.374 0l-1.167-1.166a2.15 2.15 0 0 1 0-3.04l7-7c.42-.42.97-.63 1.52-.63ZM11.52 8.52l-4.999 5a1.15 1.15 0 0 0 0 1.626l1.167 1.167a2.8 2.8 0 0 0 3.96 0l3.832-3.833-3.96-3.96Z"
|
|
13
|
-
/>
|
|
14
|
-
</svg>
|
|
15
|
-
);
|
|
16
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Expand = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path fill="none" stroke={stroke} d="m16 10 2 2-2 2M6 6h12M6 18h12M6 14h8m-8-4h8" />
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Laser = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<g fill="none" fill-rule="evenodd">
|
|
11
|
-
<circle cx="12" cy="12" r="2" fill={stroke} />
|
|
12
|
-
<path
|
|
13
|
-
stroke={stroke}
|
|
14
|
-
stroke-linecap="square"
|
|
15
|
-
stroke-linejoin="round"
|
|
16
|
-
d="M12 4v2m0 12v2m8-8h-2M6 12H4m13.657 5.657-1.414-1.414M7.757 7.757 6.343 6.343m0 11.314 1.414-1.414m8.486-8.486 1.414-1.414"
|
|
17
|
-
/>
|
|
18
|
-
</g>
|
|
19
|
-
</svg>
|
|
20
|
-
);
|
|
21
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Line = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path fill={stroke} d="m18.01 5.282.708.708L5.99 18.718l-.708-.708z" />
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Loading = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path fill={stroke} d="M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8Z"></path>
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Pencil = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path
|
|
11
|
-
fill={stroke}
|
|
12
|
-
d="m17.497 4.84.116.105 1.442 1.442a1.52 1.52 0 0 1 .104 2.034l-.104.116L8.733 18.858l-4.347.756.756-4.347L15.463 4.945a1.52 1.52 0 0 1 2.034-.104ZM5.967 16.349l-.353 2.037 2.037-.354-1.683-1.683Zm8.407-8.901-7.946 7.946 2.178 2.178 7.946-7.946-2.178-2.178Zm-.728 2.2.708.707-5 5-.708-.708 5-5Zm2.596-4.055-.072.06-1.09 1.088 2.179 2.178 1.089-1.088a.52.52 0 0 0 .105-.584l-.045-.08-.06-.072-1.442-1.442a.52.52 0 0 0-.664-.06Z"
|
|
13
|
-
/>
|
|
14
|
-
</svg>
|
|
15
|
-
);
|
|
16
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Rectangle = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path fill="none" stroke={stroke} d="M5.5 5.5h13v13h-13z" />
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Selector = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path fill={stroke} d="m12 12 8 2.667-3.556 1.777L14.667 20 12 12Zm3-8v7.5h-1V5H5v9h6.5v1H4V4h11Z" />
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const SpeechBalloon = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path
|
|
11
|
-
fill="none"
|
|
12
|
-
stroke={stroke}
|
|
13
|
-
d="M17 4.5c.414 0 .79.168 1.06.44.272.27.44.646.44 1.06v9c0 .414-.168.79-.44 1.06a1.49 1.49 0 0 1-1.06.44h-4.207l-2.715 2.715-1.81-2.715H7a1.49 1.49 0 0 1-1.06-.44A1.495 1.495 0 0 1 5.5 15V6c0-.414.168-.79.44-1.06A1.49 1.49 0 0 1 7 4.5Z"
|
|
14
|
-
/>
|
|
15
|
-
</svg>
|
|
16
|
-
);
|
|
17
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Star = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path
|
|
11
|
-
fill="none"
|
|
12
|
-
stroke={stroke}
|
|
13
|
-
d="m12 3.523 1.993 5.734 6.07.123-4.838 3.668 1.758 5.81L12 15.391l-4.983 3.467 1.758-5.81L3.938 9.38l6.069-.123L12 3.523Z"
|
|
14
|
-
/>
|
|
15
|
-
</svg>
|
|
16
|
-
);
|
|
17
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Text = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path fill={stroke} d="M18.5 5.5V8h-1V6.5H13v11h2v1H9v-1h2v-11H6.5V8h-1V5.5h13Z" />
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Triangle = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path fill="none" stroke={stroke} d="M12 6.008 19.138 18.5H4.862L12 6.008Z" />
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconProps } from "../../../typings";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { getStroke } from "../../../theme";
|
|
5
|
-
|
|
6
|
-
export const Up = (props: IconProps) => {
|
|
7
|
-
const stroke = getStroke(props);
|
|
8
|
-
return (
|
|
9
|
-
<svg viewBox="0 0 24 24">
|
|
10
|
-
<path fill="none" stroke={stroke} d="m16 11-2-2-2-2-2 2-2 2m8 6-2-2-2-2-2 2-2 2" />
|
|
11
|
-
</svg>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { memo } from "react";
|
|
2
|
-
import { Apps } from "./Apps";
|
|
3
|
-
import { Arrow } from "./Arrow";
|
|
4
|
-
import { Circle } from "./Circle";
|
|
5
|
-
import { Clean } from "./Clean";
|
|
6
|
-
import { Clicker } from "./Clicker";
|
|
7
|
-
import { Collapse } from "./Collapse";
|
|
8
|
-
import { Diamond } from "./Diamond";
|
|
9
|
-
import { Down } from "./Down";
|
|
10
|
-
import { Eraser } from "./Eraser";
|
|
11
|
-
import { Expand } from "./Expand";
|
|
12
|
-
import { Line } from "./Line";
|
|
13
|
-
import { Pencil } from "./Pencil";
|
|
14
|
-
import { Rectangle } from "./Rectangle";
|
|
15
|
-
import { Selector } from "./Selector";
|
|
16
|
-
import { SpeechBalloon } from "./SpeechBalloon";
|
|
17
|
-
import { Star } from "./Star";
|
|
18
|
-
import { Text } from "./Text";
|
|
19
|
-
import { Triangle } from "./Triangle";
|
|
20
|
-
import { Up } from "./Up";
|
|
21
|
-
|
|
22
|
-
export const Icons = {
|
|
23
|
-
Clicker: memo(Clicker),
|
|
24
|
-
Collapse: memo(Collapse),
|
|
25
|
-
Eraser: memo(Eraser),
|
|
26
|
-
Expand: memo(Expand),
|
|
27
|
-
Pencil: memo(Pencil),
|
|
28
|
-
Selector: memo(Selector),
|
|
29
|
-
Rectangle: memo(Rectangle),
|
|
30
|
-
Text: memo(Text),
|
|
31
|
-
Apps: memo(Apps),
|
|
32
|
-
Clean: memo(Clean),
|
|
33
|
-
Circle: memo(Circle),
|
|
34
|
-
Line: memo(Line),
|
|
35
|
-
Arrow: memo(Arrow),
|
|
36
|
-
Star: memo(Star),
|
|
37
|
-
Diamond: memo(Diamond),
|
|
38
|
-
SpeechBalloon: memo(SpeechBalloon),
|
|
39
|
-
Triangle: memo(Triangle),
|
|
40
|
-
Up: memo(Up),
|
|
41
|
-
Down: memo(Down),
|
|
42
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
$name: "fastboard-zoom-control";
|
|
2
|
-
|
|
3
|
-
.#{$name} {
|
|
4
|
-
position: relative;
|
|
5
|
-
display: inline-flex;
|
|
6
|
-
align-items: center;
|
|
7
|
-
gap: 4px;
|
|
8
|
-
padding: 4px;
|
|
9
|
-
border-radius: 4px;
|
|
10
|
-
backdrop-filter: blur(5px);
|
|
11
|
-
-webkit-backdrop-filter: blur(5px);
|
|
12
|
-
|
|
13
|
-
&.light {
|
|
14
|
-
color: #333;
|
|
15
|
-
background-color: rgba(255, 255, 255, 0.9);
|
|
16
|
-
border: 1px solid #e5e8f0;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
&.dark {
|
|
20
|
-
color: #ddd;
|
|
21
|
-
background-color: #14181e;
|
|
22
|
-
border: 1px solid #383b42;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.#{$name}-btn {
|
|
27
|
-
appearance: none;
|
|
28
|
-
cursor: pointer;
|
|
29
|
-
margin: 0;
|
|
30
|
-
border: 0;
|
|
31
|
-
padding: 0;
|
|
32
|
-
width: 24px;
|
|
33
|
-
height: 24px;
|
|
34
|
-
background-color: transparent;
|
|
35
|
-
border-radius: 4px;
|
|
36
|
-
font-size: 24px;
|
|
37
|
-
line-height: 1;
|
|
38
|
-
|
|
39
|
-
svg,
|
|
40
|
-
img {
|
|
41
|
-
width: 100%;
|
|
42
|
-
height: 100%;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
&:disabled {
|
|
46
|
-
opacity: 0.5;
|
|
47
|
-
cursor: not-allowed;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
&.light:not(:disabled):hover {
|
|
51
|
-
background-color: #ebf2ff;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
&.dark:not(:disabled):hover {
|
|
55
|
-
background-color: #383b42;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.#{$name}-cut-line {
|
|
60
|
-
height: 24px;
|
|
61
|
-
width: 0.5px;
|
|
62
|
-
|
|
63
|
-
&.light {
|
|
64
|
-
background-color: #e7e7e7;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
&.dark {
|
|
68
|
-
background-color: rgba(255, 255, 255, 0.15);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.#{$name}-text {
|
|
73
|
-
line-height: 24px;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.#{$name}-percent {
|
|
77
|
-
opacity: 0.6;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.#{$name}-scale,
|
|
81
|
-
.#{$name}-percent {
|
|
82
|
-
font-size: 14px;
|
|
83
|
-
font-variant-numeric: tabular-nums;
|
|
84
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import type { CommonProps, GenericIcon } from "../../typings";
|
|
2
|
-
|
|
3
|
-
import Tippy from "@tippyjs/react";
|
|
4
|
-
import clsx from "clsx";
|
|
5
|
-
import React from "react";
|
|
6
|
-
|
|
7
|
-
import { useTranslation } from "../../i18n";
|
|
8
|
-
import { Icon } from "../../icons";
|
|
9
|
-
import { Minus } from "../../icons/Minus";
|
|
10
|
-
import { Plus } from "../../icons/Plus";
|
|
11
|
-
import { Reset } from "../../icons/Reset";
|
|
12
|
-
import { TopOffset } from "../../theme";
|
|
13
|
-
import { useTheme, useWritable } from "../hooks";
|
|
14
|
-
import { useZoomControl } from "./hooks";
|
|
15
|
-
|
|
16
|
-
export const name = "fastboard-zoom-control";
|
|
17
|
-
|
|
18
|
-
export type ZoomControlProps = CommonProps & GenericIcon<"reset" | "minus" | "plus">;
|
|
19
|
-
|
|
20
|
-
export function ZoomControl({
|
|
21
|
-
theme,
|
|
22
|
-
resetIcon,
|
|
23
|
-
resetIconDisable,
|
|
24
|
-
minusIcon,
|
|
25
|
-
minusIconDisable,
|
|
26
|
-
plusIcon,
|
|
27
|
-
plusIconDisable,
|
|
28
|
-
}: ZoomControlProps) {
|
|
29
|
-
theme = useTheme(theme);
|
|
30
|
-
const { t } = useTranslation();
|
|
31
|
-
|
|
32
|
-
const writable = useWritable();
|
|
33
|
-
const { scale, resetCamera, zoomIn, zoomOut } = useZoomControl();
|
|
34
|
-
|
|
35
|
-
const disabled = !writable;
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div className={clsx(name, theme)}>
|
|
39
|
-
{/* <span className={clsx(`${name}-cut-line`, theme)} /> */}
|
|
40
|
-
<Tippy
|
|
41
|
-
className="fastboard-tip"
|
|
42
|
-
content={t("zoomOut")}
|
|
43
|
-
theme={theme}
|
|
44
|
-
disabled={disabled}
|
|
45
|
-
placement="top"
|
|
46
|
-
delay={[1000, 400]}
|
|
47
|
-
duration={300}
|
|
48
|
-
offset={TopOffset}
|
|
49
|
-
>
|
|
50
|
-
<button className={clsx(`${name}-btn`, "minus", theme)} disabled={disabled} onClick={zoomOut}>
|
|
51
|
-
<Icon
|
|
52
|
-
fallback={<Minus theme={theme} />}
|
|
53
|
-
src={disabled ? minusIconDisable : minusIcon}
|
|
54
|
-
alt="[minus]"
|
|
55
|
-
/>
|
|
56
|
-
</button>
|
|
57
|
-
</Tippy>
|
|
58
|
-
<span className={clsx(`${name}-text`, theme)}>
|
|
59
|
-
<span className={clsx(`${name}-scale`, theme)}>{Math.ceil(scale * 100)}</span>
|
|
60
|
-
<span className={clsx(`${name}-percent`, theme)}>%</span>
|
|
61
|
-
</span>
|
|
62
|
-
<Tippy
|
|
63
|
-
className="fastboard-tip"
|
|
64
|
-
content={t("zoomIn")}
|
|
65
|
-
theme={theme}
|
|
66
|
-
disabled={disabled}
|
|
67
|
-
placement="top"
|
|
68
|
-
delay={[1000, 400]}
|
|
69
|
-
duration={300}
|
|
70
|
-
offset={TopOffset}
|
|
71
|
-
>
|
|
72
|
-
<button className={clsx(`${name}-btn`, "plus", theme)} disabled={disabled} onClick={zoomIn}>
|
|
73
|
-
<Icon fallback={<Plus theme={theme} />} src={disabled ? plusIconDisable : plusIcon} alt="[plus]" />
|
|
74
|
-
</button>
|
|
75
|
-
</Tippy>
|
|
76
|
-
<Tippy
|
|
77
|
-
className="fastboard-tip"
|
|
78
|
-
content={t("reset")}
|
|
79
|
-
theme={theme}
|
|
80
|
-
disabled={disabled}
|
|
81
|
-
placement="top"
|
|
82
|
-
delay={[1000, 400]}
|
|
83
|
-
duration={300}
|
|
84
|
-
offset={TopOffset}
|
|
85
|
-
>
|
|
86
|
-
<button className={clsx(`${name}-btn`, "reset", theme)} disabled={disabled} onClick={resetCamera}>
|
|
87
|
-
<Icon
|
|
88
|
-
fallback={<Reset theme={theme} />}
|
|
89
|
-
src={disabled ? resetIconDisable : resetIcon}
|
|
90
|
-
alt="[reset]"
|
|
91
|
-
/>
|
|
92
|
-
</button>
|
|
93
|
-
</Tippy>
|
|
94
|
-
</div>
|
|
95
|
-
);
|
|
96
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
2
|
-
|
|
3
|
-
import { clamp } from "../../internal";
|
|
4
|
-
import { useFastboardApp, useFastboardValue } from "../hooks";
|
|
5
|
-
|
|
6
|
-
export const ScalePoints: readonly number[] = [
|
|
7
|
-
0.3, 0.4096000000000002, 0.5120000000000001, 0.6400000000000001, 0.8, 1, 1.26, 1.5876000000000001, 2.000376,
|
|
8
|
-
2.5204737600000002, 3,
|
|
9
|
-
];
|
|
10
|
-
|
|
11
|
-
function nextScale(scale: number, delta: 1 | -1) {
|
|
12
|
-
const { length } = ScalePoints;
|
|
13
|
-
const last = length - 1;
|
|
14
|
-
if (scale < ScalePoints[0]) return ScalePoints[0];
|
|
15
|
-
if (scale > ScalePoints[last]) return ScalePoints[last];
|
|
16
|
-
for (let i = 0; i < length; ++i) {
|
|
17
|
-
const curr = ScalePoints[i];
|
|
18
|
-
const prev = i === 0 ? -Infinity : (ScalePoints[i - 1] + curr) / 2;
|
|
19
|
-
const next = i === last ? Infinity : (ScalePoints[i + 1] + curr) / 2;
|
|
20
|
-
if (prev <= scale && scale <= next) return ScalePoints[clamp(i + delta, 0, last)];
|
|
21
|
-
}
|
|
22
|
-
return 1;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function useZoomControl() {
|
|
26
|
-
const app = useFastboardApp();
|
|
27
|
-
const scale = useFastboardValue(app.camera).scale || 1;
|
|
28
|
-
|
|
29
|
-
const resetCamera = useCallback(() => {
|
|
30
|
-
app.moveCamera({ scale: 1, centerX: 0, centerY: 0 });
|
|
31
|
-
}, [app]);
|
|
32
|
-
|
|
33
|
-
const zoomIn = useCallback(() => {
|
|
34
|
-
app.moveCamera({
|
|
35
|
-
scale: nextScale(scale, 1),
|
|
36
|
-
centerX: 0,
|
|
37
|
-
centerY: 0,
|
|
38
|
-
});
|
|
39
|
-
}, [app, scale]);
|
|
40
|
-
|
|
41
|
-
const zoomOut = useCallback(() => {
|
|
42
|
-
app.moveCamera({
|
|
43
|
-
scale: nextScale(scale, -1),
|
|
44
|
-
centerX: 0,
|
|
45
|
-
centerY: 0,
|
|
46
|
-
});
|
|
47
|
-
}, [app, scale]);
|
|
48
|
-
|
|
49
|
-
return { scale, resetCamera, zoomIn, zoomOut };
|
|
50
|
-
}
|
package/src/components/hooks.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import type { FastboardApp, FastboardReadable } from "@netless/fastboard-core";
|
|
2
|
-
import type { Theme } from "../typings";
|
|
3
|
-
|
|
4
|
-
import { BuiltinApps } from "@netless/window-manager";
|
|
5
|
-
import { createContext, useContext, useEffect, useState } from "react";
|
|
6
|
-
|
|
7
|
-
export const FastboardAppContext = /* @__PURE__ */ createContext<FastboardApp | null>(null);
|
|
8
|
-
|
|
9
|
-
export const ThemeContext = /* @__PURE__ */ createContext<Theme>("light");
|
|
10
|
-
|
|
11
|
-
export function useTheme(userTheme?: Theme | null) {
|
|
12
|
-
const themeFromContext = useContext(ThemeContext);
|
|
13
|
-
return userTheme || themeFromContext;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function useFastboardApp() {
|
|
17
|
-
const app = useContext(FastboardAppContext);
|
|
18
|
-
if (!app) {
|
|
19
|
-
throw new Error("useFastboardApp() can only be called inside of <Fastboard>");
|
|
20
|
-
}
|
|
21
|
-
return app;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function useFastboardValue<T>(val: FastboardReadable<T>) {
|
|
25
|
-
const [value, setValue] = useState(val.value);
|
|
26
|
-
useEffect(() => val.subscribe(setValue), [val]);
|
|
27
|
-
return value;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function useWritable() {
|
|
31
|
-
return useFastboardValue(useFastboardApp().writable);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function useBoxState() {
|
|
35
|
-
return useFastboardValue(useFastboardApp().boxState);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function useFocusedApp() {
|
|
39
|
-
return useFastboardValue(useFastboardApp().focusedApp);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function useMaximized() {
|
|
43
|
-
return useBoxState() === "maximized";
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const AppsShouldShowToolbar = /* @__PURE__ */ (() => [BuiltinApps.DocsViewer, "Slide"])();
|
|
47
|
-
|
|
48
|
-
export function useHideControls() {
|
|
49
|
-
const writable = useWritable();
|
|
50
|
-
const maximized = useMaximized();
|
|
51
|
-
const focusedApp = useFocusedApp();
|
|
52
|
-
|
|
53
|
-
if (!writable) {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (maximized) {
|
|
58
|
-
if (AppsShouldShowToolbar.some(kind => focusedApp?.includes(kind))) {
|
|
59
|
-
return "toolbar-only";
|
|
60
|
-
} else {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return false;
|
|
66
|
-
}
|
package/src/i18n/en.json
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"translation": {
|
|
3
|
-
"clicker": "clicker",
|
|
4
|
-
"selector": "selector",
|
|
5
|
-
"text": "text",
|
|
6
|
-
"pencil": "pencil",
|
|
7
|
-
"arrow": "arrow",
|
|
8
|
-
"hand": "hand",
|
|
9
|
-
"eraser": "eraser",
|
|
10
|
-
"laser": "laser",
|
|
11
|
-
"collapse": "Collapse",
|
|
12
|
-
"expand": "Expand",
|
|
13
|
-
"zoomIn": "Zoom In",
|
|
14
|
-
"zoomOut": "Zoom Out",
|
|
15
|
-
"reset": "Reset",
|
|
16
|
-
"prevPage": "Prev Page",
|
|
17
|
-
"nextPage": "Next Page",
|
|
18
|
-
"addPage": "Add Page",
|
|
19
|
-
"redo": "Redo",
|
|
20
|
-
"undo": "Undo",
|
|
21
|
-
"shape": "Shape",
|
|
22
|
-
"triangle": "Triangle",
|
|
23
|
-
"rhombus": "Rhombus",
|
|
24
|
-
"pentagram": "Pentagram",
|
|
25
|
-
"speechBalloon": "Speech Balloon",
|
|
26
|
-
"rectangle": "Rectangle",
|
|
27
|
-
"ellipse": "Ellipse",
|
|
28
|
-
"straight": "Straight",
|
|
29
|
-
"speed": "Speed"
|
|
30
|
-
}
|
|
31
|
-
}
|
package/src/i18n/index.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { i18n } from "i18next";
|
|
2
|
-
import type { Language } from "../typings";
|
|
3
|
-
|
|
4
|
-
import { createContext, useContext, useMemo } from "react";
|
|
5
|
-
import i18next from "i18next";
|
|
6
|
-
import en from "./en.json";
|
|
7
|
-
import zhCN from "./zh-CN.json";
|
|
8
|
-
|
|
9
|
-
export interface CreateI18nParams {
|
|
10
|
-
language?: Language;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const createI18n = async ({
|
|
14
|
-
language = (navigator.language as Language) || "zh-CN",
|
|
15
|
-
}: CreateI18nParams = {}) => {
|
|
16
|
-
await i18next.init({
|
|
17
|
-
lng: language,
|
|
18
|
-
resources: { en, "zh-CN": zhCN },
|
|
19
|
-
});
|
|
20
|
-
return i18next;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const I18nContext = /* @__PURE__ */ createContext<i18n | null>(null);
|
|
24
|
-
|
|
25
|
-
export function useTranslation() {
|
|
26
|
-
const i18n = useContext(I18nContext);
|
|
27
|
-
const t = useMemo(() => (i18n ? i18n.getFixedT(null, ["translation"]) : (id: string) => id), [i18n]);
|
|
28
|
-
return { t, i18n };
|
|
29
|
-
}
|
package/src/i18n/zh-CN.json
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"translation": {
|
|
3
|
-
"clicker": "点击",
|
|
4
|
-
"selector": "选择",
|
|
5
|
-
"text": "文字",
|
|
6
|
-
"pencil": "铅笔",
|
|
7
|
-
"arrow": "箭头",
|
|
8
|
-
"hand": "抓手",
|
|
9
|
-
"eraser": "橡皮",
|
|
10
|
-
"laser": "激光笔",
|
|
11
|
-
"zoomIn": "放大",
|
|
12
|
-
"zoomOut": "缩小",
|
|
13
|
-
"reset": "重置",
|
|
14
|
-
"prevPage": "上一页",
|
|
15
|
-
"nextPage": "下一页",
|
|
16
|
-
"addPage": "添加页面",
|
|
17
|
-
"redo": "重做",
|
|
18
|
-
"undo": "撤销",
|
|
19
|
-
"collapse": "收起",
|
|
20
|
-
"expand": "展开",
|
|
21
|
-
"clean": "清屏",
|
|
22
|
-
"shape": "形状",
|
|
23
|
-
"triangle": "三角形",
|
|
24
|
-
"rhombus": "菱形",
|
|
25
|
-
"pentagram": "五角星",
|
|
26
|
-
"speechBalloon": "气球",
|
|
27
|
-
"rectangle": "矩形",
|
|
28
|
-
"ellipse": "椭圆",
|
|
29
|
-
"straight": "直线",
|
|
30
|
-
"speed": "速度"
|
|
31
|
-
}
|
|
32
|
-
}
|