reacthub-pixitweenjs 0.2.4 → 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.
Files changed (40) hide show
  1. package/.storybook/preview.tsx +6 -0
  2. package/CHANGELOG.md +27 -0
  3. package/README.md +1 -1
  4. package/build-storybook.log +79 -476
  5. package/package.json +29 -29
  6. package/src/components/PixiAnimatedSprite/PixiAnimatedSprite.tsx +51 -0
  7. package/src/components/PixiAnimatedSprite/index.ts +2 -0
  8. package/src/components/PixiAudioSprite/PixiAudioSprite.stories.tsx +61 -0
  9. package/src/components/PixiAudioSprite/PixiAudioSprite.tsx +202 -0
  10. package/src/components/PixiAudioSprite/index.ts +1 -0
  11. package/src/components/PixiGifSprite/PixiGifSprite.stories.tsx +135 -0
  12. package/src/components/PixiGifSprite/PixiGifSprite.tsx +372 -0
  13. package/src/components/PixiGifSprite/index.ts +2 -0
  14. package/src/components/PixiImageSprite/PixiImageSprite.stories.tsx +11 -0
  15. package/src/components/PixiImageSprite/PixiImageSprite.tsx +33 -70
  16. package/src/components/PixiSVGSprite/PixiSvgPathSprite.stories.tsx +137 -0
  17. package/src/components/PixiSVGSprite/PixiSvgPathSprite.tsx +346 -0
  18. package/src/components/PixiSVGSprite/index.ts +1 -0
  19. package/src/components/PixiTextSprite/PixiTextSprite.stories.tsx +176 -0
  20. package/src/components/PixiTextSprite/PixiTextSprite.tsx +540 -0
  21. package/src/components/PixiTextSprite/index.ts +1 -0
  22. package/src/components/PixiVideoSprite/PixiVideoSprite.stories.tsx +147 -0
  23. package/src/components/PixiVideoSprite/PixiVideoSprite.tsx +631 -0
  24. package/src/components/PixiVideoSprite/PixiVideoSpriteBackup.txt +755 -0
  25. package/src/components/PixiVideoSprite/index.ts +1 -0
  26. package/src/declare.module.ts +5 -0
  27. package/src/main.tsx +8 -7
  28. package/src/providers/GsapPixieContextProvider.tsx +102 -22
  29. package/src/reacthub-react-bindings.d.ts +27 -0
  30. package/src/stories/Installation.mdx +3 -3
  31. package/src/utils/AppStateProvider.tsx +18 -29
  32. package/src/utils/AppStateStage.tsx +1 -13
  33. package/src/utils/AppWrapper.tsx +4 -0
  34. package/src/utils/GsapAnim.tsx +1 -7
  35. package/src/utils/InteractionManager.tsx +36 -0
  36. package/src/utils/PixiStage.tsx +1 -5
  37. package/src/utils/PixiTransformer.tsx +165 -0
  38. package/src/utils/VideoSeekBar.tsx +35 -31
  39. package/src/utils/useDebounce.tsx +15 -0
  40. package/src/hooks/usePixiTransformer.tsx +0 -168
@@ -0,0 +1 @@
1
+ export { default as PixiVideoSprite } from "./PixiVideoSprite";
@@ -0,0 +1,5 @@
1
+ // declare module "@pixi/react" {
2
+ // interface Container {
3
+ // children?: React.ReactNode;
4
+ // }
5
+ // }
package/src/main.tsx CHANGED
@@ -1,10 +1,11 @@
1
- import React from 'react'
2
- import ReactDOM from 'react-dom/client'
3
- import App from './App'
4
- import './index.css'
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
- ReactDOM.createRoot(document.getElementById('root')).render(
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
+ );
@@ -7,18 +7,23 @@ import {
7
7
  useLayoutEffect,
8
8
  } from "react";
9
9
  import gsap from "gsap";
10
- import { emitCustomEvent } from "react-custom-events";
10
+ import { emitCustomEvent, useCustomEventListener } from "react-custom-events";
11
+ import { useDebounce } from "../utils/useDebounce";
11
12
 
12
13
  interface GsapPixieContextProps {
13
14
  gsapCtx: React.MutableRefObject<any>;
14
15
  tl: React.MutableRefObject<any>;
16
+ play: boolean;
17
+ isDragging: boolean;
15
18
  handlePlay: () => void;
16
19
  handlePause: () => void;
17
20
  handleReset: () => void;
18
- handleSeek: () => void;
21
+ handleSeek: (value: number) => void;
22
+ handleSeekTest: () => void;
19
23
  handleRestart: () => void;
20
24
  handleRepeat: () => void;
21
25
  playerTimeRef: React.MutableRefObject<number>;
26
+ totalDuration: number;
22
27
  }
