reacthub-pixitweenjs 0.2.3 → 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.
- package/.storybook/{main.js → main.ts} +9 -1
- package/.storybook/{preview.jsx → preview.tsx} +3 -7
- package/CHANGELOG.md +40 -0
- package/README.md +21 -2
- package/build-storybook.log +94 -0
- package/index.html +1 -1
- package/package.json +68 -36
- package/src/App.tsx +29 -0
- package/src/components/PixiAnimatedSprite/PixiAnimatedSprite.tsx +51 -0
- package/src/components/PixiAnimatedSprite/index.ts +2 -0
- package/src/components/PixiAudioSprite/PixiAudioSprite.stories.tsx +61 -0
- package/src/components/PixiAudioSprite/PixiAudioSprite.tsx +212 -0
- package/src/components/PixiAudioSprite/index.ts +1 -0
- package/src/components/PixiGifSprite/PixiGifSprite.stories.tsx +135 -0
- package/src/components/PixiGifSprite/PixiGifSprite.tsx +451 -0
- package/src/components/PixiGifSprite/index.ts +2 -0
- package/src/{stories/PixiImageSprite/PixiImageSprite.stories.js → components/PixiImageSprite/PixiImageSprite.stories.tsx} +36 -8
- package/src/components/PixiImageSprite/PixiImageSprite.tsx +340 -0
- package/src/components/PixiImageSprite/index.ts +1 -0
- package/src/components/PixiSVGSprite/PixiSvgPathSprite.stories.tsx +137 -0
- package/src/components/PixiSVGSprite/PixiSvgPathSprite.tsx +378 -0
- package/src/components/PixiSVGSprite/index.ts +1 -0
- package/src/components/PixiVideoSprite/PixiVideoSprite.stories.tsx +147 -0
- package/src/components/PixiVideoSprite/PixiVideoSprite.tsx +684 -0
- package/src/components/PixiVideoSprite/PixiVideoSpriteBackup.txt +755 -0
- package/src/components/PixiVideoSprite/index.ts +1 -0
- package/src/declare.module.ts +5 -0
- package/src/hooks/usePixiTransformer.tsx +168 -0
- package/src/index.ts +3 -0
- package/src/providers/GsapPixieContextProvider.tsx +251 -0
- package/src/providers/index.ts +1 -0
- package/src/reacthub-react-bindings.d.ts +27 -0
- package/src/types/transformation.tsx +13 -0
- package/src/utils/AppStateProvider.tsx +59 -0
- package/src/utils/AppStateStage.tsx +27 -0
- package/src/utils/AppWrapper.tsx +43 -0
- package/src/utils/ContextBridge.tsx +25 -0
- package/src/{providers/GsapAnim.jsx → utils/GsapAnim.tsx} +35 -4
- package/src/utils/PixiStage.tsx +29 -0
- package/src/utils/PixiTransformer.tsx +100 -0
- package/src/utils/VideoSeekBar.tsx +129 -0
- package/src/utils/useDebounce.tsx +15 -0
- package/src/utils/useDeepEffect.tsx +23 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +37 -0
- package/tsconfig.node.json +10 -0
- package/{vite.config.js → vite.config.ts} +4 -2
- package/vitest.config.ts +11 -0
- package/src/App.jsx +0 -35
- package/src/index.js +0 -3
- package/src/providers/ContextBridge.jsx +0 -67
- package/src/providers/GsapPixieContextProvider.jsx +0 -162
- package/src/providers/VideoSeekBar.jsx +0 -186
- package/src/providers/index.js +0 -3
- package/src/stories/PixiImageSprite/PixiImageSprite.jsx +0 -318
- package/src/stories/PixiImageSprite/index.js +0 -1
- /package/src/{main.jsx → main.tsx} +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useContext, useEffect, useRef } from "react";
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import PropTypes from "prop-types";
|
|
5
|
+
import {
|
|
6
|
+
GsapPixieContext,
|
|
7
|
+
Events,
|
|
8
|
+
} from "../../providers/GsapPixieContextProvider";
|
|
9
|
+
import { Container, useApp } from "@pixi/react";
|
|
10
|
+
import { useCustomEventListener } from "react-custom-events";
|
|
11
|
+
import gsap from "gsap";
|
|
12
|
+
import { Sound } from "@pixi/sound";
|
|
13
|
+
import * as PIXI from "pixi.js";
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
import isEmpty from "lodash/isEmpty";
|
|
16
|
+
|
|
17
|
+
type PixiAudioSpriteProps = {
|
|
18
|
+
uniqueId: string;
|
|
19
|
+
src: string;
|
|
20
|
+
startAt: number;
|
|
21
|
+
endAt: number;
|
|
22
|
+
mute: boolean;
|
|
23
|
+
speed: number;
|
|
24
|
+
};
|
|
25
|
+
interface AudioState {
|
|
26
|
+
isPlaying: boolean;
|
|
27
|
+
progress: number;
|
|
28
|
+
speed: number;
|
|
29
|
+
mute: boolean;
|
|
30
|
+
isWaiting: boolean;
|
|
31
|
+
loaded: boolean;
|
|
32
|
+
size: { width: number; height: number };
|
|
33
|
+
isDragging: boolean;
|
|
34
|
+
completed?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const PixiAudioSprite: React.FC<PixiAudioSpriteProps> = (props) => {
|
|
38
|
+
const initialState: AudioState = {
|
|
39
|
+
isPlaying: false,
|
|
40
|
+
progress: 0,
|
|
41
|
+
speed: 1,
|
|
42
|
+
mute: false,
|
|
43
|
+
isWaiting: false,
|
|
44
|
+
loaded: false,
|
|
45
|
+
size: { width: 50, height: 50 },
|
|
46
|
+
isDragging: false,
|
|
47
|
+
};
|
|
48
|
+
//// State
|
|
49
|
+
const [isMounted, setIsMounted] = React.useState(false);
|
|
50
|
+
|
|
51
|
+
const audioStateRef = useRef<AudioState>(initialState);
|
|
52
|
+
|
|
53
|
+
console.log("allProps", props);
|
|
54
|
+
//// Refs
|
|
55
|
+
const containerRef = useRef<PIXI.Container>(null);
|
|
56
|
+
const imgGroupRef = useRef<PIXI.Container>(null);
|
|
57
|
+
|
|
58
|
+
//// Context
|
|
59
|
+
//// Context
|
|
60
|
+
const { tl, playerTimeRef } = useContext(GsapPixieContext);
|
|
61
|
+
|
|
62
|
+
/// 1001
|
|
63
|
+
// console.log("contxt Values", tl);
|
|
64
|
+
const { uniqueId, src, startAt, endAt, mute, speed, ...restProps } = props;
|
|
65
|
+
|
|
66
|
+
const app = useApp();
|
|
67
|
+
const audioContainerRef = React.useRef<Sound>(null);
|
|
68
|
+
|
|
69
|
+
/** Adding custom event listners */
|
|
70
|
+
/** Event Listeneres */
|
|
71
|
+
useCustomEventListener(Events.PAUSE, () => {
|
|
72
|
+
console.log("pause event");
|
|
73
|
+
if (containerRef.current) {
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
audioContainerRef.current?.pause();
|
|
76
|
+
audioStateRef.current.isPlaying = false;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const gsapOnStart = (startAt: number) => {
|
|
81
|
+
if (containerRef.current) {
|
|
82
|
+
console.log("audio gsapOnStart", startAt);
|
|
83
|
+
if (playerTimeRef.current >= startAt && playerTimeRef.current <= endAt) {
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
audioContainerRef.current?.play({
|
|
86
|
+
volume: mute ? 0 : 1,
|
|
87
|
+
start: startAt,
|
|
88
|
+
end: endAt,
|
|
89
|
+
speed: speed || 1,
|
|
90
|
+
});
|
|
91
|
+
audioStateRef.current.isPlaying = true;
|
|
92
|
+
audioStateRef.current.completed = false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const gsapOnPause = (startAt: number) => {
|
|
98
|
+
if (containerRef.current) {
|
|
99
|
+
console.log("audio gsapOnStart", startAt);
|
|
100
|
+
// @ts-ignore
|
|
101
|
+
audioContainerRef.current?.pause();
|
|
102
|
+
audioStateRef.current.isPlaying = false;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const gsapOnComplete = () => {
|
|
107
|
+
if (containerRef.current) {
|
|
108
|
+
console.log("audio gsapOnStart", startAt);
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
audioContainerRef.current?.stop();
|
|
111
|
+
audioStateRef.current.isPlaying = false;
|
|
112
|
+
audioStateRef.current.completed = true;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const gsapOnUpdate = (startAt: number) => {
|
|
117
|
+
if (
|
|
118
|
+
containerRef.current &&
|
|
119
|
+
!audioStateRef.current.isPlaying &&
|
|
120
|
+
!audioStateRef.current.completed
|
|
121
|
+
) {
|
|
122
|
+
console.log("audio gsapOnUpdate", startAt);
|
|
123
|
+
// @ts-ignore
|
|
124
|
+
audioContainerRef.current?.refresh();
|
|
125
|
+
// @ts-ignore
|
|
126
|
+
audioContainerRef.current?.refreshPaused();
|
|
127
|
+
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
audioContainerRef.current?.resume();
|
|
130
|
+
audioStateRef.current.isPlaying = true;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const onInterrupt = (startAt: number) => {};
|
|
135
|
+
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
let ctx = gsap.context(() => {});
|
|
138
|
+
if (containerRef.current && tl.current) {
|
|
139
|
+
const data = {
|
|
140
|
+
duration: Number(endAt) - Number(startAt),
|
|
141
|
+
onStart: gsapOnStart,
|
|
142
|
+
onComplete: gsapOnComplete,
|
|
143
|
+
onStartParams: [startAt],
|
|
144
|
+
onCompleteParams: [],
|
|
145
|
+
onInterrupt: onInterrupt,
|
|
146
|
+
onUpdate: gsapOnUpdate,
|
|
147
|
+
onUpdateParams: [],
|
|
148
|
+
};
|
|
149
|
+
ctx = gsap.context(() => {
|
|
150
|
+
tl.current
|
|
151
|
+
.to(containerRef.current, { alpha: 1, duration: 0.01 }, startAt)
|
|
152
|
+
.from(imgGroupRef.current, { ...data }, startAt)
|
|
153
|
+
.to(
|
|
154
|
+
containerRef.current,
|
|
155
|
+
{ alpha: 0, duration: 0.1 },
|
|
156
|
+
Number(endAt) - Number(0.1)
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return () => ctx.revert(); // cleanup!
|
|
161
|
+
}, [startAt, endAt]);
|
|
162
|
+
|
|
163
|
+
React.useEffect(() => {
|
|
164
|
+
if (containerRef.current) {
|
|
165
|
+
setIsMounted(true);
|
|
166
|
+
}
|
|
167
|
+
}, []);
|
|
168
|
+
|
|
169
|
+
React.useEffect(() => {
|
|
170
|
+
if (containerRef.current && audioContainerRef.current) {
|
|
171
|
+
console.log("soundref", audioContainerRef.current);
|
|
172
|
+
// @ts-ignore
|
|
173
|
+
audioStateRef.current.mute = mute;
|
|
174
|
+
audioStateRef.current.speed = speed;
|
|
175
|
+
console.log("containerAudio", audioContainerRef.current.volume);
|
|
176
|
+
audioContainerRef.current.volume = mute ? 0 : 1;
|
|
177
|
+
}
|
|
178
|
+
}, [mute, speed]);
|
|
179
|
+
|
|
180
|
+
const onSoundLoaded = React.useCallback(
|
|
181
|
+
(err: any, sound: Sound | undefined) => {
|
|
182
|
+
//@ts-ignore
|
|
183
|
+
audioContainerRef.current = sound;
|
|
184
|
+
audioStateRef.current.loaded = true;
|
|
185
|
+
// const instance = sound.play();
|
|
186
|
+
},
|
|
187
|
+
[]
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
React.useEffect(() => {
|
|
191
|
+
if (!isEmpty(src)) {
|
|
192
|
+
// @pixi/sound package usage
|
|
193
|
+
//@ts-ignore
|
|
194
|
+
audioContainerRef.current = Sound.from({
|
|
195
|
+
url: src,
|
|
196
|
+
preload: true,
|
|
197
|
+
singleInstance: true,
|
|
198
|
+
loaded: onSoundLoaded,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return () => {
|
|
202
|
+
// app.loader.reset();
|
|
203
|
+
};
|
|
204
|
+
}, [uniqueId, src, onSoundLoaded]);
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
<Container ref={containerRef}></Container>
|
|
209
|
+
);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
export default PixiAudioSprite;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PixiAudioSprite } from "./PixiAudioSprite";
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { PixiGifSprite } from ".";
|
|
3
|
+
import { AppStateContextProvider } from "../../utils/AppStateProvider";
|
|
4
|
+
|
|
5
|
+
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "Components/GifSprite",
|
|
8
|
+
component: PixiGifSprite,
|
|
9
|
+
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
argTypes: {
|
|
12
|
+
uniqueId: {
|
|
13
|
+
control: "text",
|
|
14
|
+
description: "uniqueId of the sprite",
|
|
15
|
+
},
|
|
16
|
+
src: {
|
|
17
|
+
control: "text",
|
|
18
|
+
description: "source of the image",
|
|
19
|
+
},
|
|
20
|
+
transformation: {
|
|
21
|
+
control: "object",
|
|
22
|
+
description: "transformation of the sprite",
|
|
23
|
+
x: { control: "number", description: "x position of the sprite" },
|
|
24
|
+
y: { control: "number", description: "y position of the sprite" },
|
|
25
|
+
width: { control: "number", description: "width of the sprite" },
|
|
26
|
+
height: { control: "number", description: "height of the sprite" },
|
|
27
|
+
anchor: { control: "number", description: "anchor of the sprite" },
|
|
28
|
+
rotation: { control: "number", description: "rotation of the sprite" },
|
|
29
|
+
alpha: {
|
|
30
|
+
control: "number",
|
|
31
|
+
min: 0,
|
|
32
|
+
max: 1,
|
|
33
|
+
description: "alpha of the sprite",
|
|
34
|
+
},
|
|
35
|
+
scale: { control: "number", description: "scale of the sprite" },
|
|
36
|
+
tint: { control: "number", description: "tint of the sprite" },
|
|
37
|
+
blendMode: { control: "number", description: "blendMode of the sprite" },
|
|
38
|
+
colorCorrection: {
|
|
39
|
+
control: "object",
|
|
40
|
+
description: "colorCorrection of the sprite",
|
|
41
|
+
brightness: {
|
|
42
|
+
control: "number",
|
|
43
|
+
description: "brightness of the sprite",
|
|
44
|
+
},
|
|
45
|
+
contrast: { control: "number", description: "contrast of the sprite" },
|
|
46
|
+
saturation: {
|
|
47
|
+
control: "number",
|
|
48
|
+
description: "saturation of the sprite",
|
|
49
|
+
},
|
|
50
|
+
alpha: { control: "number", description: "alpha of the sprite" },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
applyTransformer: { control: "boolean", description: "applyTransformer" },
|
|
54
|
+
startAt: { control: "number", description: "startAt" },
|
|
55
|
+
endAt: { control: "number", description: "endAt" },
|
|
56
|
+
initialAlpha: {
|
|
57
|
+
control: "number",
|
|
58
|
+
min: 0,
|
|
59
|
+
max: 1,
|
|
60
|
+
description: "sprite initial alpha value (default 1)",
|
|
61
|
+
},
|
|
62
|
+
onAnchorTransformationEnd: {
|
|
63
|
+
action: "onAnchorTransformationEnd",
|
|
64
|
+
description:
|
|
65
|
+
"on transforamtion end the event is fire callback with latest sprite transformation properties.",
|
|
66
|
+
},
|
|
67
|
+
pointerdown: {
|
|
68
|
+
action: "pointerdown",
|
|
69
|
+
description: "pointerdown event",
|
|
70
|
+
},
|
|
71
|
+
pointerup: {
|
|
72
|
+
action: "pointerup",
|
|
73
|
+
description: "pointerup event",
|
|
74
|
+
},
|
|
75
|
+
mousedown: {
|
|
76
|
+
action: "mousedown",
|
|
77
|
+
description: "mousedown event",
|
|
78
|
+
},
|
|
79
|
+
mouseup: {
|
|
80
|
+
action: "mouseup",
|
|
81
|
+
description: "mouseup event",
|
|
82
|
+
},
|
|
83
|
+
pointerover: {
|
|
84
|
+
action: "pointerover",
|
|
85
|
+
description: "pointerover event",
|
|
86
|
+
},
|
|
87
|
+
mouseover: {
|
|
88
|
+
action: "mouseover",
|
|
89
|
+
description: "mouseover event",
|
|
90
|
+
},
|
|
91
|
+
mouseout: {
|
|
92
|
+
action: "mouseout",
|
|
93
|
+
description: "mouseout event",
|
|
94
|
+
},
|
|
95
|
+
pointerout: {
|
|
96
|
+
action: "pointerout",
|
|
97
|
+
description: "pointerout event",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
} satisfies Meta<typeof PixiGifSprite>;
|
|
101
|
+
|
|
102
|
+
export default meta;
|
|
103
|
+
type Story = StoryObj<typeof meta>;
|
|
104
|
+
|
|
105
|
+
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
106
|
+
export const Normal: Story = {
|
|
107
|
+
render: (args: any) => (
|
|
108
|
+
<AppStateContextProvider {...args}>
|
|
109
|
+
<PixiGifSprite {...args} />
|
|
110
|
+
</AppStateContextProvider>
|
|
111
|
+
),
|
|
112
|
+
args: {
|
|
113
|
+
uniqueId: "suryaGify001", // uniqueId of the sprite
|
|
114
|
+
src: "https://media.giphy.com/media/5VKbvrjxpVJCM/giphy.gif",
|
|
115
|
+
locked: false,
|
|
116
|
+
loop: false,
|
|
117
|
+
transformation: {
|
|
118
|
+
x: 100,
|
|
119
|
+
y: 100,
|
|
120
|
+
width: 150,
|
|
121
|
+
height: 150,
|
|
122
|
+
anchor: 0.5,
|
|
123
|
+
rotation: 0,
|
|
124
|
+
alpha: 1,
|
|
125
|
+
scale: 1,
|
|
126
|
+
tint: 0xffffff,
|
|
127
|
+
blendMode: 0,
|
|
128
|
+
colorCorrection: {},
|
|
129
|
+
},
|
|
130
|
+
applyTransformer: false,
|
|
131
|
+
startAt: 0,
|
|
132
|
+
endAt: 4,
|
|
133
|
+
initialAlpha: 1,
|
|
134
|
+
},
|
|
135
|
+
};
|