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.
- package/CHANGELOG.md +14 -0
- package/build-storybook.log +79 -476
- package/package.json +26 -29
- 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/components/PixiImageSprite/PixiImageSprite.stories.tsx +11 -0
- package/src/components/PixiImageSprite/PixiImageSprite.tsx +30 -36
- 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/providers/GsapPixieContextProvider.tsx +94 -8
- package/src/reacthub-react-bindings.d.ts +27 -0
- package/src/utils/AppStateProvider.tsx +15 -26
- package/src/utils/AppStateStage.tsx +1 -1
- package/src/utils/PixiStage.tsx +1 -5
- package/src/utils/PixiTransformer.tsx +100 -0
- package/src/utils/VideoSeekBar.tsx +34 -23
- package/src/utils/useDebounce.tsx +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PixiVideoSprite } from "./PixiVideoSprite";
|
|
@@ -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
|
|
@@ -38,6 +49,10 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
38
49
|
}) => {
|
|
39
50
|
const [play, setPlay] = useState<boolean>(false);
|
|
40
51
|
const [frameNumber, setFrameNumber] = useState<number>(0);
|
|
52
|
+
const [isDragging, setIsDragging] = useState<boolean>(false);
|
|
53
|
+
const [internalDuration, setInternalDuration] = useState<number>(0);
|
|
54
|
+
const [totalDuration, setTotalDuration] = useState<number>(0);
|
|
55
|
+
const delayedDuration = useDebounce(internalDuration, 600);
|
|
41
56
|
|
|
42
57
|
const tl = useRef<any>();
|
|
43
58
|
const gsapCtx = useRef<any>();
|
|
@@ -60,6 +75,14 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
60
75
|
return () => gsapCtx.current.revert();
|
|
61
76
|
}, []);
|
|
62
77
|
|
|
78
|
+
gsap.ticker.add((time, deltaTime, frame) => {
|
|
79
|
+
// console.log("timeframe", time, deltaTime, frame);
|
|
80
|
+
// setFrameNumber(frame);
|
|
81
|
+
if (tl.current && getTimelineDuration) {
|
|
82
|
+
setInternalDuration(getTimelineDuration());
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
63
86
|
const onUpdate = useCallback(() => {
|
|
64
87
|
/// console.log("update event callback");
|
|
65
88
|
const timeline = tl.current;
|
|
@@ -73,16 +96,51 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
73
96
|
playerTimeRef.current = now;
|
|
74
97
|
}, []);
|
|
75
98
|
|
|
99
|
+
// set the total duration based on the delayed duration value
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
setTotalDuration(delayedDuration);
|
|
102
|
+
}, [delayedDuration]);
|
|
103
|
+
|
|
76
104
|
useEffect(() => {
|
|
77
105
|
const timeline = tl.current;
|
|
78
106
|
timeline
|
|
107
|
+
.eventCallback("onStart", function () {
|
|
108
|
+
// console.log("onstart", timeline.progress());
|
|
109
|
+
// setPlay(true);
|
|
110
|
+
// onUpdate();
|
|
111
|
+
})
|
|
112
|
+
.eventCallback("onInterrupt", function () {
|
|
113
|
+
/// console.log("onInterrupt", timeline.progress());
|
|
114
|
+
setPlay(false);
|
|
115
|
+
onUpdate();
|
|
116
|
+
})
|
|
79
117
|
.eventCallback("onUpdate", function () {
|
|
80
118
|
/// console.log("onupdate", timeline.progress());
|
|
81
119
|
onUpdate();
|
|
82
120
|
})
|
|
121
|
+
// .eventCallback("onRepeat", function () {
|
|
122
|
+
// /// console.log("onrepeat", timeline.progress());
|
|
123
|
+
// onUpdate();
|
|
124
|
+
// })
|
|
125
|
+
// .eventCallback("onReverseComplete", function () {
|
|
126
|
+
// /// console.log("onReverseComplete", timeline.progress());
|
|
127
|
+
// onUpdate();
|
|
128
|
+
// })
|
|
129
|
+
// write a pause event
|
|
130
|
+
.eventCallback("onPause", function () {
|
|
131
|
+
console.log("onPause", timeline.progress());
|
|
132
|
+
setPlay(false);
|
|
133
|
+
onUpdate();
|
|
134
|
+
})
|
|
135
|
+
.eventCallback("onResume", function () {
|
|
136
|
+
console.log("onResume", timeline.progress());
|
|
137
|
+
setPlay(true);
|
|
138
|
+
onUpdate();
|
|
139
|
+
})
|
|
83
140
|
.eventCallback("onComplete", function () {
|
|
84
|
-
timeline.seek(0
|
|
141
|
+
timeline.seek(0);
|
|
85
142
|
timeline.pause();
|
|
143
|
+
setPlay(false);
|
|
86
144
|
onUpdate();
|
|
87
145
|
});
|
|
88
146
|
}, []);
|
|
@@ -110,39 +168,63 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
110
168
|
const handleRestart = useCallback(() => {
|
|
111
169
|
const timeline = tl.current;
|
|
112
170
|
timeline.restart();
|
|
171
|
+
setPlay(true);
|
|
113
172
|
}, []);
|
|
114
173
|
|
|
115
174
|
const handleRepeat = useCallback(() => {
|
|
116
175
|
const timeline = tl.current;
|
|
117
|
-
|
|
118
176
|
timeline.repeat(1);
|
|
119
177
|
timeline.restart();
|
|
178
|
+
// setPlay(true);
|
|
120
179
|
}, []);
|
|
121
180
|
|
|
122
|
-
const handleSeek = useCallback(() => {
|
|
181
|
+
const handleSeek = useCallback((value: number) => {
|
|
123
182
|
const timeline = tl.current;
|
|
124
|
-
timeline.seek(
|
|
183
|
+
timeline.seek(value);
|
|
125
184
|
}, []);
|
|
126
185
|
|
|
127
|
-
const
|
|
186
|
+
const handleSeekTest = useCallback(() => {
|
|
128
187
|
const timeline = tl.current;
|
|
188
|
+
timeline.seek(4);
|
|
189
|
+
}, []);
|
|
129
190
|
|
|
191
|
+
const setTimelineDuration = useCallback(() => {
|
|
192
|
+
const timeline = tl.current;
|
|
130
193
|
timeline.totalDuration(3);
|
|
131
194
|
}, []);
|
|
132
195
|
|
|
133
|
-
const
|
|
196
|
+
const getTimelineDuration = useCallback(() => {
|
|
134
197
|
const timeline = tl.current;
|
|
198
|
+
if (!timeline) return 0;
|
|
199
|
+
return timeline.totalDuration();
|
|
200
|
+
}, []);
|
|
135
201
|
|
|
202
|
+
const handlePause = () => {
|
|
203
|
+
const timeline = tl.current;
|
|
136
204
|
timeline.pause();
|
|
137
205
|
emitCustomEvent(Events.PAUSE);
|
|
206
|
+
setPlay(false);
|
|
138
207
|
};
|
|
139
208
|
|
|
140
209
|
const handlePlay = () => {
|
|
141
210
|
const timeline = tl.current;
|
|
211
|
+
setPlay(true);
|
|
142
212
|
timeline.resume();
|
|
143
213
|
emitCustomEvent(Events.RESUME);
|
|
144
214
|
};
|
|
145
215
|
|
|
216
|
+
/** Event listener dragging */
|
|
217
|
+
useCustomEventListener(Events.DRAGGING_START, (time) => {
|
|
218
|
+
console.log("dragging start");
|
|
219
|
+
setIsDragging(true);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
useCustomEventListener(Events.DRAGGING_END, (time) => {
|
|
223
|
+
setIsDragging(false);
|
|
224
|
+
console.log("dragging end");
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
console.log("set play updated", play);
|
|
146
228
|
return (
|
|
147
229
|
<GsapPixieContext.Provider
|
|
148
230
|
value={{
|
|
@@ -152,9 +234,13 @@ const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
|
152
234
|
handlePause,
|
|
153
235
|
handleReset,
|
|
154
236
|
handleSeek,
|
|
237
|
+
handleSeekTest,
|
|
155
238
|
handleRestart,
|
|
156
239
|
handleRepeat,
|
|
157
240
|
playerTimeRef,
|
|
241
|
+
play,
|
|
242
|
+
totalDuration,
|
|
243
|
+
isDragging,
|
|
158
244
|
}}
|
|
159
245
|
>
|
|
160
246
|
{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
|
+
}
|
|
@@ -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,27 +15,30 @@ 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
|
-
|
|
39
|
-
transformation: { [key: string]: unknown };
|
|
40
|
-
}) => {
|
|
28
|
+
(data: TransformationEnd) => {
|
|
29
|
+
console.log("onAnchorTransformationEnd", data);
|
|
41
30
|
const { uniqueId, transformation } = data;
|
|
42
31
|
const newAppState = {
|
|
43
|
-
...
|
|
32
|
+
...appStateRef.current,
|
|
44
33
|
transformation: {
|
|
45
|
-
...
|
|
34
|
+
...appStateRef.current?.transformation,
|
|
46
35
|
...transformation,
|
|
47
36
|
},
|
|
48
37
|
};
|
|
38
|
+
console.log("saving state", newAppState);
|
|
49
39
|
setAppState(newAppState);
|
|
50
40
|
},
|
|
51
|
-
[
|
|
41
|
+
[]
|
|
52
42
|
);
|
|
53
43
|
|
|
54
44
|
const onMouseOverSprite = React.useCallback((data: unknown) => {}, []);
|
|
@@ -56,15 +46,14 @@ export const AppStateContextProvider: React.FC<
|
|
|
56
46
|
const onClickSprite = React.useCallback((data: unknown) => {}, []);
|
|
57
47
|
|
|
58
48
|
return (
|
|
59
|
-
|
|
60
|
-
|
|
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,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import ContextBridge from "./ContextBridge";
|
|
3
|
-
import { AppStateContext } from "
|
|
3
|
+
import { AppStateContext } from "./AppStateProvider";
|
|
4
4
|
import { Container as PixiContainer } from "@pixi/react";
|
|
5
5
|
|
|
6
6
|
interface AppStateStageProps {
|
package/src/utils/PixiStage.tsx
CHANGED
|
@@ -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
|
-
|
|
22
|
-
{/* @ts-ignore */}
|
|
23
|
-
{children}
|
|
24
|
-
</AppStateContextProvider>
|
|
20
|
+
{children}
|
|
25
21
|
</PixiStage>
|
|
26
22
|
)}
|
|
27
23
|
>
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
uniqueId?: string;
|
|
14
|
+
};
|
|
15
|
+
const PixiTransformer = ({
|
|
16
|
+
pixiTransformerRef,
|
|
17
|
+
imageRef,
|
|
18
|
+
isMounted,
|
|
19
|
+
transformCommit,
|
|
20
|
+
transformChange,
|
|
21
|
+
mouseoverEvent,
|
|
22
|
+
uniqueId = "",
|
|
23
|
+
}: PixiTransformerProps) => {
|
|
24
|
+
const colorYellow = PIXI.utils.string2hex("#F3C409");
|
|
25
|
+
const anchorFill = PIXI.utils.string2hex("#F3C409");
|
|
26
|
+
|
|
27
|
+
const handleOnMouseOver = React.useCallback(() => {
|
|
28
|
+
if (mouseoverEvent) {
|
|
29
|
+
mouseoverEvent(true);
|
|
30
|
+
}
|
|
31
|
+
}, [mouseoverEvent]);
|
|
32
|
+
|
|
33
|
+
const handleOnMouseOut = React.useCallback(() => {
|
|
34
|
+
if (mouseoverEvent) {
|
|
35
|
+
mouseoverEvent(false);
|
|
36
|
+
}
|
|
37
|
+
}, [mouseoverEvent]);
|
|
38
|
+
|
|
39
|
+
const handleOnTransformCommit = React.useCallback(() => {
|
|
40
|
+
if (imageRef.current === null) return;
|
|
41
|
+
const x = imageRef.current.x;
|
|
42
|
+
const y = imageRef.current.y;
|
|
43
|
+
const width = imageRef.current.width;
|
|
44
|
+
const height = imageRef.current.height;
|
|
45
|
+
const rotate = imageRef.current.rotation;
|
|
46
|
+
const scale: [number, number] = [
|
|
47
|
+
imageRef.current.scale.x,
|
|
48
|
+
imageRef.current.scale.y,
|
|
49
|
+
];
|
|
50
|
+
if (transformCommit) {
|
|
51
|
+
transformCommit({
|
|
52
|
+
uniqueId,
|
|
53
|
+
transformation: {
|
|
54
|
+
x: Math.round(x),
|
|
55
|
+
y: Math.round(y),
|
|
56
|
+
width: Math.round(Math.max(5, width)),
|
|
57
|
+
height: Math.round(Math.max(5, height)),
|
|
58
|
+
rotate: Math.round(rotate),
|
|
59
|
+
scale: scale,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}, [transformCommit]);
|
|
64
|
+
|
|
65
|
+
React.useEffect(() => {
|
|
66
|
+
if (pixiTransformerRef.current) {
|
|
67
|
+
pixiTransformerRef.current.on("mouseover", handleOnMouseOver);
|
|
68
|
+
pixiTransformerRef.current.on("mouseout", handleOnMouseOut);
|
|
69
|
+
}
|
|
70
|
+
return () => {
|
|
71
|
+
if (pixiTransformerRef.current) {
|
|
72
|
+
pixiTransformerRef.current.off("mouseover", handleOnMouseOver);
|
|
73
|
+
pixiTransformerRef.current.off("mouseout", handleOnMouseOut);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<Transformer
|
|
80
|
+
ref={pixiTransformerRef}
|
|
81
|
+
group={isMounted ? [imageRef.current] : []}
|
|
82
|
+
rotateEnabled={true}
|
|
83
|
+
boxRotationEnabled={true}
|
|
84
|
+
boxScalingEnabled={true}
|
|
85
|
+
wireframeStyle={{ thickness: 1, color: anchorFill }}
|
|
86
|
+
lockAspectRatio={true}
|
|
87
|
+
scaleEnabled={true}
|
|
88
|
+
handleStyle={{
|
|
89
|
+
// color: colorYellow,
|
|
90
|
+
outlineColor: colorYellow,
|
|
91
|
+
shape: "circle",
|
|
92
|
+
radius: 9,
|
|
93
|
+
}}
|
|
94
|
+
transformchange={transformChange}
|
|
95
|
+
transformcommit={handleOnTransformCommit}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export default PixiTransformer;
|
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
Box,
|
|
12
12
|
Button,
|
|
13
13
|
} from "@chakra-ui/react";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
GsapPixieContext,
|
|
16
|
+
Events,
|
|
17
|
+
} from "../providers/GsapPixieContextProvider";
|
|
18
|
+
import { useCustomEventListener, emitCustomEvent } from "react-custom-events";
|
|
15
19
|
|
|
16
20
|
import { gsap } from "gsap";
|
|
17
21
|
import { Draggable } from "gsap/Draggable";
|
|
@@ -30,19 +34,18 @@ export const VideoSeekBar: React.FC = () => {
|
|
|
30
34
|
handlePause,
|
|
31
35
|
handleReset,
|
|
32
36
|
handleSeek,
|
|
37
|
+
handleSeekTest,
|
|
33
38
|
handleRestart,
|
|
34
39
|
handleRepeat,
|
|
40
|
+
totalDuration: duration,
|
|
35
41
|
} = React.useContext(GsapPixieContext);
|
|
36
42
|
|
|
37
43
|
/// state
|
|
38
44
|
const [time, setTime] = React.useState<number>(0);
|
|
39
|
-
const [duration, setDuration] = React.useState<number>(0);
|
|
40
|
-
|
|
41
45
|
const totalVideoSeconds = 20;
|
|
42
46
|
|
|
43
47
|
const animate = (time: number) => {
|
|
44
48
|
/// console.log("totalDuration", timeline.current.totalDuration());
|
|
45
|
-
setDuration(timeline.current.totalDuration());
|
|
46
49
|
if (playerTimeRef && playerTimeRef.current) {
|
|
47
50
|
setTime(playerTimeRef.current);
|
|
48
51
|
}
|
|
@@ -55,31 +58,39 @@ export const VideoSeekBar: React.FC = () => {
|
|
|
55
58
|
}, []); // Make sure the effect runs only once
|
|
56
59
|
|
|
57
60
|
const handleOnSliderChange = (value: number) => {
|
|
61
|
+
console.log("onslider change", value);
|
|
58
62
|
const nTotSeconds =
|
|
59
63
|
totalVideoSeconds && totalVideoSeconds > 0 ? totalVideoSeconds : 1;
|
|
60
64
|
const progress = value / nTotSeconds;
|
|
61
65
|
console.log("progressbar", value, progress);
|
|
66
|
+
|
|
62
67
|
playerTimeRef.current = value;
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
// handleSeek(value);
|
|
69
|
+
// // @ts-ignore
|
|
70
|
+
timeline && timeline.current.progress(progress);
|
|
71
|
+
// timeline && timeline.current.pause();
|
|
72
|
+
// gsap.set(sliderProgressRef.current!, {
|
|
73
|
+
// scaleX: progress,
|
|
74
|
+
// });
|
|
68
75
|
};
|
|
69
|
-
const handleOnSliderChangeStart = (value: number) => {};
|
|
70
|
-
const handleOnSliderChangeEnd = (value: number) => {};
|
|
71
76
|
|
|
72
|
-
/**
|
|
77
|
+
/** on slider start
|
|
78
|
+
* 1. pause the timeline
|
|
79
|
+
* 2. trigger custom event isDraggingStart
|
|
80
|
+
*/
|
|
81
|
+
const handleOnSliderChangeStart = (value: number) => {
|
|
82
|
+
// trigger custom event and pause the timeline
|
|
83
|
+
emitCustomEvent(Events.DRAGGING_START);
|
|
84
|
+
timeline && timeline.current.pause();
|
|
85
|
+
};
|
|
73
86
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
[totalVideoSeconds],
|
|
82
|
-
);
|
|
87
|
+
const handleOnSliderChangeEnd = (value: number) => {
|
|
88
|
+
// trigger custom event and pause the timeline
|
|
89
|
+
emitCustomEvent(Events.DRAGGING_END);
|
|
90
|
+
timeline && timeline.current.pause();
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** Create Draggable for the Gsap Player */
|
|
83
94
|
|
|
84
95
|
return (
|
|
85
96
|
<Flex flexDir={"column"}>
|
|
@@ -87,7 +98,7 @@ export const VideoSeekBar: React.FC = () => {
|
|
|
87
98
|
<Button onClick={handleRestart}>Play</Button>
|
|
88
99
|
<Button onClick={handlePause}>Pause</Button>
|
|
89
100
|
<Button onClick={handlePlay}>Resume</Button>
|
|
90
|
-
<Button onClick={
|
|
101
|
+
<Button onClick={handleSeekTest}>Seek (4:00)</Button>
|
|
91
102
|
</Box>
|
|
92
103
|
<Flex px={1} mt={2}>
|
|
93
104
|
<Slider
|
|
@@ -95,7 +106,7 @@ export const VideoSeekBar: React.FC = () => {
|
|
|
95
106
|
data-testid="sliderthumb"
|
|
96
107
|
value={playerTimeRef.current || 0}
|
|
97
108
|
min={0}
|
|
98
|
-
max={
|
|
109
|
+
max={10}
|
|
99
110
|
step={0.1}
|
|
100
111
|
onChange={handleOnSliderChange}
|
|
101
112
|
onChangeStart={handleOnSliderChangeStart}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
export function useDebounce<T>(value: T, delay?: number): T {
|
|
4
|
+
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay || 500);
|
|
8
|
+
|
|
9
|
+
return () => {
|
|
10
|
+
clearTimeout(timer);
|
|
11
|
+
};
|
|
12
|
+
}, [value, delay]);
|
|
13
|
+
|
|
14
|
+
return debouncedValue;
|
|
15
|
+
}
|