23
28
 
24
29
  // Context has been created
@@ -30,6 +35,12 @@ const Events = {
30
35
  PAUSE: "GSAP_PAUSE",
31
36
  PLAY: "GSAP_PLAY",
32
37
  RESUME: "GSAP_RESUME",
38
+ RESTART: "GSAP_RESTART",
39
+ REPEAT: "GSAP_REPEAT",
40
+ SEEK: "GSAP_SEEK",
41
+ RESET: "GSAP_RESET",
42
+ DRAGGING_START: "GSAP_DRAGGING_START",
43
+ DRAGGING_END: "GSAP_DRAGGING_END",
33
44
  };
34
45
 
35
46
  // Provider
@@ -37,15 +48,18 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
37
48
  children,
38
49
  }) => {
39
50
  const [play, setPlay] = useState<boolean>(false);
40
- const [frameNumber, setFrameNumber] = useState<number>(0);
51
+ const [isDragging, setIsDragging] = useState<boolean>(false);
52
+ const [internalDuration, setInternalDuration] = useState<number>(0);
53
+ const [totalDuration, setTotalDuration] = useState<number>(0);
54
+ const delayedDuration = useDebounce(internalDuration, 600);
41
55
 
42
56
  const tl = useRef<any>();
43
57
  const gsapCtx = useRef<any>();
44
58
  const playerTimeRef = useRef<number>(0.001);
45
59
 
46
- const parentElementRef = useRef<any>();
60
+ // const parentElementRef = useRef<any>();
47
61
  // передаем предка анимируемых элементов
48
- const q = gsap.utils.selector(parentElementRef);
62
+ // const q = gsap.utils.selector(parentElementRef);
49
63
 
50
64
  useLayoutEffect(() => {
51
65
  gsapCtx.current = gsap.context(() => {
@@ -60,29 +74,72 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
60
74
  return () => gsapCtx.current.revert();
61
75
  }, []);
62
76
 
77
+ gsap.ticker.add(() => {
78
+ // console.log("timeframe", time, deltaTime, frame);
79
+ // setFrameNumber(frame);
80
+ if (tl.current && getTimelineDuration) {
81
+ setInternalDuration(getTimelineDuration());
82
+ }
83
+ });
84
+
63
85
  const onUpdate = useCallback(() => {
64
86
  /// console.log("update event callback");
65
87
  const timeline = tl.current;
66
- var now = timeline.time();
67
- var elapsedTime;
68
- if (playerTimeRef.current) {
69
- elapsedTime = now - playerTimeRef.current;
70
- }
88
+ let now = timeline.time();
89
+ // let elapsedTime;
90
+ // if (playerTimeRef.current) {
91
+ // elapsedTime = now - playerTimeRef.current;
92
+ // }
71
93
  // console.log(`elapseTime :${elapsedTime} and frame: ${frameNumber}`);
72
94
  //time = now;
73
95
  playerTimeRef.current = now;
74
96
  }, []);
75
97
 
98
+ // set the total duration based on the delayed duration value
99
+ useEffect(() => {
100
+ setTotalDuration(delayedDuration);
101
+ }, [delayedDuration]);
102
+
76
103
  useEffect(() => {
77
104
  const timeline = tl.current;
78
105
  timeline
106
+ .eventCallback("onStart", function () {
107
+ // console.log("onstart", timeline.progress());
108
+ // setPlay(true);
109
+ // onUpdate();
110
+ })
111
+ .eventCallback("onInterrupt", function () {
112
+ /// console.log("onInterrupt", timeline.progress());
113
+ setPlay(false);
114
+ onUpdate();
115
+ })
79
116
  .eventCallback("onUpdate", function () {
80
117
  /// console.log("onupdate", timeline.progress());
81
118
  onUpdate();
82
119
  })
120
+ // .eventCallback("onRepeat", function () {
121
+ // /// console.log("onrepeat", timeline.progress());
122
+ // onUpdate();
123
+ // })
124
+ // .eventCallback("onReverseComplete", function () {
125
+ // /// console.log("onReverseComplete", timeline.progress());
126
+ // onUpdate();
127
+ // })
128
+ // write a pause event
129
+ .eventCallback("onPause", function () {
130
+ console.log("onPause", timeline.progress());
131
+ setPlay(false);
132
+ onUpdate();
133
+ })
134
+ .eventCallback("onResume", function () {
135
+ console.log("onResume", timeline.progress());
136
+ setPlay(true);
137
+ onUpdate();
138
+ })
83
139
  .eventCallback("onComplete", function () {
84
- timeline.seek(0.01);
140
+ timeline.seek(0);
85
141
  timeline.pause();
142
+ setPlay(false);
86
143
  onUpdate();
87
144
  });
88
145
  }, []);
@@ -96,11 +153,6 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
96
153
  }
97
154
  }, [play]);
