reacthub-pixitweenjs 0.2.4 → 0.2.5

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 (29) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build-storybook.log +79 -476
  3. package/package.json +26 -29
  4. package/src/components/PixiAnimatedSprite/PixiAnimatedSprite.tsx +51 -0
  5. package/src/components/PixiAnimatedSprite/index.ts +2 -0
  6. package/src/components/PixiAudioSprite/PixiAudioSprite.stories.tsx +61 -0
  7. package/src/components/PixiAudioSprite/PixiAudioSprite.tsx +212 -0
  8. package/src/components/PixiAudioSprite/index.ts +1 -0
  9. package/src/components/PixiGifSprite/PixiGifSprite.stories.tsx +135 -0
  10. package/src/components/PixiGifSprite/PixiGifSprite.tsx +451 -0
  11. package/src/components/PixiGifSprite/index.ts +2 -0
  12. package/src/components/PixiImageSprite/PixiImageSprite.stories.tsx +11 -0
  13. package/src/components/PixiImageSprite/PixiImageSprite.tsx +30 -36
  14. package/src/components/PixiSVGSprite/PixiSvgPathSprite.stories.tsx +137 -0
  15. package/src/components/PixiSVGSprite/PixiSvgPathSprite.tsx +378 -0
  16. package/src/components/PixiSVGSprite/index.ts +1 -0
  17. package/src/components/PixiVideoSprite/PixiVideoSprite.stories.tsx +147 -0
  18. package/src/components/PixiVideoSprite/PixiVideoSprite.tsx +684 -0
  19. package/src/components/PixiVideoSprite/PixiVideoSpriteBackup.txt +755 -0
  20. package/src/components/PixiVideoSprite/index.ts +1 -0
  21. package/src/declare.module.ts +5 -0
  22. package/src/providers/GsapPixieContextProvider.tsx +94 -8
  23. package/src/reacthub-react-bindings.d.ts +27 -0
  24. package/src/utils/AppStateProvider.tsx +15 -26
  25. package/src/utils/AppStateStage.tsx +1 -1
  26. package/src/utils/PixiStage.tsx +1 -5
  27. package/src/utils/PixiTransformer.tsx +100 -0
  28. package/src/utils/VideoSeekBar.tsx +34 -23
  29. package/src/utils/useDebounce.tsx +15 -0
