reacthub-pixitweenjs 0.2.2 → 0.2.4
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 +28 -0
- package/README.md +29 -80
- package/build-storybook.log +491 -0
- package/index.html +1 -1
- package/package.json +54 -19
- package/src/App.tsx +29 -0
- package/src/{stories/PixiImageSprite/PixiImageSprite.stories.js → components/PixiImageSprite/PixiImageSprite.stories.tsx} +25 -8
- package/src/components/PixiImageSprite/PixiImageSprite.tsx +346 -0
- package/src/components/PixiImageSprite/index.ts +1 -0
- package/src/hooks/usePixiTransformer.tsx +168 -0
- package/src/index.ts +3 -0
- package/src/providers/{GsapPixieContextProvider.jsx → GsapPixieContextProvider.tsx} +27 -24
- package/src/providers/index.ts +1 -0
- package/src/stories/Introduction.mdx +0 -99
- package/src/types/transformation.tsx +13 -0
- package/src/utils/AppStateProvider.tsx +70 -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 +33 -0
- package/src/utils/VideoSeekBar.tsx +118 -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/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,168 @@
|
|
|
1
|
+
import { Transformer } from "@pixi-essentials/transformer";
|
|
2
|
+
import * as PIXI from "pixi.js";
|
|
3
|
+
import { useApp } from "@pixi/react";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { useEffect, useRef, useCallback } from "react";
|
|
6
|
+
import { Transformation } from "../types/transformation";
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
import has from "lodash/has";
|
|
9
|
+
|
|
10
|
+
const colorYellow = PIXI.utils.string2hex("#F3C409");
|
|
11
|
+
const anchorFill = PIXI.utils.string2hex("#F3C409");
|
|
12
|
+
|
|
13
|
+
interface Events {
|
|
14
|
+
dblclick?: (e: any) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
uniqueId?: string;
|
|
19
|
+
onTransformEnd?: (data: {
|
|
20
|
+
uniqueId: string;
|
|
21
|
+
transformation: Transformation;
|
|
22
|
+
}) => void;
|
|
23
|
+
events?: Events;
|
|
24
|
+
mouseoverEvent?: (flag: boolean) => void;
|
|
25
|
+
setDragging?: (flag: boolean) => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const usePixiTransformer = ({
|
|
29
|
+
uniqueId = "",
|
|
30
|
+
onTransformEnd,
|
|
31
|
+
events = {},
|
|
32
|
+
mouseoverEvent = (f) => f,
|
|
33
|
+
setDragging = (f) => f,
|
|
34
|
+
}: Props) => {
|
|
35
|
+
const [isDragging, setIsDragging] = React.useState(false);
|
|
36
|
+
const PixiTransformer = React.useRef<PIXI.Container>(null);
|
|
37
|
+
const mounted = React.useRef(false);
|
|
38
|
+
const app = useApp();
|
|
39
|
+
const transformerRef = useRef<Transformer>(null);
|
|
40
|
+
const parentRef = useRef<PIXI.Container>(null);
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
mounted.current = true;
|
|
44
|
+
return () => {
|
|
45
|
+
mounted.current = false;
|
|
46
|
+
if (transformerRef.current) {
|
|
47
|
+
parentRef.current?.removeChild(transformerRef.current);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}, []);
|
|
51
|
+
|
|
52
|
+
const transformChange = useCallback(() => {
|
|
53
|
+
setIsDragging(true);
|
|
54
|
+
setDragging(true);
|
|
55
|
+
}, []);
|
|
56
|
+
|
|
57
|
+
const transformCommit = useCallback(() => {
|
|
58
|
+
if (PixiTransformer.current === null) return;
|
|
59
|
+
const x = PixiTransformer.current.x;
|
|
60
|
+
const y = PixiTransformer.current.y;
|
|
61
|
+
const width = PixiTransformer.current.width;
|
|
62
|
+
const height = PixiTransformer.current.height;
|
|
63
|
+
const rotate = PixiTransformer.current.rotation;
|
|
64
|
+
const scale: [number, number] = [
|
|
65
|
+
PixiTransformer.current.scale.x,
|
|
66
|
+
PixiTransformer.current.scale.y,
|
|
67
|
+
];
|
|
68
|
+
if (onTransformEnd) {
|
|
69
|
+
onTransformEnd({
|
|
70
|
+
uniqueId,
|
|
71
|
+
transformation: {
|
|
72
|
+
x: Math.round(x),
|
|
73
|
+
y: Math.round(y),
|
|
74
|
+
width: Math.round(Math.max(5, width)),
|
|
75
|
+
height: Math.round(Math.max(5, height)),
|
|
76
|
+
rotate: Math.round(rotate),
|
|
77
|
+
scale: scale,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
setIsDragging(false);
|
|
82
|
+
setDragging(false);
|
|
83
|
+
}, []);
|
|
84
|
+
|
|
85
|
+
const handleOnDblClick = useCallback((e: any) => {
|
|
86
|
+
if (events && has(events, "dblclick") && events.dblclick) {
|
|
87
|
+
events.dblclick(e);
|
|
88
|
+
}
|
|
89
|
+
}, []);
|
|
90
|
+
|
|
91
|
+
const handleOnMouseOver = useCallback(
|
|
92
|
+
(msevent: any) => {
|
|
93
|
+
if (mouseoverEvent) {
|
|
94
|
+
mouseoverEvent(true);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
[mouseoverEvent],
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const handleOnMouseOut = useCallback(
|
|
101
|
+
(msevent: any) => {
|
|
102
|
+
if (mouseoverEvent) {
|
|
103
|
+
mouseoverEvent(false);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
[mouseoverEvent],
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const handleTransformer = useCallback(
|
|
110
|
+
(node: PIXI.Container, parentNode: PIXI.Container) => {
|
|
111
|
+
const isEnabled = true;
|
|
112
|
+
// @ts-ignore
|
|
113
|
+
PixiTransformer.current = node;
|
|
114
|
+
const transformer = new Transformer({
|
|
115
|
+
rotateEnabled: isEnabled,
|
|
116
|
+
boxRotationEnabled: isEnabled,
|
|
117
|
+
boxScalingEnabled: isEnabled,
|
|
118
|
+
scaleEnabled: isEnabled,
|
|
119
|
+
group: [node],
|
|
120
|
+
wireframeStyle: {
|
|
121
|
+
thickness: 2,
|
|
122
|
+
color: anchorFill,
|
|
123
|
+
},
|
|
124
|
+
lockAspectRatio: true,
|
|
125
|
+
handleStyle: {
|
|
126
|
+
// color: colorYellow,
|
|
127
|
+
outlineColor: colorYellow,
|
|
128
|
+
shape: "circle",
|
|
129
|
+
radius: 10,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// transformer.addListener("transformchange", transformChange);
|
|
134
|
+
// @ts-ignore
|
|
135
|
+
transformer.addListener("transformcommit", transformCommit);
|
|
136
|
+
// transformer.addListener("dblclick", (evt) => {
|
|
137
|
+
// handleOnDblClick(evt);
|
|
138
|
+
// });
|
|
139
|
+
// transformer.on("mouseover", () => {
|
|
140
|
+
// handleOnMouseOver(true);
|
|
141
|
+
// });
|
|
142
|
+
// transformer.on("mouseout", () => {
|
|
143
|
+
// handleOnMouseOut(false);
|
|
144
|
+
// });
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
transformerRef.current = transformer;
|
|
147
|
+
// @ts-ignore
|
|
148
|
+
parentRef.current = parentNode;
|
|
149
|
+
parentRef.current.addChild(transformerRef.current);
|
|
150
|
+
},
|
|
151
|
+
[
|
|
152
|
+
transformCommit,
|
|
153
|
+
transformChange,
|
|
154
|
+
handleOnMouseOver,
|
|
155
|
+
handleOnMouseOut,
|
|
156
|
+
handleOnDblClick,
|
|
157
|
+
],
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const removeTransformer = useCallback(() => {
|
|
161
|
+
if (transformerRef.current) {
|
|
162
|
+
// @ts-ignore
|
|
163
|
+
parentRef.current.removeChild(transformerRef.current);
|
|
164
|
+
}
|
|
165
|
+
}, []);
|
|
166
|
+
|
|
167
|
+
return { handleTransformer, removeTransformer, isDragging };
|
|
168
|
+
};
|
package/src/index.ts
ADDED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
2
3
|
useState,
|
|
3
4
|
useEffect,
|
|
4
5
|
useCallback,
|
|
@@ -7,10 +8,22 @@ import React, {
|
|
|
7
8
|
} from "react";
|
|
8
9
|
import gsap from "gsap";
|
|
9
10
|
import { emitCustomEvent } from "react-custom-events";
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
interface GsapPixieContextProps {
|
|
13
|
+
gsapCtx: React.MutableRefObject<any>;
|
|
14
|
+
tl: React.MutableRefObject<any>;
|
|
15
|
+
handlePlay: () => void;
|
|
16
|
+
handlePause: () => void;
|
|
17
|
+
handleReset: () => void;
|
|
18
|
+
handleSeek: () => void;
|
|
19
|
+
handleRestart: () => void;
|
|
20
|
+
handleRepeat: () => void;
|
|
21
|
+
playerTimeRef: React.MutableRefObject<number>;
|
|
22
|
+
}
|
|
11
23
|
|
|
12
24
|
// Context has been created
|
|
13
|
-
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
const GsapPixieContext = React.createContext<GsapPixieContextProps>({});
|
|
14
27
|
|
|
15
28
|
const Events = {
|
|
16
29
|
STOP: "GSAP_STOP",
|
|
@@ -18,21 +31,19 @@ const Events = {
|
|
|
18
31
|
PLAY: "GSAP_PLAY",
|
|
19
32
|
RESUME: "GSAP_RESUME",
|
|
20
33
|
};
|
|
21
|
-
// Provider
|
|
22
|
-
const GsapPixieContextProvider = ({ children }) => {
|
|
23
|
-
const [play, setPlay] = useState(false);
|
|
24
|
-
const [frameNumber, setFrameNumber] = useState(0);
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
// Provider
|
|
36
|
+
const GsapPixieContextProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
37
|
+
children,
|
|
38
|
+
}) => {
|
|
39
|
+
const [play, setPlay] = useState<boolean>(false);
|
|
40
|
+
const [frameNumber, setFrameNumber] = useState<number>(0);
|
|
29
41
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// });
|
|
42
|
+
const tl = useRef<any>();
|
|
43
|
+
const gsapCtx = useRef<any>();
|
|
44
|
+
const playerTimeRef = useRef<number>(0.001);
|
|
34
45
|
|
|
35
|
-
const parentElementRef = useRef();
|
|
46
|
+
const parentElementRef = useRef<any>();
|
|
36
47
|
// передаем предка анимируемых элементов
|
|
37
48
|
const q = gsap.utils.selector(parentElementRef);
|
|
38
49
|
|
|
@@ -62,14 +73,6 @@ const GsapPixieContextProvider = ({ children }) => {
|
|
|
62
73
|
playerTimeRef.current = now;
|
|
63
74
|
}, []);
|
|
64
75
|
|
|
65
|
-
// const timeline = React.useCallback(
|
|
66
|
-
// gsap.timeline({
|
|
67
|
-
// paused: true,
|
|
68
|
-
// defaults: { duration: 0, onUpdate: onUpdate },
|
|
69
|
-
// }),
|
|
70
|
-
// [],
|
|
71
|
-
// );
|
|
72
|
-
|
|
73
76
|
useEffect(() => {
|
|
74
77
|
const timeline = tl.current;
|
|
75
78
|
timeline
|
|
@@ -93,7 +96,7 @@ const GsapPixieContextProvider = ({ children }) => {
|
|
|
93
96
|
}
|
|
94
97
|
}, [play]);
|
|
95
98
|
|
|
96
|
-
const addTotalDuration = (duration) => {
|
|
99
|
+
const addTotalDuration = (duration: number) => {
|
|
97
100
|
const timeline = tl.current;
|
|
98
101
|
timeline.totalDuration(duration);
|
|
99
102
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./GsapPixieContextProvider";
|
|
@@ -136,104 +136,5 @@ reacthub-pixitweenjs also provides a set of React components that make it easy t
|
|
|
136
136
|
|
|
137
137
|
Overall, reacthub-pixitweenjs is a great choice for developers who want to create stunning animations and interactive graphics in their React applications. It provides a powerful set of tools and a simple API that makes it easy to create complex animations and manipulate images in a timeline sequence.
|
|
138
138
|
|
|
139
|
-
Storybook helps you build UI components in isolation from your app's business logic, data, and context.
|
|
140
|
-
That makes it easy to develop hard-to-reach states. Save these UI states as **stories** to revisit during development, testing, or QA.
|
|
141
|
-
|
|
142
139
|
Browse example stories now by navigating to them in the sidebar.
|
|
143
140
|
View their code in the `stories` directory to learn how they work.
|
|
144
|
-
We recommend building UIs with a [**component-driven**](https://componentdriven.org) process starting with atomic components and ending with pages.
|
|
145
|
-
|
|
146
|
-
<div className="subheading">Configure</div>
|
|
147
|
-
|
|
148
|
-
<div className="link-list">
|
|
149
|
-
<a
|
|
150
|
-
className="link-item"
|
|
151
|
-
href="https://storybook.js.org/docs/react/addons/addon-types"
|
|
152
|
-
target="_blank"
|
|
153
|
-
>
|
|
154
|
-
<img src={Plugin} alt="plugin" />
|
|
155
|
-
<span>
|
|
156
|
-
<strong>Presets for popular tools</strong>
|
|
157
|
-
Easy setup for TypeScript, SCSS and more.
|
|
158
|
-
</span>
|
|
159
|
-
</a>
|
|
160
|
-
<a
|
|
161
|
-
className="link-item"
|
|
162
|
-
href="https://storybook.js.org/docs/react/configure/webpack"
|
|
163
|
-
target="_blank"
|
|
164
|
-
>
|
|
165
|
-
<img src={StackAlt} alt="Build" />
|
|
166
|
-
<span>
|
|
167
|
-
<strong>Build configuration</strong>
|
|
168
|
-
How to customize webpack and Babel
|
|
169
|
-
</span>
|
|
170
|
-
</a>
|
|
171
|
-
<a
|
|
172
|
-
className="link-item"
|
|
173
|
-
href="https://storybook.js.org/docs/react/configure/styling-and-css"
|
|
174
|
-
target="_blank"
|
|
175
|
-
>
|
|
176
|
-
<img src={Colors} alt="colors" />
|
|
177
|
-
<span>
|
|
178
|
-
<strong>Styling</strong>
|
|
179
|
-
How to load and configure CSS libraries
|
|
180
|
-
</span>
|
|
181
|
-
</a>
|
|
182
|
-
<a
|
|
183
|
-
className="link-item"
|
|
184
|
-
href="https://storybook.js.org/docs/react/get-started/setup#configure-storybook-for-your-stack"
|
|
185
|
-
target="_blank"
|
|
186
|
-
>
|
|
187
|
-
<img src={Flow} alt="flow" />
|
|
188
|
-
<span>
|
|
189
|
-
<strong>Data</strong>
|
|
190
|
-
Providers and mocking for data libraries
|
|
191
|
-
</span>
|
|
192
|
-
</a>
|
|
193
|
-
</div>
|
|
194
|
-
|
|
195
|
-
<div className="subheading">Learn</div>
|
|
196
|
-
|
|
197
|
-
<div className="link-list">
|
|
198
|
-
<a className="link-item" href="https://storybook.js.org/docs" target="_blank">
|
|
199
|
-
<img src={Repo} alt="repo" />
|
|
200
|
-
<span>
|
|
201
|
-
<strong>Storybook documentation</strong>
|
|
202
|
-
Configure, customize, and extend
|
|
203
|
-
</span>
|
|
204
|
-
</a>
|
|
205
|
-
<a
|
|
206
|
-
className="link-item"
|
|
207
|
-
href="https://storybook.js.org/tutorials/"
|
|
208
|
-
target="_blank"
|
|
209
|
-
>
|
|
210
|
-
<img src={Direction} alt="direction" />
|
|
211
|
-
<span>
|
|
212
|
-
<strong>In-depth guides</strong>
|
|
213
|
-
Best practices from leading teams
|
|
214
|
-
</span>
|
|
215
|
-
</a>
|
|
216
|
-
<a
|
|
217
|
-
className="link-item"
|
|
218
|
-
href="https://github.com/storybookjs/storybook"
|
|
219
|
-
target="_blank"
|
|
220
|
-
>
|
|
221
|
-
<img src={Code} alt="code" />
|
|
222
|
-
<span>
|
|
223
|
-
<strong>GitHub project</strong>
|
|
224
|
-
View the source and add issues
|
|
225
|
-
</span>
|
|
226
|
-
</a>
|
|
227
|
-
<a className="link-item" href="https://discord.gg/storybook" target="_blank">
|
|
228
|
-
<img src={Comments} alt="comments" />
|
|
229
|
-
<span>
|
|
230
|
-
<strong>Discord chat</strong>
|
|
231
|
-
Chat with maintainers and the community
|
|
232
|
-
</span>
|
|
233
|
-
</a>
|
|
234
|
-
</div>
|
|
235
|
-
|
|
236
|
-
<div className="tip-wrapper">
|
|
237
|
-
<span className="tip">Tip</span>Edit the Markdown in{" "}
|
|
238
|
-
<code>stories/Introduction.stories.mdx</code>
|
|
239
|
-
</div>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import useDeepEffect from "./useDeepEffect";
|
|
3
|
+
import { TransformationEnd } from "../types/transformation";
|
|
4
|
+
|
|
5
|
+
interface AppState {
|
|
6
|
+
transformation: {
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
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
|
+
interface AppStateContextProviderProps extends AppState {
|
|
25
|
+
children: React.ReactNode;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const AppStateContextProvider: React.FC<
|
|
29
|
+
AppStateContextProviderProps
|
|
30
|
+
> = ({ children, ...props }) => {
|
|
31
|
+
const [appState, setAppState] = React.useState<AppState>(props);
|
|
32
|
+
useDeepEffect(() => {
|
|
33
|
+
setAppState(props);
|
|
34
|
+
}, [props]);
|
|
35
|
+
|
|
36
|
+
const onAnchorTransformationEnd = React.useCallback(
|
|
37
|
+
(data: {
|
|
38
|
+
uniqueId: string;
|
|
39
|
+
transformation: { [key: string]: unknown };
|
|
40
|
+
}) => {
|
|
41
|
+
const { uniqueId, transformation } = data;
|
|
42
|
+
const newAppState = {
|
|
43
|
+
...props,
|
|
44
|
+
transformation: {
|
|
45
|
+
...props.transformation,
|
|
46
|
+
...transformation,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
setAppState(newAppState);
|
|
50
|
+
},
|
|
51
|
+
[props],
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const onMouseOverSprite = React.useCallback((data: unknown) => {}, []);
|
|
55
|
+
|
|
56
|
+
const onClickSprite = React.useCallback((data: unknown) => {}, []);
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<AppStateContext.Provider
|
|
60
|
+
value={{
|
|
61
|
+
...appState,
|
|
62
|
+
onAnchorTransformationEnd,
|
|
63
|
+
onMouseOverSprite,
|
|
64
|
+
onClickSprite,
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
{children}
|
|
68
|
+
</AppStateContext.Provider>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import ContextBridge from "./ContextBridge";
|
|
3
|
+
import { AppStateContext } from "../providers/AppStateProvider";
|
|
4
|
+
import { Container as PixiContainer } from "@pixi/react";
|
|
5
|
+
|
|
6
|
+
interface AppStateStageProps {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const AppStateStage: React.FC<AppStateStageProps> = ({
|
|
11
|
+
children,
|
|
12
|
+
...props
|
|
13
|
+
}) => {
|
|
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
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default AppStateStage;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Flex, Box } from "@chakra-ui/react";
|
|
3
|
+
import * as PIXI from "pixi.js";
|
|
4
|
+
import { ChakraProvider } from "@chakra-ui/react";
|
|
5
|
+
import { GsapPixieContextProvider } from "../providers/GsapPixieContextProvider";
|
|
6
|
+
import { VideoSeekBar } from "./VideoSeekBar";
|
|
7
|
+
import Stage from "./PixiStage";
|
|
8
|
+
|
|
9
|
+
interface AppProps {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
backgroundColor?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const AppWrapper: React.FC<AppProps> = ({
|
|
15
|
+
children,
|
|
16
|
+
backgroundColor,
|
|
17
|
+
}) => {
|
|
18
|
+
const backgroundColorx = PIXI.utils.string2hex(backgroundColor || "#2D2E3C");
|
|
19
|
+
const width = 600;
|
|
20
|
+
const height = 500;
|
|
21
|
+
/// color: 0x1099bb,
|
|
22
|
+
return (
|
|
23
|
+
<div className="App">
|
|
24
|
+
<GsapPixieContextProvider>
|
|
25
|
+
<ChakraProvider>
|
|
26
|
+
<Flex flexDir={"column"}>
|
|
27
|
+
<Stage
|
|
28
|
+
width={width}
|
|
29
|
+
height={height}
|
|
30
|
+
// options={{ background: backgroundColor }}
|
|
31
|
+
options={{ backgroundColor: backgroundColorx, resolution: 2 }}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
</Stage>
|
|
35
|
+
<Box mt={5} w={600}>
|
|
36
|
+
<VideoSeekBar />
|
|
37
|
+
</Box>
|
|
38
|
+
</Flex>
|
|
39
|
+
</ChakraProvider>
|
|
40
|
+
</GsapPixieContextProvider>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// your Stage:
|
|
2
|
+
// the context bridge:
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
const ContextBridge = <T,>({
|
|
6
|
+
children,
|
|
7
|
+
Context,
|
|
8
|
+
render,
|
|
9
|
+
}: {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
Context: React.Context<T>;
|
|
12
|
+
render: (children: React.ReactNode) => JSX.Element;
|
|
13
|
+
}) => {
|
|
14
|
+
return (
|
|
15
|
+
<Context.Consumer>
|
|
16
|
+
{(value) => {
|
|
17
|
+
return render(
|
|
18
|
+
<Context.Provider value={value}>{children}</Context.Provider>,
|
|
19
|
+
);
|
|
20
|
+
}}
|
|
21
|
+
</Context.Consumer>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default ContextBridge;
|
|
@@ -1,8 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
interface Ease {
|
|
2
|
+
from?: {
|
|
3
|
+
duration: number;
|
|
4
|
+
ease: string;
|
|
5
|
+
y?: number;
|
|
6
|
+
x?: number;
|
|
7
|
+
};
|
|
8
|
+
fromTo?: {
|
|
9
|
+
from: {
|
|
10
|
+
y?: number;
|
|
11
|
+
x?: number;
|
|
12
|
+
alpha?: number;
|
|
13
|
+
};
|
|
14
|
+
to: {
|
|
15
|
+
ease: string;
|
|
16
|
+
y?: number;
|
|
17
|
+
x?: number;
|
|
18
|
+
alpha?: number;
|
|
19
|
+
duration: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
to?: {
|
|
23
|
+
ease: string;
|
|
24
|
+
alpha: number;
|
|
25
|
+
duration: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
3
28
|
|
|
4
|
-
export const getAnimByName = (
|
|
5
|
-
|
|
29
|
+
export const getAnimByName = (
|
|
30
|
+
animate: string,
|
|
31
|
+
stageWidth?: number,
|
|
32
|
+
stageHeight?: number,
|
|
33
|
+
x?: number,
|
|
34
|
+
y?: number,
|
|
35
|
+
): Ease => {
|
|
36
|
+
let ease: Ease = {};
|
|
6
37
|
switch (animate) {
|
|
7
38
|
case "NONE":
|
|
8
39
|
case "none":
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import ContextBridge from "./ContextBridge";
|
|
3
|
+
import { Stage as PixiStage } from "@pixi/react";
|
|
4
|
+
import { AppStateContextProvider } from "./AppStateProvider";
|
|
5
|
+
import { GsapPixieContext } from "../providers/GsapPixieContextProvider";
|
|
6
|
+
|
|
7
|
+
interface StageProps {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
options: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const Stage: React.FC<StageProps> = ({ children, ...props }) => {
|
|
15
|
+
return (
|
|
16
|
+
<ContextBridge
|
|
17
|
+
Context={GsapPixieContext}
|
|
18
|
+
render={(children: React.ReactNode | React.ReactElement) => (
|
|
19
|
+
<PixiStage {...props}>
|
|
20
|
+
{/* @ts-ignore */}
|
|
21
|
+
<AppStateContextProvider {...props}>
|
|
22
|
+
{/* @ts-ignore */}
|
|
23
|
+
{children}
|
|
24
|
+
</AppStateContextProvider>
|
|
25
|
+
</PixiStage>
|
|
26
|
+
)}
|
|
27
|
+
>
|
|
28
|
+
{children}
|
|
29
|
+
</ContextBridge>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default Stage;
|