98
155
 
99
- const addTotalDuration = (duration: number) => {
100
- const timeline = tl.current;
101
- timeline.totalDuration(duration);
102
- };
103
-
104
156
  const handleReset = useCallback(() => {
105
157
  const timeline = tl.current;
106
158
 
@@ -110,39 +162,63 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
110
162
  const handleRestart = useCallback(() => {
111
163
  const timeline = tl.current;
112
164
  timeline.restart();
165
+ setPlay(true);
113
166
  }, []);
114
167
 
115
168
  const handleRepeat = useCallback(() => {
116
169
  const timeline = tl.current;
117
-
118
170
  timeline.repeat(1);
119
171
  timeline.restart();
172
+ // setPlay(true);
120
173
  }, []);
121
174
 
122
- const handleSeek = useCallback(() => {
175
+ const handleSeek = useCallback((value: number) => {
123
176
  const timeline = tl.current;
124
- timeline.seek(4);
177
+ timeline.seek(value);
125
178
  }, []);
126
179
 
127
- const setDurationTimeline = useCallback(() => {
180
+ const handleSeekTest = useCallback(() => {
128
181
  const timeline = tl.current;
182
+ timeline.seek(4);
183
+ }, []);
184
+
185
+ // const setTimelineDuration = useCallback(() => {
186
+ // const timeline = tl.current;
187
+ // timeline.totalDuration(3);
188
+ // }, []);
129
189
 
130
- timeline.totalDuration(3);
190
+ const getTimelineDuration = useCallback(() => {
191
+ const timeline = tl.current;
192
+ if (!timeline) return 0;
193
+ return timeline.totalDuration();
131
194
  }, []);
132
195
 
133
196
  const handlePause = () => {
134
197
  const timeline = tl.current;
135
-
136
198
  timeline.pause();
137
199
  emitCustomEvent(Events.PAUSE);
200
+ setPlay(false);
138
201
  };
139
202
 
140
203
  const handlePlay = () => {
141
204
  const timeline = tl.current;
205
+ setPlay(true);
142
206
  timeline.resume();
143
207
  emitCustomEvent(Events.RESUME);
144
208
  };
145
209
 
210
+ /** Event listener dragging */
211
+ useCustomEventListener(Events.DRAGGING_START, () => {
212
+ console.log("dragging start");
213
+ setIsDragging(true);
214
+ });
215
+
216
+ useCustomEventListener(Events.DRAGGING_END, () => {
217
+ setIsDragging(false);
218
+ console.log("dragging end");
219
+ });
220
+
221
+ console.log("set play updated", play);
146
222
  return (
147
223
  <GsapPixieContext.Provider
148
224
  value={{
@@ -152,9 +228,13 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
152
228
  handlePause,
153
229
  handleReset,
154
230
  handleSeek,
231
+ handleSeekTest,
155
232
  handleRestart,
156
233
  handleRepeat,
157
234
  playerTimeRef,
235
+ play,
236
+ totalDuration,
237
+ isDragging,
158
238
  }}
159
239
  >
160
240
  {children}
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ import * as PIXI from "pixi.js";
3
+
4
+ declare module "reacthub-react-bindings" {
5
+ interface TransformerProps {
6
+ group: PIXI.DisplayObject[];
7
+ rotateEnabled?: boolean;
8
+ boxRotationEnabled?: boolean;
9
+ boxScalingEnabled?: boolean;
10
+ wireframeStyle?: {
11
+ thickness: number;
12
+ color: number;
13
+ };
14
+ lockAspectRatio?: boolean;
15
+ scaleEnabled?: boolean;
16
+ handleStyle?: {
17
+ color?: number;
18
+ outlineColor?: number;
19
+ shape?: "circle" | "square";
20
+ radius?: number;
21
+ };
22
+ transformchange?: (transform: PIXI.Matrix) => void;
23
+ transformcommit?: (transform: PIXI.Matrix) => void;
24
+ }
25
+
26
+ export class Transformer extends React.Component<TransformerProps> {}
27
+ }
@@ -34,7 +34,7 @@ npm install
34
34
  "@pixi/picture": "^3.0.3",
35
35
  "@pixi/react": "7.0.0",
36
36
  "@pixi/sound": "^4.3.1",
37
- "pixi-filters": "5.1.1",
38
- "pixi-svg": "3.2.0",
39
- "pixi.js": "6.5.9",
37
+ "pixi-filters": "^5.2.1",
38
+ "pixi-svg": "^3.2.0",
39
+ "pixi.js": "^7.2.3",
40
40
  ```
@@ -8,19 +8,6 @@ interface AppState {
8
8
  };
9
9
  }
10
10
 
11
- interface AppStateContextProps extends AppState {
12
- onAnchorTransformationEnd: (data: TransformationEnd) => void;
13
- onMouseOverSprite: (data: unknown) => void;
14
- onClickSprite: (data: unknown) => void;
15
- }
16
-
17
- export const AppStateContext = React.createContext<AppStateContextProps>({
18
- transformation: {},
19
- onAnchorTransformationEnd: () => {},
20
- onMouseOverSprite: () => {},
21
- onClickSprite: () => {},
22
- });
23
-
24
11
  interface AppStateContextProviderProps extends AppState {
25
12
  children: React.ReactNode;
26
13
  }
@@ -28,43 +15,45 @@ interface AppStateContextProviderProps extends AppState {
28
15
  export const AppStateContextProvider: React.FC<
29
16
  AppStateContextProviderProps
30
17
  > = ({ children, ...props }) => {
18
+ console.log("AppStateContextProvider", props);
31
19
  const [appState, setAppState] = React.useState<AppState>(props);
20
+ const appStateRef = React.useRef<AppState>(appState);
21
+
32
22
  useDeepEffect(() => {
33
23
  setAppState(props);
24
+ appStateRef.current = props;
34
25
  }, [props]);
35
26
 
36
27
  const onAnchorTransformationEnd = React.useCallback(
37
- (data: {
38
- uniqueId: string;
39
- transformation: { [key: string]: unknown };
40
- }) => {
41
- const { uniqueId, transformation } = data;
28
+ (data: TransformationEnd) => {
29
+ console.log("onAnchorTransformationEnd", data);
30
+ const { transformation } = data;
42
31
  const newAppState = {
43
- ...props,
32
+ ...appStateRef.current,
44
33
  transformation: {
45
- ...props.transformation,
34
+ ...appStateRef.current?.transformation,
46
35
  ...transformation,
47
36
  },
48
37
  };
38
+ console.log("saving state", newAppState);
49
39
  setAppState(newAppState);
50
40
  },
51
- [props],
41
+ []
52
42
  );
53
43
 
54
- const onMouseOverSprite = React.useCallback((data: unknown) => {}, []);
44
+ const onMouseOverSprite = React.useCallback(() => {}, []);
55
45
 
56
- const onClickSprite = React.useCallback((data: unknown) => {}, []);
46
+ const onClickSprite = React.useCallback(() => {}, []);
57
47
 
58
48
  return (
59
- <AppStateContext.Provider
60
- value={{
49
+ <>
50
+ {/*@ts-ignore */}
51
+ {React.cloneElement(children, {
61
52
  ...appState,
62
53
  onAnchorTransformationEnd,
63
54
  onMouseOverSprite,
64
55
  onClickSprite,
65
- }}
66
- >
67
- {children}
68
- </AppStateContext.Provider>
56
+ })}
57
+ </>
69
58
  );
70
59
  };
@@ -1,6 +1,4 @@
1
1
  import * as React from "react";
2
- import ContextBridge from "./ContextBridge";
3
- import { AppStateContext } from "../providers/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;
@@ -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"}>
@@ -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;
@@ -1,7 +1,6 @@
1
1
  import * as React from "react";
2
2
  import ContextBridge from "./ContextBridge";
3
3
  import { Stage as PixiStage } from "@pixi/react";
4
- import { AppStateContextProvider } from "./AppStateProvider";
5
4
  import { GsapPixieContext } from "../providers/GsapPixieContextProvider";
6
5
 
7
6
  interface StageProps {
@@ -18,10 +17,7 @@ const Stage: React.FC<StageProps> = ({ children, ...props }) => {
18
17
  render={(children: React.ReactNode | React.ReactElement) => (
19
18
  <PixiStage {...props}>
20
19
  {/* @ts-ignore */}
21
- <AppStateContextProvider {...props}>
22
- {/* @ts-ignore */}
23
- {children}
24
- </AppStateContextProvider>
20
+ {children}
25
21
  </PixiStage>
26
22
  )}
27
23
  >
@@ -0,0 +1,165 @@
1
+ import * as PIXI from "pixi.js";
2
+ import * as React from "react";
3
+ // @ts-ignore
4
+ import { Transformer } from "reacthub-react-bindings";
5
+
6
+ type PixiTransformerProps = {
7
+ pixiTransformerRef: React.MutableRefObject<any>;
8
+ imageRef: React.MutableRefObject<any>;
9
+ isMounted: boolean;
10
+ transformCommit?: (data: any) => void;
11
+ transformChange?: (data: any) => void;
12
+ mouseoverEvent?: (flag: boolean) => void;
13
+ onDoubleClick?: (data: any) => void;
14
+ uniqueId?: string;
15
+ };
16
+
17
+ type PixiTransformerState = {
18
+ isDragging: boolean;
19
+ };
20
+
21
+ /**
22
+ * Initialize PixiTransformer to transform the image
23
+ * @param param0
24
+ * @returns
25
+ */
26
+ const PixiTransformer = ({
27
+ pixiTransformerRef,
28
+ imageRef,
29
+ isMounted,
30
+ transformCommit,
31
+ transformChange,
32
+ mouseoverEvent,
33
+ onDoubleClick,
34
+ uniqueId = "",
35
+ }: PixiTransformerProps) => {
36
+ // states
37
+ const colorYellow = PIXI.utils.string2hex("#F3C409");
38
+ const anchorFill = PIXI.utils.string2hex("#F3C409");
39
+ const transformerState = React.useRef<PixiTransformerState>({
40
+ isDragging: false,
41
+ });
42
+
43
+ const handleOnMouseOver = React.useCallback(() => {
44
+ if (mouseoverEvent && !transformerState.current.isDragging) {
45
+ mouseoverEvent(true);
46
+ }
47
+ }, [mouseoverEvent]);
48
+
49
+ const handleOnMouseOut = React.useCallback(() => {
50
+ if (mouseoverEvent && !transformerState.current.isDragging) {
51
+ mouseoverEvent(false);
52
+ }
53
+ }, [mouseoverEvent]);
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
+
85
+ const handleOnTransformCommit = React.useCallback(() => {
86
+ if (imageRef.current === null) return;
87
+ const x = imageRef.current.x;
88
+ const y = imageRef.current.y;
89
+ const width = imageRef.current.width;
90
+ const height = imageRef.current.height;
91
+ const rotate = imageRef.current.rotation;
92
+ const scale: [number, number] = [
93
+ imageRef.current.scale.x,
94
+ imageRef.current.scale.y,
95
+ ];
96
+ if (transformCommit) {
97
+ transformCommit({
98
+ uniqueId,
99
+ transformation: {
100
+ x: Math.round(x),
101
+ y: Math.round(y),
102
+ width: Math.round(Math.max(5, width)),
103
+ height: Math.round(Math.max(5, height)),
104
+ rotate: Math.round(rotate),
105
+ scale: scale,
106
+ },
107
+ });
108
+ }
109
+ // update transformer state to is not dragging.
110
+ transformerState.current.isDragging = false;
111
+ }, [transformCommit]);
112
+
113
+ React.useEffect(() => {
114
+ if (pixiTransformerRef.current) {
115
+ pixiTransformerRef.current.on("mouseover", handleOnMouseOver);
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);
122
+ }
123
+ return () => {
124
+ if (pixiTransformerRef.current) {
125
+ pixiTransformerRef.current.off("mouseover", handleOnMouseOver);
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
+ );
138
+ }
139
+ };
140
+ }, []);
141
+
142
+ return (
143
+ <Transformer
144
+ ref={pixiTransformerRef}
145
+ group={isMounted ? [imageRef.current] : []}
146
+ rotateEnabled={true}
147
+ boxRotationEnabled={true}
148
+ centeredScaling={true}
149
+ boxScalingEnabled={true}
150
+ wireframeStyle={{ thickness: 1, color: anchorFill }}
151
+ lockAspectRatio={true}
152
+ scaleEnabled={true}
153
+ handleStyle={{
154
+ // color: colorYellow,
155
+ outlineColor: colorYellow,
156
+ shape: "circle",
157
+ radius: 9,
158
+ }}
159
+ transformchange={handleOnTransformChange}
160
+ transformcommit={handleOnTransformCommit}
161
+ />
162
+ );
163
+ };
164
+
165
+ export default PixiTransformer;