@@ -0,0 +1,451 @@
1
+ import * as React from "react";
2
+ import { useContext, useEffect, useRef, useState } from "react";
3
+ // @ts-ignore
4
+ import map from "lodash/map";
5
+ // @ts-ignore
6
+ import PropTypes from "prop-types";
7
+ import { GsapPixieContext } from "../../providers/GsapPixieContextProvider";
8
+ import { Container, useApp, withFilters, Graphics } from "@pixi/react";
9
+ import { AdjustmentFilter } from "@pixi/filter-adjustment";
10
+ import * as PIXI from "pixi.js";
11
+ import gsap from "gsap";
12
+ import { useWorkerParser, usePlayerState } from "@react-gifs/tools";
13
+ import PixiTransformer from "../../utils/PixiTransformer";
14
+
15
+ // @ts-ignore
16
+ import isEmpty from "lodash/isEmpty";
17
+ import { getAnimByName } from "../../utils/GsapAnim";
18
+ import { TransformationEnd } from "../../types/transformation";
19
+ import { PixiAnimatedSprite } from "../PixiAnimatedSprite";
20
+
21
+ type PixiGifSpriteProps = {
22
+ uniqueId: string;
23
+ src: string;
24
+ startAt: number;
25
+ endAt: number;
26
+ initialAlpha: number;
27
+ locked: boolean;
28
+ loop: boolean;
29
+ transformation: {
30
+ x: number;
31
+ y: number;
32
+ width: number;
33
+ height: number;
34
+ anchor: number;
35
+ rotation?: number;
36
+ alpha?: number;
37
+ scale?: number | [number, number];
38
+ tint?: number;
39
+ blendMode?: number;
40
+ animation?: string;
41
+ colorCorrection?: {
42
+ enabled?: boolean;
43
+ temperature?: number;
44
+ hue?: number;
45
+ contrast?: number;
46
+ saturation?: number;
47
+ exposure?: number;
48
+ reset?: boolean;
49
+ sharpness?: number;
50
+ value?: number;
51
+ levels?: number;
52
+ luminance?: number;
53
+ enhance?: number;
54
+ blurRadius?: number;
55
+ red?: number;
56
+ green?: number;
57
+ blue?: number;
58
+ alpha?: number;
59
+ scaleInput?: number;
60
+ };
61
+ effect?: string;
62
+ };
63
+ pointerdown?: () => void;
64
+ pointerup?: () => void;
65
+ mousedown?: () => void;
66
+ mouseup?: () => void;
67
+ pointerover?: () => void;
68
+ mouseover?: () => void;
69
+ mouseout?: () => void;
70
+ pointerout?: () => void;
71
+ applyTransformer?: boolean;
72
+ onAnchorTransformationEnd?: (endData: any) => void;
73
+ };
74
+
75
+ type EffectFunc = () => void;
76
+ type Deps = ReadonlyArray<unknown>;
77
+
78
+ const Filters = withFilters(Container, {
79
+ blur: PIXI.filters.BlurFilter,
80
+ adjust: AdjustmentFilter,
81
+ matrix: PIXI.filters.ColorMatrixFilter,
82
+ });
83
+
84
+ /** filter config */
85
+ const config = {
86
+ dot: {
87
+ scale: 1,
88
+ angle: 5,
89
+ },
90
+ blur: {
91
+ blur: 0,
92
+ quality: 4,
93
+ },
94
+ };
95
+
96
+ /** CYAN Filters */
97
+ const CYAN = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
98
+
99
+ const initialState = {
100
+ isPlaying: false,
101
+ progress: 0,
102
+ speed: 1,
103
+ isMuted: false,
104
+ isWaiting: false,
105
+ loaded: false,
106
+ size: { width: 50, height: 50 },
107
+ play: false,
108
+ current: false,
109
+ };
110
+
111
+ /**
112
+ * PixiGifSprite Component is used to render gif image
113
+ * @param props Gif Sprite props
114
+ * @returns
115
+ */
116
+ const PixiGifSprite: React.FC<PixiGifSpriteProps> = (props) => {
117
+ //// State
118
+ const [gifFrame, setGifFrame] = React.useState<PIXI.Texture[]>([]);
119
+ const [gifDuration, setGifDuration] = React.useState<number>(0);
120
+ const [gifFrameObject, setGifFrameObject] = React.useState<
121
+ PIXI.FrameObject[]
122
+ >([]);
123
+ const [currentFrame, setCurrentFrame] = useState<number>(0);
124
+ const [isComplete, setIsComplete] = useState<boolean>(false);
125
+
126
+ const [isDragging, setIsDragging] = useState(false);
127
+ const [isMouseOverTransformer, setIsMouseOverTransformer] = useState(false);
128
+
129
+ const [gifState, update] = usePlayerState({ autoPlay: false });
130
+ const graphicRef = React.useRef<PIXI.Graphics>(null);
131
+ const gifStatusRef = React.useRef(false);
132
+
133
+ console.log("allProps", props);
134
+ //// Refs
135
+ const animatedSpriteRef = useRef<PIXI.AnimatedSprite>(null);
136
+ const containerRef = useRef<PIXI.Container>(null);
137
+ const parentNode = useRef<PIXI.Container>(null);
138
+ const imgGroupRef = useRef<PIXI.Container>(null);
139
+ const transformerRef = useRef<PIXI.Container>(null);
140
+
141
+ //// Context
142
+ const { tl, play: tlPlay } = useContext(GsapPixieContext);
143
+
144
+ /// 1001
145
+ console.log("contxt Values", tl);
146
+ console.log("gifState", gifState, gifDuration);
147
+ const {
148
+ index,
149
+ frames: gifFrames,
150
+ delays: gifDelays,
151
+ length,
152
+ loaded,
153
+ } = gifState;
154
+
155
+ const {
156
+ uniqueId,
157
+ src,
158
+ startAt,
159
+ endAt,
160
+ initialAlpha,
161
+ locked,
162
+ loop,
163
+ transformation: {
164
+ width = 0,
165
+ height = 0,
166
+ x,
167
+ y,
168
+ rotation = 0,
169
+ scale,
170
+ anchor,
171
+ animation,
172
+ colorCorrection,
173
+ effect,
174
+ },
175
+ pointerdown,
176
+ pointerup,
177
+ mousedown,
178
+ mouseup,
179
+ pointerover,
180
+ mouseover,
181
+ mouseout,
182
+ pointerout,
183
+ applyTransformer,
184
+ onAnchorTransformationEnd,
185
+ ...restProps
186
+ } = props;
187
+
188
+ // color corrections
189
+ const {
190
+ enabled = false,
191
+ temperature = 1,
192
+ hue = 1,
193
+ contrast = 1,
194
+ saturation = 1,
195
+ exposure = 1,
196
+ reset,
197
+ sharpness = 1,
198
+ value = 0,
199
+ levels = 1,
200
+ luminance = 0,
201
+ enhance = 0,
202
+ blurRadius = 0,
203
+ red = 150,
204
+ green = 150,
205
+ blue = 150,
206
+ alpha = 1,
207
+ scaleInput = 1,
208
+ } = colorCorrection || {};
209
+
210
+ const app = useApp();
211
+
212
+ /** adjustment filter */
213
+ const adjustments = {
214
+ brightness: exposure,
215
+ contrast,
216
+ saturation,
217
+ alpha,
218
+ };
219
+
220
+ // load and parse gif
221
+ useWorkerParser(src, update);
222
+
223
+ // updates current index
224
+ // usePlayback(gifState, () => update(({ index }) => ({ index: index + 1 })));
225
+
226
+ // transformer to handle sprite transformation
227
+ const handleOnTransformEnd = React.useCallback(
228
+ (endData: TransformationEnd) => {
229
+ console.log("changeEnd", endData);
230
+ if (onAnchorTransformationEnd) {
231
+ onAnchorTransformationEnd(endData);
232
+ }
233
+ },
234
+ []
235
+ );
236
+
237
+ React.useEffect(() => {
238
+ if (!isEmpty(gifFrames)) {
239
+ // app.stage.addChild(frames);
240
+ /// load textues
241
+ const texturedFrames = map(gifFrames, (eachFrame: ImageData) => {
242
+ const { data, width, height } = eachFrame;
243
+ const dataEx = new Uint8Array(data);
244
+ return PIXI.Texture.fromBuffer(dataEx, width, height);
245
+ });
246
+
247
+ const frameObj = texturedFrames.map(
248
+ (eachFrame: PIXI.Texture, index: number) => {
249
+ return {
250
+ texture: eachFrame,
251
+ time: gifDelays[index],
252
+ };
253
+ }
254
+ );
255
+
256
+ setGifFrame(texturedFrames);
257
+ setGifFrameObject(frameObj);
258
+ let duration = 0;
259
+ gifDelays.forEach((delay) => {
260
+ duration += delay * 10;
261
+ });
262
+ setGifDuration(duration);
263
+ }
264
+ }, [gifFrames, gifDelays]);
265
+
266
+ /** Gsap Start and Stop Events */
267
+ const gsapOnStart = (startAt: number) => {
268
+ if (animatedSpriteRef.current) {
269
+ animatedSpriteRef.current.gotoAndPlay(startAt || 0);
270
+ }
271
+ };
272
+
273
+ const gsapOnPause = (startAt: number) => {
274
+ // console.log(`gsap onStart ${droptype} id`, refId);
275
+ // console.log(elementRefs.current[refId]);
276
+ if (animatedSpriteRef.current) {
277
+ animatedSpriteRef.current.stop();
278
+ }
279
+ };
280
+
281
+ const gsapOnComplete = () => {
282
+ if (animatedSpriteRef.current) {
283
+ animatedSpriteRef.current.stop();
284
+ // animatedSpriteRef.current.gotoAndStop(0);
285
+ }
286
+ };
287
+
288
+ const onInterrupt = () => {
289
+ // console.log('interrupting', refId);
290
+ };
291
+
292
+ const onUpdate = () => {
293
+ // console.log('timeline paused', ctxTimeLine.paused());
294
+ // if (animatedSpriteRef.current) {
295
+ // animatedSpriteRef.current.play();
296
+ // dispatchState({
297
+ // play: play,
298
+ // });
299
+ // }
300
+ };
301
+
302
+ const handleComplete = () => {
303
+ setIsComplete(true);
304
+ // if (onComplete) {
305
+ // onComplete();
306
+ // }
307
+ };
308
+
309
+ useEffect(() => {
310
+ let ctx = gsap.context(() => {});
311
+ if (containerRef.current && tl.current) {
312
+ const data = {
313
+ duration: Number(endAt) - Number(startAt),
314
+ onStart: gsapOnStart,
315
+ onComplete: gsapOnComplete,
316
+ onStartParams: [startAt],
317
+ onCompleteParams: [],
318
+ onInterrupt: onInterrupt,
319
+ onUpdate: onUpdate,
320
+ onUpdateParams: [],
321
+ };
322
+
323
+ const ease = getAnimByName(animation || "None");
324
+ ctx = gsap.context(() => {
325
+ if (!isEmpty(ease.from)) {
326
+ tl.current
327
+ .from(containerRef.current, { ...ease.from }, startAt)
328
+ .to(imgGroupRef.current, { alpha: 1, duration: 0.2 }, startAt)
329
+ .from(imgGroupRef.current, { ...data }, startAt)
330
+ .to(containerRef.current, { alpha: 0, duration: 0.2 }, endAt - 0.2);
331
+ } else if (!isEmpty(ease.to)) {
332
+ tl.current
333
+ .to(
334
+ containerRef.current,
335
+ { alpha: 1, duration: 0.2, ...ease.to },
336
+ startAt
337
+ )
338
+ .from(imgGroupRef.current, { ...data }, startAt)
339
+ .to(containerRef.current, { alpha: 0, duration: 0.2 }, endAt - 0.2);
340
+ } else if (!isEmpty(ease.fromTo)) {
341
+ tl.current
342
+ .fromTo(
343
+ containerRef.current,
344
+ ease.fromTo?.from,
345
+ ease.fromTo?.to,
346
+ startAt
347
+ )
348
+ .from(imgGroupRef.current, { ...data }, startAt)
349
+ .to(containerRef.current, { alpha: 0, duration: 0.2 }, endAt - 0.2);
350
+ } else {
351
+ tl.current
352
+ .to(containerRef.current, { alpha: 1, duration: 0.01 }, startAt)
353
+ .from(imgGroupRef.current, { ...data }, startAt)
354
+ .to(
355
+ containerRef.current,
356
+ { alpha: 0, duration: 0.1 },
357
+ Number(endAt) - Number(0.1)
358
+ );
359
+ }
360
+ });
361
+ }
362
+ return () => ctx.revert(); // cleanup!
363
+ }, [animation, startAt, endAt]);
364
+
365
+ /** handle on tranformer onchange */
366
+ const handleOnTransformChange = React.useCallback(() => {
367
+ setIsDragging(true);
368
+ }, []);
369
+
370
+ app.ticker.add((delta) => {
371
+ if (graphicRef.current) {
372
+ graphicRef.current.rotation += 0.01 * delta;
373
+ graphicRef.current
374
+ .clear()
375
+ .lineStyle(4, 0xffffff, 1)
376
+ .moveTo(40, 0)
377
+ .arc(0, 0, 40, 0, Math.PI * 2 * 0.6, false);
378
+ }
379
+ });
380
+
381
+ const draw = React.useCallback((g: PIXI.Graphics) => {
382
+ g.clear();
383
+ }, []);
384
+
385
+ return (
386
+ // @ts-ignore
387
+ <Container ref={parentNode}>
388
+ {/* @ts-ignore */}
389
+ <Container
390
+ ref={containerRef}
391
+ alpha={initialAlpha}
392
+ position={[x, y]}
393
+ pivot={[x, y]}
394
+ width={width}
395
+ height={height}
396
+ >
397
+ {/* @ts-ignore */}
398
+ <Container ref={imgGroupRef}>
399
+ {!loaded && (
400
+ // @ts-ignore
401
+ <Container anchor={0.5} position={[width / 2, height / 2]}>
402
+ <Graphics x={x} y={y} ref={graphicRef} draw={draw} />
403
+ </Container>
404
+ )}
405
+ {gifFrame && gifFrame.length > 0 && (
406
+ <PixiAnimatedSprite
407
+ x={x}
408
+ y={y}
409
+ width={width}
410
+ height={height}
411
+ rotation={rotation}
412
+ animationSpeed={1}
413
+ loop={loop}
414
+ isPlaying={!!tlPlay}
415
+ // @ts-ignore
416
+ textures={gifFrameObject}
417
+ onComplete={handleComplete}
418
+ onFrameChange={(currentFrame: number) =>
419
+ setCurrentFrame(currentFrame)
420
+ }
421
+ anchor={0.5}
422
+ {...(!locked &&
423
+ !isDragging && {
424
+ interactive: true,
425
+ buttonMode: true,
426
+ pointerdown: pointerdown,
427
+ pointerover: pointerover,
428
+ pointerout: pointerout,
429
+ })}
430
+ forwardRef={animatedSpriteRef}
431
+ scale={scale}
432
+ />
433
+ )}
434
+ </Container>
435
+ </Container>
436
+ {applyTransformer && (
437
+ <PixiTransformer
438
+ pixiTransformerRef={transformerRef}
439
+ imageRef={containerRef}
440
+ isMounted={loaded}
441
+ transformCommit={handleOnTransformEnd}
442
+ transformChange={handleOnTransformChange}
443
+ mouseoverEvent={setIsMouseOverTransformer}
444
+ uniqueId={uniqueId}
445
+ />
446
+ )}
447
+ </Container>
448
+ );
449
+ };
450
+
451
+ export default PixiGifSprite;
@@ -0,0 +1,2 @@
1
+ export { default as PixiGifSprite } from "./PixiGifSprite";
2
+ export * from "./PixiGifSprite";
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { PixiImageSprite } from ".";
3
+ import { AppStateContextProvider } from "../../utils/AppStateProvider";
3
4
 
