reacthub-pixitweenjs 0.2.5 → 0.2.6
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/.storybook/preview.tsx +6 -0
- package/CHANGELOG.md +13 -0
- package/README.md +1 -1
- package/package.json +4 -1
- package/src/components/PixiAudioSprite/PixiAudioSprite.tsx +5 -15
- package/src/components/PixiGifSprite/PixiGifSprite.tsx +10 -89
- package/src/components/PixiImageSprite/PixiImageSprite.tsx +3 -34
- package/src/components/PixiSVGSprite/PixiSvgPathSprite.stories.tsx +2 -2
- package/src/components/PixiSVGSprite/PixiSvgPathSprite.tsx +3 -35
- package/src/components/PixiTextSprite/PixiTextSprite.stories.tsx +176 -0
- package/src/components/PixiTextSprite/PixiTextSprite.tsx +540 -0
- package/src/components/PixiTextSprite/index.ts +1 -0
- package/src/components/PixiVideoSprite/PixiVideoSprite.tsx +9 -62
- package/src/main.tsx +8 -7
- package/src/providers/GsapPixieContextProvider.tsx +14 -20
- package/src/stories/Installation.mdx +3 -3
- package/src/utils/AppStateProvider.tsx +3 -3
- package/src/utils/AppStateStage.tsx +1 -13
- package/src/utils/AppWrapper.tsx +4 -0
- package/src/utils/GsapAnim.tsx +1 -7
- package/src/utils/InteractionManager.tsx +36 -0
- package/src/utils/PixiTransformer.tsx +68 -3
- package/src/utils/VideoSeekBar.tsx +4 -11
- package/src/hooks/usePixiTransformer.tsx +0 -168
package/src/main.tsx
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import ReactDOM from
|
|
3
|
-
import App from
|
|
4
|
-
import
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as ReactDOM from "react-dom/client";
|
|
3
|
+
import App from "./App";
|
|
4
|
+
import "./index.css";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
7
8
|
<React.StrictMode>
|
|
8
9
|
<App />
|
|
9
|
-
</React.StrictMode
|
|
10
|
-
)
|
|
10
|
+
</React.StrictMode>
|
|
11
|
+
);
|
|
@@ -48,7 +48,6 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
48
48
|
children,
|
|
49
49
|
}) => {
|
|
50
50
|
const [play, setPlay] = useState<boolean>(false);
|
|
51
|
-
const [frameNumber, setFrameNumber] = useState<number>(0);
|
|
52
51
|
const [isDragging, setIsDragging] = useState<boolean>(false);
|
|
53
52
|
const [internalDuration, setInternalDuration] = useState<number>(0);
|
|
54
53
|
const [totalDuration, setTotalDuration] = useState<number>(0);
|
|
@@ -58,9 +57,9 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
58
57
|
const gsapCtx = useRef<any>();
|
|
59
58
|
const playerTimeRef = useRef<number>(0.001);
|
|
60
59
|
|
|
61
|
-
const parentElementRef = useRef<any>();
|
|
60
|
+
// const parentElementRef = useRef<any>();
|
|
62
61
|
// передаем предка анимируемых элементов
|
|
63
|
-
const q = gsap.utils.selector(parentElementRef);
|
|
62
|
+
// const q = gsap.utils.selector(parentElementRef);
|
|
64
63
|
|
|
65
64
|
useLayoutEffect(() => {
|
|
66
65
|
gsapCtx.current = gsap.context(() => {
|
|
@@ -75,7 +74,7 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
75
74
|
return () => gsapCtx.current.revert();
|
|
76
75
|
}, []);
|
|
77
76
|
|
|
78
|
-
gsap.ticker.add((
|
|
77
|
+
gsap.ticker.add(() => {
|
|
79
78
|
// console.log("timeframe", time, deltaTime, frame);
|
|
80
79
|
// setFrameNumber(frame);
|
|
81
80
|
if (tl.current && getTimelineDuration) {
|
|
@@ -86,11 +85,11 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
86
85
|
const onUpdate = useCallback(() => {
|
|
87
86
|
/// console.log("update event callback");
|
|
88
87
|
const timeline = tl.current;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (playerTimeRef.current) {
|
|
92
|
-
|
|
93
|
-
}
|
|
88
|
+
let now = timeline.time();
|
|
89
|
+
// let elapsedTime;
|
|
90
|
+
// if (playerTimeRef.current) {
|
|
91
|
+
// elapsedTime = now - playerTimeRef.current;
|
|
92
|
+
// }
|
|
94
93
|
// console.log(`elapseTime :${elapsedTime} and frame: ${frameNumber}`);
|
|
95
94
|
//time = now;
|
|
96
95
|
playerTimeRef.current = now;
|
|
@@ -154,11 +153,6 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
154
153
|
}
|
|
155
154
|
}, [play]);
|
|
156
155
|
|
|
157
|
-
const addTotalDuration = (duration: number) => {
|
|
158
|
-
const timeline = tl.current;
|
|
159
|
-
timeline.totalDuration(duration);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
156
|
const handleReset = useCallback(() => {
|
|
163
157
|
const timeline = tl.current;
|
|
164
158
|
|
|
@@ -188,10 +182,10 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
188
182
|
timeline.seek(4);
|
|
189
183
|
}, []);
|
|
190
184
|
|
|
191
|
-
const setTimelineDuration = useCallback(() => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}, []);
|
|
185
|
+
// const setTimelineDuration = useCallback(() => {
|
|
186
|
+
// const timeline = tl.current;
|
|
187
|
+
// timeline.totalDuration(3);
|
|
188
|
+
// }, []);
|
|
195
189
|
|
|
196
190
|
const getTimelineDuration = useCallback(() => {
|
|
197
191
|
const timeline = tl.current;
|
|
@@ -214,12 +208,12 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
214
208
|
};
|
|
215
209
|
|
|
216
210
|
/** Event listener dragging */
|
|
217
|
-
useCustomEventListener(Events.DRAGGING_START, (
|
|
211
|
+
useCustomEventListener(Events.DRAGGING_START, () => {
|
|
218
212
|
console.log("dragging start");
|
|
219
213
|
setIsDragging(true);
|
|
220
214
|
});
|
|
221
215
|
|
|
222
|
-
useCustomEventListener(Events.DRAGGING_END, (
|
|
216
|
+
useCustomEventListener(Events.DRAGGING_END, () => {
|
|
223
217
|
setIsDragging(false);
|
|
224
218
|
console.log("dragging end");
|
|
225
219
|
});
|
|
@@ -27,7 +27,7 @@ export const AppStateContextProvider: React.FC<
|
|
|
27
27
|
const onAnchorTransformationEnd = React.useCallback(
|
|
28
28
|
(data: TransformationEnd) => {
|
|
29
29
|
console.log("onAnchorTransformationEnd", data);
|
|
30
|
-
const {
|
|
30
|
+
const { transformation } = data;
|
|
31
31
|
const newAppState = {
|
|
32
32
|
...appStateRef.current,
|
|
33
33
|
transformation: {
|
|
@@ -41,9 +41,9 @@ export const AppStateContextProvider: React.FC<
|
|
|
41
41
|
[]
|
|
42
42
|
);
|
|
43
43
|
|
|
44
|
-
const onMouseOverSprite = React.useCallback((
|
|
44
|
+
const onMouseOverSprite = React.useCallback(() => {}, []);
|
|
45
45
|
|
|
46
|
-
const onClickSprite = React.useCallback((
|
|
46
|
+
const onClickSprite = React.useCallback(() => {}, []);
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
49
|
<>
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import ContextBridge from "./ContextBridge";
|
|
3
|
-
import { AppStateContext } from "./AppStateProvider";
|
|
4
2
|
import { Container as PixiContainer } from "@pixi/react";
|
|
5
3
|
|
|
6
4
|
interface AppStateStageProps {
|
|
@@ -11,17 +9,7 @@ const AppStateStage: React.FC<AppStateStageProps> = ({
|
|
|
11
9
|
children,
|
|
12
10
|
...props
|
|
13
11
|
}) => {
|
|
14
|
-
return
|
|
15
|
-
<ContextBridge
|
|
16
|
-
Context={AppStateContext}
|
|
17
|
-
render={(children: React.ReactNode) => (
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
<PixiContainer {...props}>{children}</PixiContainer>
|
|
20
|
-
)}
|
|
21
|
-
>
|
|
22
|
-
{children}
|
|
23
|
-
</ContextBridge>
|
|
24
|
-
);
|
|
12
|
+
return <PixiContainer {...props}>{children}</PixiContainer>;
|
|
25
13
|
};
|
|
26
14
|
|
|
27
15
|
export default AppStateStage;
|
package/src/utils/AppWrapper.tsx
CHANGED
|
@@ -18,9 +18,13 @@ export const AppWrapper: React.FC<AppProps> = ({
|
|
|
18
18
|
const backgroundColorx = PIXI.utils.string2hex(backgroundColor || "#2D2E3C");
|
|
19
19
|
const width = 600;
|
|
20
20
|
const height = 500;
|
|
21
|
+
const quillEditorRef = React.useRef<HTMLDivElement>(null);
|
|
22
|
+
|
|
21
23
|
/// color: 0x1099bb,
|
|
22
24
|
return (
|
|
23
25
|
<div className="App">
|
|
26
|
+
<div id="note-editor" ref={quillEditorRef}></div>
|
|
27
|
+
<div id="lottieroot"></div>
|
|
24
28
|
<GsapPixieContextProvider>
|
|
25
29
|
<ChakraProvider>
|
|
26
30
|
<Flex flexDir={"column"}>
|
package/src/utils/GsapAnim.tsx
CHANGED
|
@@ -26,13 +26,7 @@ interface Ease {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export const getAnimByName = (
|
|
30
|
-
animate: string,
|
|
31
|
-
stageWidth?: number,
|
|
32
|
-
stageHeight?: number,
|
|
33
|
-
x?: number,
|
|
34
|
-
y?: number,
|
|
35
|
-
): Ease => {
|
|
29
|
+
export const getAnimByName = (animate: string): Ease => {
|
|
36
30
|
let ease: Ease = {};
|
|
37
31
|
switch (animate) {
|
|
38
32
|
case "NONE":
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useApp } from "@pixi/react";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
|
|
4
|
+
type PixiInteractionManagerProps = {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
options?: {
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const interactionManagerSettings = { moveWhenInside: true };
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Initialize Pixi Interaction Manager
|
|
15
|
+
* @param param0
|
|
16
|
+
* @returns
|
|
17
|
+
* @see https://pixijs.download/dev/docs/PIXI.InteractionManager.html
|
|
18
|
+
* @see https://pixijs.download/dev/docs/PIXI.InteractionManager.html#moveWhenInside
|
|
19
|
+
* @see https://pixijs.download/dev/docs/PIXI.InteractionManager.html#on
|
|
20
|
+
*
|
|
21
|
+
* */
|
|
22
|
+
const InteractionManager = ({
|
|
23
|
+
children,
|
|
24
|
+
options = interactionManagerSettings,
|
|
25
|
+
}: PixiInteractionManagerProps) => {
|
|
26
|
+
const app = useApp();
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
Object.keys(options).forEach((key) => {
|
|
30
|
+
app.renderer.plugins.interaction[key] = options[key];
|
|
31
|
+
});
|
|
32
|
+
}, [options]);
|
|
33
|
+
|
|
34
|
+
return children;
|
|
35
|
+
};
|
|
36
|
+
export default InteractionManager;
|
|
@@ -10,8 +10,19 @@ type PixiTransformerProps = {
|
|
|
10
10
|
transformCommit?: (data: any) => void;
|
|
11
11
|
transformChange?: (data: any) => void;
|
|
12
12
|
mouseoverEvent?: (flag: boolean) => void;
|
|
13
|
+
onDoubleClick?: (data: any) => void;
|
|
13
14
|
uniqueId?: string;
|
|
14
15
|
};
|
|
16
|
+
|
|
17
|
+
type PixiTransformerState = {
|
|
18
|
+
isDragging: boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Initialize PixiTransformer to transform the image
|
|
23
|
+
* @param param0
|
|
24
|
+
* @returns
|
|
25
|
+
*/
|
|
15
26
|
const PixiTransformer = ({
|
|
16
27
|
pixiTransformerRef,
|
|
17
28
|
imageRef,
|
|
@@ -19,23 +30,58 @@ const PixiTransformer = ({
|
|
|
19
30
|
transformCommit,
|
|
20
31
|
transformChange,
|
|
21
32
|
mouseoverEvent,
|
|
33
|
+
onDoubleClick,
|
|
22
34
|
uniqueId = "",
|
|
23
35
|
}: PixiTransformerProps) => {
|
|
36
|
+
// states
|
|
24
37
|
const colorYellow = PIXI.utils.string2hex("#F3C409");
|
|
25
38
|
const anchorFill = PIXI.utils.string2hex("#F3C409");
|
|
39
|
+
const transformerState = React.useRef<PixiTransformerState>({
|
|
40
|
+
isDragging: false,
|
|
41
|
+
});
|
|
26
42
|
|
|
27
43
|
const handleOnMouseOver = React.useCallback(() => {
|
|
28
|
-
if (mouseoverEvent) {
|
|
44
|
+
if (mouseoverEvent && !transformerState.current.isDragging) {
|
|
29
45
|
mouseoverEvent(true);
|
|
30
46
|
}
|
|
31
47
|
}, [mouseoverEvent]);
|
|
32
48
|
|
|
33
49
|
const handleOnMouseOut = React.useCallback(() => {
|
|
34
|
-
if (mouseoverEvent) {
|
|
50
|
+
if (mouseoverEvent && !transformerState.current.isDragging) {
|
|
35
51
|
mouseoverEvent(false);
|
|
36
52
|
}
|
|
37
53
|
}, [mouseoverEvent]);
|
|
38
54
|
|
|
55
|
+
const handleOnMouseDown = React.useCallback(() => {
|
|
56
|
+
// update transfomer state to is draggin.
|
|
57
|
+
transformerState.current.isDragging = true;
|
|
58
|
+
}, []);
|
|
59
|
+
|
|
60
|
+
const handleOnMouseUp = React.useCallback(() => {
|
|
61
|
+
// update transfomer state to is not dragging.
|
|
62
|
+
transformerState.current.isDragging = false;
|
|
63
|
+
}, []);
|
|
64
|
+
|
|
65
|
+
const handleOnMouseUpOutside = React.useCallback(() => {
|
|
66
|
+
// update transfomer state to is not dragging.
|
|
67
|
+
transformerState.current.isDragging = false;
|
|
68
|
+
}, []);
|
|
69
|
+
|
|
70
|
+
const handleOnDoubleClick = React.useCallback(() => {
|
|
71
|
+
console.log("dobule click in pixi transformer");
|
|
72
|
+
if (onDoubleClick) onDoubleClick({ uniqueId });
|
|
73
|
+
}, [onDoubleClick]);
|
|
74
|
+
|
|
75
|
+
// add handler for transform change
|
|
76
|
+
const handleOnTransformChange = React.useCallback(
|
|
77
|
+
(e: any) => {
|
|
78
|
+
// update transfomer state to is draggin.
|
|
79
|
+
transformerState.current.isDragging = true;
|
|
80
|
+
if (transformChange) transformChange(e);
|
|
81
|
+
},
|
|
82
|
+
[transformChange]
|
|
83
|
+
);
|
|
84
|
+
|
|
39
85
|
const handleOnTransformCommit = React.useCallback(() => {
|
|
40
86
|
if (imageRef.current === null) return;
|
|
41
87
|
const x = imageRef.current.x;
|
|
@@ -60,17 +106,35 @@ const PixiTransformer = ({
|
|
|
60
106
|
},
|
|
61
107
|
});
|
|
62
108
|
}
|
|
109
|
+
// update transformer state to is not dragging.
|
|
110
|
+
transformerState.current.isDragging = false;
|
|
63
111
|
}, [transformCommit]);
|
|
64
112
|
|
|
65
113
|
React.useEffect(() => {
|
|
66
114
|
if (pixiTransformerRef.current) {
|
|
67
115
|
pixiTransformerRef.current.on("mouseover", handleOnMouseOver);
|
|
68
116
|
pixiTransformerRef.current.on("mouseout", handleOnMouseOut);
|
|
117
|
+
pixiTransformerRef.current.on("mousedown", handleOnMouseDown);
|
|
118
|
+
pixiTransformerRef.current.on("mouseup", handleOnMouseUp);
|
|
119
|
+
pixiTransformerRef.current.on("mouseupoutside", handleOnMouseUpOutside);
|
|
120
|
+
/// pixiTransformerRef.current.on("dblclick", handleOnDoubleClick);
|
|
121
|
+
pixiTransformerRef.current.addListener("dblclick", handleOnDoubleClick);
|
|
69
122
|
}
|
|
70
123
|
return () => {
|
|
71
124
|
if (pixiTransformerRef.current) {
|
|
72
125
|
pixiTransformerRef.current.off("mouseover", handleOnMouseOver);
|
|
73
126
|
pixiTransformerRef.current.off("mouseout", handleOnMouseOut);
|
|
127
|
+
pixiTransformerRef.current.off("mousedown", handleOnMouseDown);
|
|
128
|
+
pixiTransformerRef.current.off("mouseup", handleOnMouseUp);
|
|
129
|
+
pixiTransformerRef.current.off(
|
|
130
|
+
"mouseupoutside",
|
|
131
|
+
handleOnMouseUpOutside
|
|
132
|
+
);
|
|
133
|
+
//// pixiTransformerRef.current.off("dblclick", handleOnDoubleClick);
|
|
134
|
+
pixiTransformerRef.current.removeListener(
|
|
135
|
+
"dblclick",
|
|
136
|
+
handleOnDoubleClick
|
|
137
|
+
);
|
|
74
138
|
}
|
|
75
139
|
};
|
|
76
140
|
}, []);
|
|
@@ -81,6 +145,7 @@ const PixiTransformer = ({
|
|
|
81
145
|
group={isMounted ? [imageRef.current] : []}
|
|
82
146
|
rotateEnabled={true}
|
|
83
147
|
boxRotationEnabled={true}
|
|
148
|
+
centeredScaling={true}
|
|
84
149
|
boxScalingEnabled={true}
|
|
85
150
|
wireframeStyle={{ thickness: 1, color: anchorFill }}
|
|
86
151
|
lockAspectRatio={true}
|
|
@@ -91,7 +156,7 @@ const PixiTransformer = ({
|
|
|
91
156
|
shape: "circle",
|
|
92
157
|
radius: 9,
|
|
93
158
|
}}
|
|
94
|
-
transformchange={
|
|
159
|
+
transformchange={handleOnTransformChange}
|
|
95
160
|
transformcommit={handleOnTransformCommit}
|
|
96
161
|
/>
|
|
97
162
|
);
|
|
@@ -4,9 +4,7 @@ import {
|
|
|
4
4
|
SliderTrack,
|
|
5
5
|
SliderFilledTrack,
|
|
6
6
|
SliderThumb,
|
|
7
|
-
SliderMark,
|
|
8
7
|
Flex,
|
|
9
|
-
Icon,
|
|
10
8
|
Text,
|
|
11
9
|
Box,
|
|
12
10
|
Button,
|
|
@@ -15,7 +13,7 @@ import {
|
|
|
15
13
|
GsapPixieContext,
|
|
16
14
|
Events,
|
|
17
15
|
} from "../providers/GsapPixieContextProvider";
|
|
18
|
-
import {
|
|
16
|
+
import { emitCustomEvent } from "react-custom-events";
|
|
19
17
|
|
|
20
18
|
import { gsap } from "gsap";
|
|
21
19
|
import { Draggable } from "gsap/Draggable";
|
|
@@ -24,19 +22,14 @@ gsap.registerPlugin(Draggable);
|
|
|
24
22
|
|
|
25
23
|
export const VideoSeekBar: React.FC = () => {
|
|
26
24
|
const rafRef = React.useRef<number>();
|
|
27
|
-
const sliderRef = React.useRef<HTMLDivElement>(null);
|
|
28
25
|
const sliderThumbRef = React.useRef<HTMLDivElement>(null);
|
|
29
|
-
const sliderProgressRef = React.useRef<HTMLDivElement>(null);
|
|
30
26
|
const {
|
|
31
27
|
tl: timeline,
|
|
32
28
|
playerTimeRef,
|
|
33
29
|
handlePlay,
|
|
34
30
|
handlePause,
|
|
35
|
-
handleReset,
|
|
36
|
-
handleSeek,
|
|
37
31
|
handleSeekTest,
|
|
38
32
|
handleRestart,
|
|
39
|
-
handleRepeat,
|
|
40
33
|
totalDuration: duration,
|
|
41
34
|
} = React.useContext(GsapPixieContext);
|
|
42
35
|
|
|
@@ -44,7 +37,7 @@ export const VideoSeekBar: React.FC = () => {
|
|
|
44
37
|
const [time, setTime] = React.useState<number>(0);
|
|
45
38
|
const totalVideoSeconds = 20;
|
|
46
39
|
|
|
47
|
-
const animate = (
|
|
40
|
+
const animate = () => {
|
|
48
41
|
/// console.log("totalDuration", timeline.current.totalDuration());
|
|
49
42
|
if (playerTimeRef && playerTimeRef.current) {
|
|
50
43
|
setTime(playerTimeRef.current);
|
|
@@ -78,13 +71,13 @@ export const VideoSeekBar: React.FC = () => {
|
|
|
78
71
|
* 1. pause the timeline
|
|
79
72
|
* 2. trigger custom event isDraggingStart
|
|
80
73
|
*/
|
|
81
|
-
const handleOnSliderChangeStart = (
|
|
74
|
+
const handleOnSliderChangeStart = () => {
|
|
82
75
|
// trigger custom event and pause the timeline
|
|
83
76
|
emitCustomEvent(Events.DRAGGING_START);
|
|
84
77
|
timeline && timeline.current.pause();
|
|
85
78
|
};
|
|
86
79
|
|
|
87
|
-
const handleOnSliderChangeEnd = (
|
|
80
|
+
const handleOnSliderChangeEnd = () => {
|
|
88
81
|
// trigger custom event and pause the timeline
|
|
89
82
|
emitCustomEvent(Events.DRAGGING_END);
|
|
90
83
|
timeline && timeline.current.pause();
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { Transformer } from "@pixi-essentials/transformer";
|
|
2
|
-
import * as PIXI from "pixi.js";
|
|
3
|
-
import { useApp } from "@pixi/react";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
import { useEffect, useRef, useCallback } from "react";
|
|
6
|
-
import { Transformation } from "../types/transformation";
|
|
7
|
-
// @ts-ignore
|
|
8
|
-
import has from "lodash/has";
|
|
9
|
-
|
|
10
|
-
const colorYellow = PIXI.utils.string2hex("#F3C409");
|
|
11
|
-
const anchorFill = PIXI.utils.string2hex("#F3C409");
|
|
12
|
-
|
|
13
|
-
interface Events {
|
|
14
|
-
dblclick?: (e: any) => void;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface Props {
|
|
18
|
-
uniqueId?: string;
|
|
19
|
-
onTransformEnd?: (data: {
|
|
20
|
-
uniqueId: string;
|
|
21
|
-
transformation: Transformation;
|
|
22
|
-
}) => void;
|
|
23
|
-
events?: Events;
|
|
24
|
-
mouseoverEvent?: (flag: boolean) => void;
|
|
25
|
-
setDragging?: (flag: boolean) => void;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const usePixiTransformer = ({
|
|
29
|
-
uniqueId = "",
|
|
30
|
-
onTransformEnd,
|
|
31
|
-
events = {},
|
|
32
|
-
mouseoverEvent = (f) => f,
|
|
33
|
-
setDragging = (f) => f,
|
|
34
|
-
}: Props) => {
|
|
35
|
-
const [isDragging, setIsDragging] = React.useState(false);
|
|
36
|
-
const PixiTransformer = React.useRef<PIXI.Container>(null);
|
|
37
|
-
const mounted = React.useRef(false);
|
|
38
|
-
const app = useApp();
|
|
39
|
-
const transformerRef = useRef<Transformer>(null);
|
|
40
|
-
const parentRef = useRef<PIXI.Container>(null);
|
|
41
|
-
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
mounted.current = true;
|
|
44
|
-
return () => {
|
|
45
|
-
mounted.current = false;
|
|
46
|
-
if (transformerRef.current) {
|
|
47
|
-
parentRef.current?.removeChild(transformerRef.current);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
}, []);
|
|
51
|
-
|
|
52
|
-
const transformChange = useCallback(() => {
|
|
53
|
-
setIsDragging(true);
|
|
54
|
-
setDragging(true);
|
|
55
|
-
}, []);
|
|
56
|
-
|
|
57
|
-
const transformCommit = useCallback(() => {
|
|
58
|
-
if (PixiTransformer.current === null) return;
|
|
59
|
-
const x = PixiTransformer.current.x;
|
|
60
|
-
const y = PixiTransformer.current.y;
|
|
61
|
-
const width = PixiTransformer.current.width;
|
|
62
|
-
const height = PixiTransformer.current.height;
|
|
63
|
-
const rotate = PixiTransformer.current.rotation;
|
|
64
|
-
const scale: [number, number] = [
|
|
65
|
-
PixiTransformer.current.scale.x,
|
|
66
|
-
PixiTransformer.current.scale.y,
|
|
67
|
-
];
|
|
68
|
-
if (onTransformEnd) {
|
|
69
|
-
onTransformEnd({
|
|
70
|
-
uniqueId,
|
|
71
|
-
transformation: {
|
|
72
|
-
x: Math.round(x),
|
|
73
|
-
y: Math.round(y),
|
|
74
|
-
width: Math.round(Math.max(5, width)),
|
|
75
|
-
height: Math.round(Math.max(5, height)),
|
|
76
|
-
rotate: Math.round(rotate),
|
|
77
|
-
scale: scale,
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
setIsDragging(false);
|
|
82
|
-
setDragging(false);
|
|
83
|
-
}, []);
|
|
84
|
-
|
|
85
|
-
const handleOnDblClick = useCallback((e: any) => {
|
|
86
|
-
if (events && has(events, "dblclick") && events.dblclick) {
|
|
87
|
-
events.dblclick(e);
|
|
88
|
-
}
|
|
89
|
-
}, []);
|
|
90
|
-
|
|
91
|
-
const handleOnMouseOver = useCallback(
|
|
92
|
-
(msevent: any) => {
|
|
93
|
-
if (mouseoverEvent) {
|
|
94
|
-
mouseoverEvent(true);
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
[mouseoverEvent],
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
const handleOnMouseOut = useCallback(
|
|
101
|
-
(msevent: any) => {
|
|
102
|
-
if (mouseoverEvent) {
|
|
103
|
-
mouseoverEvent(false);
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
[mouseoverEvent],
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
const handleTransformer = useCallback(
|
|
110
|
-
(node: PIXI.Container, parentNode: PIXI.Container) => {
|
|
111
|
-
const isEnabled = true;
|
|
112
|
-
// @ts-ignore
|
|
113
|
-
PixiTransformer.current = node;
|
|
114
|
-
const transformer = new Transformer({
|
|
115
|
-
rotateEnabled: isEnabled,
|
|
116
|
-
boxRotationEnabled: isEnabled,
|
|
117
|
-
boxScalingEnabled: isEnabled,
|
|
118
|
-
scaleEnabled: isEnabled,
|
|
119
|
-
group: [node],
|
|
120
|
-
wireframeStyle: {
|
|
121
|
-
thickness: 2,
|
|
122
|
-
color: anchorFill,
|
|
123
|
-
},
|
|
124
|
-
lockAspectRatio: true,
|
|
125
|
-
handleStyle: {
|
|
126
|
-
// color: colorYellow,
|
|
127
|
-
outlineColor: colorYellow,
|
|
128
|
-
shape: "circle",
|
|
129
|
-
radius: 10,
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// transformer.addListener("transformchange", transformChange);
|
|
134
|
-
// @ts-ignore
|
|
135
|
-
transformer.addListener("transformcommit", transformCommit);
|
|
136
|
-
// transformer.addListener("dblclick", (evt) => {
|
|
137
|
-
// handleOnDblClick(evt);
|
|
138
|
-
// });
|
|
139
|
-
// transformer.on("mouseover", () => {
|
|
140
|
-
// handleOnMouseOver(true);
|
|
141
|
-
// });
|
|
142
|
-
// transformer.on("mouseout", () => {
|
|
143
|
-
// handleOnMouseOut(false);
|
|
144
|
-
// });
|
|
145
|
-
// @ts-ignore
|
|
146
|
-
transformerRef.current = transformer;
|
|
147
|
-
// @ts-ignore
|
|
148
|
-
parentRef.current = parentNode;
|
|
149
|
-
parentRef.current.addChild(transformerRef.current);
|
|
150
|
-
},
|
|
151
|
-
[
|
|
152
|
-
transformCommit,
|
|
153
|
-
transformChange,
|
|
154
|
-
handleOnMouseOver,
|
|
155
|
-
handleOnMouseOut,
|
|
156
|
-
handleOnDblClick,
|
|
157
|
-
],
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
const removeTransformer = useCallback(() => {
|
|
161
|
-
if (transformerRef.current) {
|
|
162
|
-
// @ts-ignore
|
|
163
|
-
parentRef.current.removeChild(transformerRef.current);
|
|
164
|
-
}
|
|
165
|
-
}, []);
|
|
166
|
-
|
|
167
|
-
return { handleTransformer, removeTransformer, isDragging };
|
|
168
|
-
};
|