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,631 @@
1
+ import * as React from "react";
2
+ import { useContext, useEffect, useRef, useState } from "react";
3
+ // @ts-ignore
4
+ import PropTypes from "prop-types";
5
+ import { useCustomEventListener } from "react-custom-events";
6
+ import {
7
+ GsapPixieContext,
8
+ Events,
9
+ } from "../../providers/GsapPixieContextProvider";
10
+ import { Sprite, Container, withFilters } from "@pixi/react";
11
+ import { AdjustmentFilter } from "@pixi/filter-adjustment";
12
+ import * as PIXI from "pixi.js";
13
+ import gsap from "gsap";
14
+ import PixiTransformer from "../../utils/PixiTransformer";
15
+
16
+ // @ts-ignore
17
+ import isEmpty from "lodash/isEmpty";
18
+ import { getAnimByName } from "../../utils/GsapAnim";
19
+ import { TransformationEnd } from "../../types/transformation";
20
+
21
+ type PixiVideoSpriteProps = {
22
+ uniqueId: string;
23
+ src: string;
24
+ startAt: number;
25
+ endAt: number;
26
+ frameStartAt: number;
27
+ frameEndAt: number;
28
+ mute: boolean;
29
+ locked: boolean;
30
+ initialAlpha: number;
31
+ transformation: {
32
+ x: number;
33
+ y: number;
34
+ width: number;
35
+ height: number;
36
+ anchor: number;
37
+ rotation?: number;
38
+ alpha?: number;
39
+ scale?: number | [number, number];
40
+ tint?: number;
41
+ blendMode?: number;
42
+ animation?: string;
43
+ colorCorrection?: {
44
+ enabled?: boolean;
45
+ temperature?: number;
46
+ hue?: number;
47
+ contrast?: number;
48
+ saturation?: number;
49
+ exposure?: number;
50
+ reset?: boolean;
51
+ sharpness?: number;
52
+ value?: number;
53
+ levels?: number;
54
+ luminance?: number;
55
+ enhance?: number;
56
+ blurRadius?: number;
57
+ red?: number;
58
+ green?: number;
59
+ blue?: number;
60
+ alpha?: number;
61
+ scaleInput?: number;
62
+ };
63
+ effect?: string;
64
+ };
65
+ pointerdown?: () => void;
66
+ pointerup?: () => void;
67
+ mousedown?: () => void;
68
+ mouseup?: () => void;
69
+ pointerover?: () => void;
70
+ mouseover?: () => void;
71
+ mouseout?: () => void;
72
+ applyTransformer?: boolean;
73
+ onAnchorTransformationEnd?: (endData: any) => void;
74
+ };
75
+
76
+ interface VideoState {
77
+ isPlaying: boolean;
78
+ progress: number;
79
+ speed: number;
80
+ isMuted: boolean;
81
+ isWaiting: boolean;
82
+ loaded: boolean;
83
+ size: { width: number; height: number };
84
+ isDragging: boolean;
85
+ }
86
+
87
+ const Filters = withFilters(Container, {
88
+ blur: PIXI.filters.BlurFilter,
89
+ adjust: AdjustmentFilter,
90
+ matrix: PIXI.filters.ColorMatrixFilter,
91
+ });
92
+
93
+ /** CYAN Filters */
94
+ const CYAN = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
95
+
96
+ const initialState: VideoState = {
97
+ isPlaying: false,
98
+ progress: 0,
99
+ speed: 1,
100
+ isMuted: false,
101
+ isWaiting: false,
102
+ loaded: false,
103
+ size: { width: 50, height: 50 },
104
+ isDragging: false,
105
+ };
106
+
107
+ const PixiVideoSprite: React.FC<PixiVideoSpriteProps> = (props) => {
108
+ //// State
109
+ const [isMounted, setIsMounted] = React.useState(false);
110
+ /// const [isTransformerDragging, setIsTransformerDragging] = useState(false);
111
+ const [, setIsMouseOverTransformer] = useState(false);
112
+ const [, setVideoState] = React.useState({
113
+ isWaiting: false,
114
+ isStalled: false,
115
+ });
116
+ const [videoTexture, setVideoTexture] =
117
+ React.useState<PIXI.Texture<PIXI.Resource>>();
118
+ const [isDragging, setIsDragging] = useState(false);
119
+
120
+ console.log("PixiVideoSpriteProps", props);
121
+ //// Refs
122
+ const imageRef = useRef<PIXI.Sprite>(null);
123
+ const containerRef = useRef<PIXI.Container>(null);
124
+ const parentNode = useRef<PIXI.Container>(null);
125
+ const imgGroupRef = useRef<PIXI.Container>(null);
126
+ const transformerRef = useRef<PIXI.Container>(null);
127
+ const videoElement = useRef<HTMLVideoElement>(null);
128
+ const videoStateRef = useRef<VideoState>(initialState);
129
+
130
+ //// Context
131
+ const {
132
+ tl,
133
+ playerTimeRef,
134
+ isDragging: gsapDragging,
135
+ play,
136
+ } = useContext(GsapPixieContext);
137
+
138
+ // console log draggging
139
+ console.log("isGsapDragging", gsapDragging);
140
+ console.log("play", play);
141
+ /// 1001
142
+ // console.log("contxt Values", tl);
143
+ const {
144
+ uniqueId,
145
+ mute = false,
146
+ locked = false,
147
+ src,
148
+ startAt,
149
+ endAt,
150
+ frameStartAt,
151
+ frameEndAt,
152
+ initialAlpha,
153
+ transformation: {
154
+ x,
155
+ y,
156
+ width,
157
+ height,
158
+ scale,
159
+ rotation,
160
+ animation,
161
+ colorCorrection,
162
+ effect,
163
+ },
164
+ pointerdown,
165
+ pointerup,
166
+ mousedown,
167
+ mouseup,
168
+ pointerover,
169
+ mouseover,
170
+ mouseout,
171
+ applyTransformer,
172
+ onAnchorTransformationEnd,
173
+ } = props;
174
+
175
+ const videoUrl = src || "";
176
+
177
+ // color corrections
178
+ const {
179
+ contrast = 1,
180
+ saturation = 1,
181
+ exposure = 1,
182
+ blurRadius = 0,
183
+ alpha = 1,
184
+ } = colorCorrection || {};
185
+
186
+ /** adjustment filter */
187
+ const adjustments = {
188
+ brightness: exposure,
189
+ contrast,
190
+ saturation,
191
+ alpha,
192
+ };
193
+
194
+ /** handle on tranformer onchange */
195
+ const handleOnTransformChange = React.useCallback(() => {
196
+ setIsDragging(true);
197
+ }, []);
198
+
199
+ // transformer to handle sprite transformation
200
+ const handleOnTransformEnd = React.useCallback(
201
+ (endData: TransformationEnd) => {
202
+ console.log("changeEnd", endData);
203
+ if (onAnchorTransformationEnd) {
204
+ console.log("running onAnchorTransformationEnd");
205
+ onAnchorTransformationEnd(endData);
206
+ }
207
+ },
208
+ []
209
+ );
210
+
211
+ /**Adding this alternative workaround to work with mov/mk4 video types */
212
+ const videoSrcElement = React.useMemo(() => {
213
+ const element = document.createElement("video");
214
+ element.src = src;
215
+ element.crossOrigin = "Anonymus";
216
+ element.autoplay = false;
217
+ element.currentTime = 0.0001;
218
+ return element;
219
+ }, [src]);
220
+
221
+ /** Adding custom event listners */
222
+ /** Event Listeneres */
223
+ useCustomEventListener(Events.PAUSE, (data) => {
224
+ console.log("pause event", data);
225
+ if (videoElement.current) {
226
+ const vid = videoElement.current;
227
+ const isVidPlaying =
228
+ vid.currentTime > 0 &&
229
+ !vid.paused &&
230
+ !vid.ended &&
231
+ vid.readyState > vid.HAVE_CURRENT_DATA;
232
+ if (isVidPlaying) videoElement.current.pause();
233
+ videoStateRef.current.isPlaying = false;
234
+ }
235
+ });
236
+
237
+ // /** stop video playing when gsapDragging is true */
238
+ React.useEffect(() => {
239
+ console.log("current", videoElement.current, gsapDragging);
240
+ if (videoElement.current) {
241
+ if (gsapDragging) {
242
+ videoElement.current.pause();
243
+ videoStateRef.current.isPlaying = false;
244
+ videoStateRef.current.isDragging = true;
245
+ } else {
246
+ videoStateRef.current.isDragging = false;
247
+ }
248
+ }
249
+ }, [gsapDragging]);
250
+
251
+ /** Gsap Start and Stop Events */
252
+ const gsapOnStart = (startAt: number) => {
253
+ if (videoElement.current) {
254
+ console.log("video gsapOnStart", playerTimeRef.current, gsapDragging);
255
+
256
+ // check the start and end times are between the playerTimeRef.current to start video;
257
+ if (
258
+ playerTimeRef.current >= startAt &&
259
+ playerTimeRef.current <= endAt &&
260
+ !gsapDragging
261
+ ) {
262
+ videoElement.current.currentTime =
263
+ Number(frameStartAt) || Number(startAt);
264
+ videoElement.current.play();
265
+ videoStateRef.current.isPlaying = true;
266
+ }
267
+ }
268
+ };
269
+
270
+ const gsapOnComplete = () => {
271
+ console.log("onComplete triggered");
272
+ if (videoElement.current) {
273
+ const vid = videoElement.current;
274
+ const isVidPlaying =
275
+ vid.currentTime > 0 &&
276
+ !vid.paused &&
277
+ !vid.ended &&
278
+ vid.readyState > vid.HAVE_CURRENT_DATA;
279
+ ///if (!isVidPlaying) videoElement.current.play();
280
+ if (isVidPlaying) videoElement.current.pause();
281
+ videoStateRef.current.isPlaying = false;
282
+ }
283
+ };
284
+
285
+ const onInterrupt = () => {
286
+ // console.log('interrupting', refId);
287
+ };
288
+
289
+ const onUpdate = () => {
290
+ if (videoElement.current) {
291
+ // console.log(
292
+ // "currenttime vs player reftime",
293
+ // videoElement.current.currentTime,
294
+ // playerTimeRef.current
295
+ // );
296
+ const absDiff = Math.abs(
297
+ videoElement.current.currentTime - playerTimeRef.current
298
+ );
299
+
300
+ const vid = videoElement.current;
301
+ const isVidPlaying =
302
+ vid.currentTime > 0 &&
303
+ !vid.paused &&
304
+ !vid.ended &&
305
+ vid.readyState > vid.HAVE_CURRENT_DATA;
306
+
307
+ if (videoStateRef.current.isDragging) {
308
+ console.log("video updating", playerTimeRef.current);
309
+ videoElement.current.currentTime = playerTimeRef.current;
310
+ videoElement.current.play();
311
+ setTimeout(() => {
312
+ videoStateRef.current.isPlaying = false;
313
+ if (videoElement.current) videoElement.current.pause();
314
+ }, 55);
315
+ videoStateRef.current.isPlaying = false;
316
+ } else if (!videoStateRef.current.isPlaying) {
317
+ // if (!isVidPlaying) videoElement.current.play();
318
+ // videoStateRef.current.isPlaying = true;
319
+ // let the video play and update current time
320
+ // videoElement.current.currentTime = playerTimeRef.current;
321
+ if (!isVidPlaying) videoElement.current.play();
322
+ videoStateRef.current.isPlaying = true;
323
+ } else if (absDiff > 0.3) {
324
+ // videoElement.current.currentTime = playerTimeRef.current;
325
+ // if (!isVidPlaying) videoElement.current.play();
326
+ // videoStateRef.current.isPlaying = true;
327
+ }
328
+ }
329
+ };
330
+
331
+ useEffect(() => {
332
+ let ctx = gsap.context(() => {});
333
+ if (containerRef.current && tl.current) {
334
+ const data = {
335
+ duration: Number(endAt) - Number(startAt),
336
+ onStart: gsapOnStart,
337
+ onComplete: gsapOnComplete,
338
+ onStartParams: [startAt],
339
+ onCompleteParams: [],
340
+ onInterrupt: onInterrupt,
341
+ onUpdate: onUpdate,
342
+ onUpdateParams: [],
343
+ };
344
+
345
+ const ease = getAnimByName(animation || "None");
346
+ ctx = gsap.context(() => {
347
+ if (!isEmpty(ease.from)) {
348
+ tl.current
349
+ .from(containerRef.current, { ...ease.from }, startAt)
350
+ .to(imgGroupRef.current, { alpha: 1, duration: 0.2 }, startAt)
351
+ .from(imgGroupRef.current, { ...data }, startAt)
352
+ .to(containerRef.current, { alpha: 0, duration: 0.2 }, endAt - 0.2);
353
+ } else if (!isEmpty(ease.to)) {
354
+ tl.current
355
+ .to(
356
+ containerRef.current,
357
+ { alpha: 1, duration: 0.2, ...ease.to },
358
+ startAt
359
+ )
360
+ .from(imgGroupRef.current, { ...data }, startAt)
361
+ .to(containerRef.current, { alpha: 0, duration: 0.2 }, endAt - 0.2);
362
+ } else if (!isEmpty(ease.fromTo)) {
363
+ tl.current
364
+ .fromTo(
365
+ containerRef.current,
366
+ ease.fromTo?.from,
367
+ ease.fromTo?.to,
368
+ startAt
369
+ )
370
+ .from(imgGroupRef.current, { ...data }, startAt)
371
+ .to(containerRef.current, { alpha: 0, duration: 0.2 }, endAt - 0.2);
372
+ } else {
373
+ tl.current
374
+ .to(containerRef.current, { alpha: 1, duration: 0.01 }, startAt)
375
+ .from(imgGroupRef.current, { ...data }, startAt)
376
+ .to(
377
+ containerRef.current,
378
+ { alpha: 0, duration: 0.1 },
379
+ Number(endAt) - Number(0.1)
380
+ );
381
+ }
382
+ });
383
+ }
384
+ return () => ctx.revert(); // cleanup!
385
+ }, [animation, startAt, endAt]);
386
+
387
+ React.useEffect(() => {
388
+ if (containerRef.current) {
389
+ setIsMounted(true);
390
+ }
391
+ }, []);
392
+
393
+ React.useEffect(() => {
394
+ if (videoElement.current) {
395
+ videoElement.current.muted = mute;
396
+ }
397
+ }, [mute]);
398
+
399
+ // stop playing video while isDragging and gsapDragging
400
+ React.useEffect(() => {
401
+ if (videoElement.current) {
402
+ const vid = videoElement.current;
403
+ const isVidPlaying =
404
+ vid.currentTime > 0 &&
405
+ !vid.paused &&
406
+ !vid.ended &&
407
+ vid.readyState > vid.HAVE_CURRENT_DATA;
408
+ if (isVidPlaying && (isDragging || gsapDragging)) {
409
+ videoElement.current.pause();
410
+ videoStateRef.current.isPlaying = false;
411
+ }
412
+ }
413
+ }, [isDragging, gsapDragging]);
414
+
415
+ // load // load meta // load seek through
416
+ React.useEffect(() => {
417
+ const minStartAt =
418
+ Math.round((Number(frameStartAt) + Number.EPSILON) * 100) / 100;
419
+ const onload = function () {
420
+ if (videoElement.current) {
421
+ videoElement.current.currentTime = minStartAt;
422
+ }
423
+ };
424
+
425
+ const onEnd = function () {
426
+ //dispatchState({ isPlaying: false });
427
+ if (videoElement.current) {
428
+ const vid = videoElement.current;
429
+ const isVidPlaying =
430
+ vid.currentTime > 0 &&
431
+ !vid.paused &&
432
+ !vid.ended &&
433
+ vid.readyState > vid.HAVE_CURRENT_DATA;
434
+
435
+ if (isVidPlaying) {
436
+ videoElement.current.pause();
437
+ }
438
+ }
439
+ setVideoState({ isWaiting: false, isStalled: false });
440
+ };
441
+
442
+ const onLoadStart = function () {
443
+ //dispatchState({ isWaiting: true, isStalled: false });
444
+ if (videoElement.current) {
445
+ videoElement.current.pause();
446
+ }
447
+ setVideoState({ isWaiting: true, isStalled: false });
448
+ };
449
+
450
+ const onCanPlayThrough = function () {
451
+ //dispatchState({ isWaiting: false, isStalled: false });
452
+ setVideoState({ isWaiting: false, isStalled: false });
453
+ };
454
+
455
+ const onStalled = function () {
456
+ //dispatchState({ isStalled: true });
457
+ setVideoState({ isWaiting: false, isStalled: true });
458
+ };
459
+
460
+ // create a new Sprite using the video texture (yes it's that easy)
461
+ const stAt =
462
+ Math.round((Number(frameStartAt) + Number.EPSILON) * 100) / 100;
463
+ const endAt = Math.round((Number(frameEndAt) + Number.EPSILON) * 100) / 100;
464
+ const urlWithTimestamp = `${videoUrl}#t=${stAt},${endAt}`;
465
+ /// const urlWithQuery = `${videoUrl}?t=${stAt},${endAt}`;
466
+
467
+ console.log("urlTimestap", urlWithTimestamp);
468
+ /// const texture =
469
+ PIXI.Texture.fromLoader(videoSrcElement, urlWithTimestamp, uniqueId, {
470
+ pixiIdPrefix: uniqueId,
471
+ resourceOptions: {
472
+ autoPlay: false,
473
+ crossorigin: "Anonymus",
474
+ updateFPS: 30,
475
+ },
476
+ }).then((texture) => {
477
+ if (!texture) return;
478
+ // texture.baseTexture.resource.source.currentSrc = urlWithTimestamp;
479
+ setVideoTexture(texture);
480
+ // @ts-ignore
481
+ console.log(texture.baseTexture.resource.source);
482
+ // @ts-ignore
483
+ videoElement.current = texture.baseTexture.resource.source;
484
+ // @ts-ignore
485
+ videoElement.current.id = uniqueId;
486
+ // @ts-ignore
487
+ videoElement.current.addEventListener("loadedmetadata", onload);
488
+ // @ts-ignore
489
+ videoElement.current.addEventListener("ended", onEnd);
490
+ // @ts-ignore
491
+ videoElement.current.addEventListener("loadstart", onLoadStart);
492
+ // @ts-ignore
493
+ videoElement.current.addEventListener("canplaythrough", onCanPlayThrough);
494
+ // @ts-ignore
495
+ videoElement.current.addEventListener("stalled", onStalled);
496
+ });
497
+
498
+ return () => {
499
+ // @ts-ignore
500
+ videoElement.current.removeEventListener("loadedmetadata", onload);
501
+ // @ts-ignore
502
+ videoElement.current.removeEventListener("ended", onEnd);
503
+ // @ts-ignore
504
+ videoElement.current.removeEventListener("loadstart", onLoadStart);
505
+ // @ts-ignore
506
+ videoElement.current.removeEventListener(
507
+ "canplaythrough",
508
+ onCanPlayThrough
509
+ );
510
+ // @ts-ignore
511
+ videoElement.current.removeEventListener("stalled", onStalled);
512
+ };
513
+ // create a new Sprite using the video texture (yes it's that easy)
514
+ // const videoSprite = new PIXI.Sprite(texture);
515
+ }, [videoUrl, uniqueId, frameStartAt, frameEndAt, videoSrcElement]);
516
+
517
+ return (
518
+ // @ts-ignore
519
+ <Container ref={parentNode}>
520
+ {/* @ts-ignore */}
521
+ {/* @ts-ignore */}
522
+ <Container
523
+ ref={containerRef}
524
+ alpha={initialAlpha}
525
+ position={[x, y]}
526
+ pivot={[x, y]}
527
+ width={width}
528
+ height={height}
529
+ >
530
+ {colorCorrection && colorCorrection.enabled ? (
531
+ <Filters
532
+ scale={1}
533
+ blur={{ blur: blurRadius, quality: 4 }}
534
+ adjust={adjustments}
535
+ apply={({ matrix }: { matrix: any }) => {
536
+ if (effect === "BlackAndWhite") {
537
+ matrix.desaturate();
538
+ } else if (effect === "Sepia") {
539
+ matrix.sepia();
540
+ } else if (effect === "RetroVintage") {
541
+ matrix.negative();
542
+ } else if (effect === "NightVision") {
543
+ matrix.negative();
544
+ } else if (effect === "Normal") {
545
+ matrix.reset();
546
+ }
547
+ }}
548
+ matrix={{
549
+ enabled: true,
550
+ // @ts-ignore
551
+ matrix: CYAN,
552
+ }}
553
+ >
554
+ {/* @ts-ignore */}
555
+ <Container ref={imgGroupRef}>
556
+ {videoTexture && (
557
+ <Sprite
558
+ texture={videoTexture}
559
+ width={width}
560
+ height={height}
561
+ anchor={0.5}
562
+ x={x}
563
+ y={y}
564
+ {...(!locked &&
565
+ !isDragging && {
566
+ interactive: true,
567
+ buttonMode: true,
568
+ pointerdown: pointerdown,
569
+ pointerover: pointerover,
570
+ pointerout: mouseout,
571
+ mousedown: mousedown,
572
+ mouseover: mouseover,
573
+ mouseout: mouseout,
574
+ mouseup: mouseup,
575
+ pointerup: pointerup,
576
+ })}
577
+ ref={imageRef}
578
+ scale={scale}
579
+ rotation={rotation}
580
+ />
581
+ )}
582
+ </Container>
583
+ </Filters>
584
+ ) : (
585
+ // @ts-ignore
586
+ <Container ref={imgGroupRef}>
587
+ {videoTexture && (
588
+ <Sprite
589
+ texture={videoTexture}
590
+ width={width}
591
+ height={height}
592
+ anchor={0.5}
593
+ x={x}
594
+ y={y}
595
+ {...(!locked &&
596
+ !isDragging && {
597
+ interactive: true,
598
+ buttonMode: true,
599
+ pointerdown: pointerdown,
600
+ pointerover: pointerover,
601
+ pointerout: mouseout,
602
+ mousedown: mousedown,
603
+ mouseover: mouseover,
604
+ mouseout: mouseout,
605
+ mouseup: mouseup,
606
+ pointerup: pointerup,
607
+ })}
608
+ ref={imageRef}
609
+ scale={scale}
610
+ rotation={rotation}
611
+ />
612
+ )}
613
+ </Container>
614
+ )}
615
+ </Container>
616
+ {applyTransformer && (
617
+ <PixiTransformer
618
+ pixiTransformerRef={transformerRef}
619
+ imageRef={containerRef}
620
+ isMounted={isMounted}
621
+ transformCommit={handleOnTransformEnd}
622
+ transformChange={handleOnTransformChange}
623
+ mouseoverEvent={setIsMouseOverTransformer}
624
+ uniqueId={uniqueId}
625
+ />
626
+ )}
627
+ </Container>
628
+ );
629
+ };
630
+
631
+ export default PixiVideoSprite;