4
5
  // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
5
6
  const meta = {
@@ -75,6 +76,11 @@ type Story = StoryObj<typeof meta>;
75
76
 
76
77
  // More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
77
78
  export const Normal: Story = {
79
+ render: (args: any) => (
80
+ <AppStateContextProvider {...args}>
81
+ <PixiImageSprite {...args} />
82
+ </AppStateContextProvider>
83
+ ),
78
84
  args: {
79
85
  uniqueId: "surya001", // uniqueId of the sprite
80
86
  src: "https://assets.codepen.io/693612/surya.svg",
@@ -99,6 +105,11 @@ export const Normal: Story = {
99
105
  };
100
106
 
101
107
  export const FadeIn: Story = {
108
+ render: (args: any) => (
109
+ <AppStateContextProvider {...args}>
110
+ <PixiImageSprite {...args} />
111
+ </AppStateContextProvider>
112
+ ),
102
113
  args: {
103
114
  uniqueId: "surya002", // uniqueId of the sprite
104
115
  src: "https://assets.codepen.io/693612/surya.svg",
@@ -7,10 +7,11 @@ import { Sprite, Container, useApp, withFilters } from "@pixi/react";
7
7
  import { AdjustmentFilter } from "@pixi/filter-adjustment";
8
8
  import * as PIXI from "pixi.js";
9
9
  import gsap from "gsap";
10
+ import PixiTransformer from "../../utils/PixiTransformer";
11
+
10
12
  // @ts-ignore
11
13
  import isEmpty from "lodash/isEmpty";
12
14
  import { getAnimByName } from "../../utils/GsapAnim";
13
- import { usePixiTransformer } from "../../hooks/usePixiTransformer";
14
15
  import { TransformationEnd } from "../../types/transformation";
15
16
 
16
17
  type PixiImageSpriteProps = {
@@ -90,13 +91,7 @@ const CYAN = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
90
91
 
91
92
  const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
92
93
  //// State
93
- const [transform, setTransform] = useState({
94
- x: 0,
95
- y: 0,
96
- width: 80,
97
- height: 80,
98
- rotate: 0,
99
- });
94
+ const [isMounted, setIsMounted] = React.useState(false);
100
95
  const [isTransformerDragging, setIsTransformerDragging] = useState(false);
101
96
  const [isMouseOverTransformer, setIsMouseOverTransformer] = useState(false);
102
97
 
@@ -106,12 +101,13 @@ const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
106
101
  const containerRef = useRef<PIXI.Container>(null);
107
102
  const parentNode = useRef<PIXI.Container>(null);
108
103
  const imgGroupRef = useRef<PIXI.Container>(null);
104
+ const transformerRef = useRef<PIXI.Container>(null);
109
105
 
110
106
  //// Context
111
107
  const { tl } = useContext(GsapPixieContext);
112
108
 
113
109
  /// 1001
114
- console.log("contxt Values", tl);
110
+ // console.log("contxt Values", tl);
115
111
  const {
116
112
  uniqueId,
117
113
  src,
@@ -163,7 +159,6 @@ const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
163
159
  } = colorCorrection || {};
164
160
 
165
161
  const app = useApp();
166
- const PixiTransformer = useRef<any>(null);
167
162
 
168
163
  /** adjustment filter */
169
164
  const adjustments = {
@@ -173,27 +168,23 @@ const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
173
168
  alpha,
174
169
  };
175
170
 
171
+ /** handle on tranformer onchange */
172
+ const handleOnTransformChange = React.useCallback(() => {
173
+ setIsTransformerDragging(true);
174
+ }, []);
175
+
176
176
  // transformer to handle sprite transformation
177
177
  const handleOnTransformEnd = React.useCallback(
178
178
  (endData: TransformationEnd) => {
179
179
  console.log("changeEnd", endData);
180
180
  if (onAnchorTransformationEnd) {
181
+ console.log("running onAnchorTransformationEnd");
181
182
  onAnchorTransformationEnd(endData);
182
183
  }
183
184
  },
184
- [],
185
+ []
185
186
  );
186
187
 
187
- // initialize usePixiTransformer hook
188
- const { handleTransformer, removeTransformer, isDragging } =
189
- usePixiTransformer({
190
- uniqueId,
191
- onTransformEnd: handleOnTransformEnd,
192
- events: {},
193
- mouseoverEvent: setIsMouseOverTransformer,
194
- setDragging: setIsTransformerDragging,
195
- });
196
-
197
188
  useEffect(() => {
198
189
  let ctx = gsap.context(() => {});
199
190
  if (containerRef.current && tl.current) {
@@ -214,7 +205,7 @@ const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
214
205
  .to(
215
206
  containerRef.current,
216
207
  { alpha: 1, duration: 0.2, ...ease.to },
217
- startAt,
208
+ startAt
218
209
  )
219
210
  .from(imgGroupRef.current, { ...data }, startAt)
220
211
  .to(containerRef.current, { alpha: 0, duration: 0.2 }, endAt - 0.2);
@@ -224,7 +215,7 @@ const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
224
215
  containerRef.current,
225
216
  ease.fromTo?.from,
226
217
  ease.fromTo?.to,
227
- startAt,
218
+ startAt
228
219
  )
229
220
  .from(imgGroupRef.current, { ...data }, startAt)
230
221
  .to(containerRef.current, { alpha: 0, duration: 0.2 }, endAt - 0.2);
@@ -235,7 +226,7 @@ const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
235
226
  .to(
236
227
  containerRef.current,
237
228
  { alpha: 0, duration: 0.1 },
238
- Number(endAt) - Number(0.1),
229
+ Number(endAt) - Number(0.1)
239
230
  );
240
231
  }
241
232
  });
@@ -243,19 +234,11 @@ const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
243
234
  return () => ctx.revert(); // cleanup!
244
235
  }, [animation, startAt, endAt]);
245
236
 
246
- useEffect(() => {
247
- setIsTransformerDragging(isDragging);
248
- }, [isDragging]);
249
-
250
- // apply transformer in use effect hook based on prop applyTransformer
251
- useEffect(() => {
252
- if (applyTransformer && containerRef.current && parentNode.current) {
253
- handleTransformer(containerRef.current, parentNode.current);
237
+ React.useEffect(() => {
238
+ if (containerRef.current) {
239
+ setIsMounted(true);
254
240
  }
255
- return () => {
256
- removeTransformer();
257
- };
258
- }, [removeTransformer, handleTransformer, applyTransformer]);
241
+ }, []);
259
242
 
260
243
  return (
261
244
  // @ts-ignore
@@ -339,6 +322,17 @@ const PixiImageSprite: React.FC<PixiImageSpriteProps> = (props) => {
339
322
  </Container>
340
323
  )}
341
324
  </Container>
325
+ {applyTransformer && (
326
+ <PixiTransformer
327
+ pixiTransformerRef={transformerRef}
328
+ imageRef={containerRef}
329
+ isMounted={isMounted}
330
+ transformCommit={handleOnTransformEnd}
331
+ transformChange={handleOnTransformChange}
332
+ mouseoverEvent={setIsMouseOverTransformer}
333
+ uniqueId={uniqueId}
334
+ />
335
+ )}
342
336
  </Container>
343
337
  );
344
338
  };