@cntrl-site/sdk-nextjs 1.6.3 → 1.6.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/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +15 -0
- package/cntrl-site-sdk-nextjs-1.6.3.tgz +0 -0
- package/cntrl-site-sdk-nextjs-1.6.4.tgz +0 -0
- package/cntrl-site-sdk-nextjs-1.6.5.tgz +0 -0
- package/cntrl-site-sdk-nextjs-1.6.6.tgz +0 -0
- package/lib/common/useItemFXData.js +37 -0
- package/lib/common/useKeyframeValue.js +2 -2
- package/lib/components/items/FileItem/ImageItem.js +5 -13
- package/lib/components/items/FileItem/VideoItem.js +5 -13
- package/lib/components/items/FileItem/useFileItem.js +2 -2
- package/lib/utils/Animator/Animator.js +21 -1
- package/lib/utils/effects/useImageFx.js +12 -7
- package/lib/utils/effects/useVideoFx.js +5 -7
- package/package.json +2 -2
- package/src/common/useItemFXData.ts +47 -0
- package/src/common/useKeyframeValue.ts +4 -5
- package/src/components/items/FileItem/ImageItem.tsx +8 -17
- package/src/components/items/FileItem/VideoItem.tsx +5 -15
- package/src/components/items/FileItem/useFileItem.ts +3 -3
- package/src/utils/Animator/Animator.ts +23 -3
- package/src/utils/effects/useImageFx.ts +15 -18
- package/src/utils/effects/useVideoFx.ts +5 -15
- package/cntrl-site-sdk-nextjs-1.2.0.tgz +0 -0
- package/cntrl-site-sdk-nextjs-1.3.3.tgz +0 -0
- package/lib/components/items/FileItem/shaderBaseVars.js +0 -11
- package/src/components/items/FileItem/shaderBaseVars.ts +0 -8
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<component name="InspectionProjectProfileManager">
|
|
2
|
+
<profile version="1.0">
|
|
3
|
+
<option name="myName" value="Project Default" />
|
|
4
|
+
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
|
5
|
+
<option name="myValues">
|
|
6
|
+
<value>
|
|
7
|
+
<list size="1">
|
|
8
|
+
<item index="0" class="java.lang.String" itemvalue="jsx" />
|
|
9
|
+
</list>
|
|
10
|
+
</value>
|
|
11
|
+
</option>
|
|
12
|
+
<option name="myCustomValuesEnabled" value="true" />
|
|
13
|
+
</inspection_tool>
|
|
14
|
+
</profile>
|
|
15
|
+
</component>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useItemFXData = void 0;
|
|
4
|
+
const sdk_1 = require("@cntrl-site/sdk");
|
|
5
|
+
const useKeyframeValue_1 = require("./useKeyframeValue");
|
|
6
|
+
const baseVariables = `precision mediump float;
|
|
7
|
+
uniform sampler2D u_image;
|
|
8
|
+
uniform sampler2D u_pattern;
|
|
9
|
+
uniform vec2 u_imgDimensions;
|
|
10
|
+
uniform vec2 u_patternDimensions;
|
|
11
|
+
uniform float u_time;
|
|
12
|
+
uniform vec2 u_cursor;
|
|
13
|
+
varying vec2 v_texCoord;`;
|
|
14
|
+
function useItemFXData(item, sectionId) {
|
|
15
|
+
const { fragmentShader: shaderBody, FXControls } = item.commonParams;
|
|
16
|
+
const controls = FXControls !== null && FXControls !== void 0 ? FXControls : [];
|
|
17
|
+
const controlsVariables = controls.map((c) => `uniform ${c.type} ${c.shaderParam};`)
|
|
18
|
+
.join('\n');
|
|
19
|
+
const fragmentShader = `${baseVariables}\n${controlsVariables}\n${shaderBody}`;
|
|
20
|
+
const controlsValues = (0, useKeyframeValue_1.useKeyframeValue)(item, sdk_1.KeyframeType.FXParams, () => {
|
|
21
|
+
const defaultValue = controls.reduce((acc, control) => {
|
|
22
|
+
if (Array.isArray(control.value)) {
|
|
23
|
+
acc[control.shaderParam] = control.value[0];
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
acc[control.shaderParam] = control.value;
|
|
27
|
+
}
|
|
28
|
+
return acc;
|
|
29
|
+
}, {});
|
|
30
|
+
return defaultValue;
|
|
31
|
+
}, (animator, scroll, value) => animator.getFXParams(value, scroll), sectionId);
|
|
32
|
+
return {
|
|
33
|
+
fragmentShader,
|
|
34
|
+
controlsValues
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
exports.useItemFXData = useItemFXData;
|
|
@@ -11,7 +11,7 @@ const KeyframesContext_1 = require("../provider/KeyframesContext");
|
|
|
11
11
|
const Animator_1 = require("../utils/Animator/Animator");
|
|
12
12
|
const useLayoutContext_1 = require("../components/useLayoutContext");
|
|
13
13
|
const emptyDeps = [];
|
|
14
|
-
|
|
14
|
+
function useKeyframeValue(item, type, itemParamsGetter, animatorGetter, sectionId, deps = emptyDeps) {
|
|
15
15
|
const animatorGetterRef = (0, react_1.useRef)(animatorGetter);
|
|
16
16
|
const itemParamsGetterRef = (0, react_1.useRef)(itemParamsGetter);
|
|
17
17
|
animatorGetterRef.current = animatorGetter;
|
|
@@ -72,5 +72,5 @@ const useKeyframeValue = (item, type, itemParamsGetter, animatorGetter, sectionI
|
|
|
72
72
|
});
|
|
73
73
|
}, [handleKeyframeValue, articleRectObserver, animator]);
|
|
74
74
|
return keyframes.length ? adjustedValue : paramValue;
|
|
75
|
-
}
|
|
75
|
+
}
|
|
76
76
|
exports.useKeyframeValue = useKeyframeValue;
|
|
@@ -18,7 +18,7 @@ const useImageFx_1 = require("../../../utils/effects/useImageFx");
|
|
|
18
18
|
const useElementRect_1 = require("../../../utils/useElementRect");
|
|
19
19
|
const useLayoutContext_1 = require("../../useLayoutContext");
|
|
20
20
|
const getStyleFromItemStateAndParams_1 = require("../../../utils/getStyleFromItemStateAndParams");
|
|
21
|
-
const
|
|
21
|
+
const useItemFXData_1 = require("../../../common/useItemFXData");
|
|
22
22
|
const ImageItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
23
23
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
24
24
|
const id = (0, react_1.useId)();
|
|
@@ -28,18 +28,11 @@ const ImageItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
28
28
|
const itemAngle = (0, useItemAngle_1.useItemAngle)(item, sectionId);
|
|
29
29
|
const [wrapperRef, setWrapperRef] = (0, react_1.useState)(null);
|
|
30
30
|
(0, useRegisterResize_1.useRegisterResize)(wrapperRef, onResize);
|
|
31
|
-
const { url, hasGLEffect
|
|
31
|
+
const { url, hasGLEffect } = item.commonParams;
|
|
32
32
|
const fxCanvas = (0, react_1.useRef)(null);
|
|
33
33
|
const isInitialRef = (0, react_1.useRef)(true);
|
|
34
|
-
const controls = FXControls !== null && FXControls !== void 0 ? FXControls : [];
|
|
35
|
-
const controlsVariables = controls.map((c) => `uniform ${c.type} ${c.shaderParam};`)
|
|
36
|
-
.join('\n');
|
|
37
|
-
const controlValues = controls.reduce((acc, control) => {
|
|
38
|
-
acc[control.shaderParam] = control.value;
|
|
39
|
-
return acc;
|
|
40
|
-
}, {});
|
|
41
34
|
const layoutValues = [item.area, item.layoutParams];
|
|
42
|
-
const
|
|
35
|
+
const { controlsValues, fragmentShader } = (0, useItemFXData_1.useItemFXData)(item, sectionId);
|
|
43
36
|
const area = layoutId ? item.area[layoutId] : null;
|
|
44
37
|
const exemplary = (_a = layouts === null || layouts === void 0 ? void 0 : layouts.find(l => l.id === layoutId)) === null || _a === void 0 ? void 0 : _a.exemplary;
|
|
45
38
|
const width = area && exemplary ? area.width * exemplary : 0;
|
|
@@ -51,9 +44,8 @@ const ImageItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
51
44
|
}, []);
|
|
52
45
|
const isFXAllowed = (0, useImageFx_1.useImageFx)(fxCanvas.current, !!(hasGLEffect && !isInitialRef.current), {
|
|
53
46
|
imageUrl: url,
|
|
54
|
-
fragmentShader
|
|
55
|
-
|
|
56
|
-
controls: controlValues
|
|
47
|
+
fragmentShader,
|
|
48
|
+
controlsValues
|
|
57
49
|
}, width, height);
|
|
58
50
|
const rect = (0, useElementRect_1.useElementRect)(wrapperRef);
|
|
59
51
|
const rectWidth = Math.floor((_b = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _b !== void 0 ? _b : 0);
|
|
@@ -17,9 +17,9 @@ const useRegisterResize_1 = require("../../../common/useRegisterResize");
|
|
|
17
17
|
const useLayoutContext_1 = require("../../useLayoutContext");
|
|
18
18
|
const ScrollPlaybackVideo_1 = require("../../ScrollPlaybackVideo");
|
|
19
19
|
const getStyleFromItemStateAndParams_1 = require("../../../utils/getStyleFromItemStateAndParams");
|
|
20
|
-
const shaderBaseVars_1 = require("./shaderBaseVars");
|
|
21
20
|
const useVideoFx_1 = require("../../../utils/effects/useVideoFx");
|
|
22
21
|
const useElementRect_1 = require("../../../utils/useElementRect");
|
|
22
|
+
const useItemFXData_1 = require("../../../common/useItemFXData");
|
|
23
23
|
const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
24
24
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
25
25
|
const id = (0, react_1.useId)();
|
|
@@ -30,20 +30,13 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
30
30
|
const [ref, setRef] = (0, react_1.useState)(null);
|
|
31
31
|
const videoRef = (0, react_1.useRef)(null);
|
|
32
32
|
const fxCanvas = (0, react_1.useRef)(null);
|
|
33
|
-
const { url, hasGLEffect
|
|
33
|
+
const { url, hasGLEffect } = item.commonParams;
|
|
34
34
|
const isInitialRef = (0, react_1.useRef)(true);
|
|
35
35
|
const area = layoutId ? item.area[layoutId] : null;
|
|
36
36
|
const exemplary = (_a = layouts === null || layouts === void 0 ? void 0 : layouts.find(l => l.id === layoutId)) === null || _a === void 0 ? void 0 : _a.exemplary;
|
|
37
37
|
const width = area && exemplary ? area.width * exemplary : 0;
|
|
38
38
|
const height = area && exemplary ? area.height * exemplary : 0;
|
|
39
|
-
const
|
|
40
|
-
const controlsVariables = controls.map((c) => `uniform ${c.type} ${c.shaderParam};`)
|
|
41
|
-
.join('\n');
|
|
42
|
-
const controlValues = controls.reduce((acc, control) => {
|
|
43
|
-
acc[control.shaderParam] = control.value;
|
|
44
|
-
return acc;
|
|
45
|
-
}, {});
|
|
46
|
-
const fullShaderCode = `${shaderBaseVars_1.baseVariables}\n${controlsVariables}\n${fragmentShader}`;
|
|
39
|
+
const { controlsValues, fragmentShader } = (0, useItemFXData_1.useItemFXData)(item, sectionId);
|
|
47
40
|
const rect = (0, useElementRect_1.useElementRect)(ref);
|
|
48
41
|
const rectWidth = Math.floor((_b = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _b !== void 0 ? _b : 0);
|
|
49
42
|
const rectHeight = Math.floor((_c = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _c !== void 0 ? _c : 0);
|
|
@@ -67,9 +60,8 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
67
60
|
}, []);
|
|
68
61
|
const isFXAllowed = (0, useVideoFx_1.useVideoFx)(fxCanvas.current, !!(hasGLEffect && !isInitialRef.current), {
|
|
69
62
|
videoUrl: url,
|
|
70
|
-
fragmentShader
|
|
71
|
-
|
|
72
|
-
controls: controlValues
|
|
63
|
+
fragmentShader,
|
|
64
|
+
controls: controlsValues
|
|
73
65
|
}, width, height);
|
|
74
66
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
75
67
|
const inlineStyles = Object.assign(Object.assign(Object.assign(Object.assign({}, (radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {})), (strokeWidth !== undefined ? { borderWidth: `${strokeWidth * 100}vw` } : {})), (borderColor ? { borderColor: `${borderColor.toCss()}` } : {})), { transition: (_k = videoStateParams === null || videoStateParams === void 0 ? void 0 : videoStateParams.transition) !== null && _k !== void 0 ? _k : 'none' });
|
|
@@ -5,7 +5,7 @@ const sdk_1 = require("@cntrl-site/sdk");
|
|
|
5
5
|
const useKeyframeValue_1 = require("../../../common/useKeyframeValue");
|
|
6
6
|
const useLayoutContext_1 = require("../../useLayoutContext");
|
|
7
7
|
const DEFAULT_COLOR = 'rgba(0, 0, 0, 1)';
|
|
8
|
-
|
|
8
|
+
function useFileItem(item, sectionId) {
|
|
9
9
|
const layoutId = (0, useLayoutContext_1.useLayoutContext)();
|
|
10
10
|
const radius = (0, useKeyframeValue_1.useKeyframeValue)(item, sdk_1.KeyframeType.BorderRadius, (item, layoutId) => {
|
|
11
11
|
if (!layoutId)
|
|
@@ -38,5 +38,5 @@ const useFileItem = (item, sectionId) => {
|
|
|
38
38
|
return 'blur' in layoutParams ? layoutParams.blur : 0;
|
|
39
39
|
}, (animator, scroll, value) => value !== undefined ? animator.getBlur({ blur: value }, scroll).blur : undefined, sectionId, [layoutId]);
|
|
40
40
|
return { radius, strokeWidth, opacity, strokeColor, blur };
|
|
41
|
-
}
|
|
41
|
+
}
|
|
42
42
|
exports.useFileItem = useFileItem;
|
|
@@ -16,6 +16,25 @@ class Animator {
|
|
|
16
16
|
this.keyframesMap = createKeyframesMap();
|
|
17
17
|
this.fillKeyframesMap();
|
|
18
18
|
}
|
|
19
|
+
getFXParams(valuesMap, pos) {
|
|
20
|
+
const keyframes = this.keyframesMap[sdk_1.KeyframeType.FXParams];
|
|
21
|
+
if (!keyframes.length)
|
|
22
|
+
return valuesMap;
|
|
23
|
+
if (keyframes.length === 1) {
|
|
24
|
+
const [keyframe] = keyframes;
|
|
25
|
+
return Object.entries(valuesMap).reduce((acc, [key, fallbackValue]) => {
|
|
26
|
+
var _a;
|
|
27
|
+
acc[key] = (_a = keyframe.value[key]) !== null && _a !== void 0 ? _a : fallbackValue;
|
|
28
|
+
return acc;
|
|
29
|
+
}, {});
|
|
30
|
+
}
|
|
31
|
+
const { start, end } = this.getStartEnd(pos, keyframes);
|
|
32
|
+
return Object.entries(valuesMap).reduce((acc, [key, fallbackValue]) => {
|
|
33
|
+
var _a, _b;
|
|
34
|
+
acc[key] = (0, rangeMap_1.rangeMap)(pos, start.position, end.position, (_a = start.value[key]) !== null && _a !== void 0 ? _a : fallbackValue, (_b = end.value[key]) !== null && _b !== void 0 ? _b : fallbackValue, true);
|
|
35
|
+
return acc;
|
|
36
|
+
}, {});
|
|
37
|
+
}
|
|
19
38
|
getDimensions(values, pos) {
|
|
20
39
|
const keyframes = this.keyframesMap[sdk_1.KeyframeType.Dimensions];
|
|
21
40
|
if (!keyframes || !keyframes.length)
|
|
@@ -266,6 +285,7 @@ function createKeyframesMap() {
|
|
|
266
285
|
[sdk_1.KeyframeType.BackdropBlur]: [],
|
|
267
286
|
[sdk_1.KeyframeType.LetterSpacing]: [],
|
|
268
287
|
[sdk_1.KeyframeType.WordSpacing]: [],
|
|
269
|
-
[sdk_1.KeyframeType.TextColor]: []
|
|
288
|
+
[sdk_1.KeyframeType.TextColor]: [],
|
|
289
|
+
[sdk_1.KeyframeType.FXParams]: []
|
|
270
290
|
};
|
|
271
291
|
}
|
|
@@ -6,22 +6,27 @@ const effects_1 = require("@cntrl-site/effects");
|
|
|
6
6
|
const rangeMap_1 = require("../rangeMap");
|
|
7
7
|
const PATTERN_URL = 'https://cdn.cntrl.site/client-app-files/texture2.png';
|
|
8
8
|
const PATTERN_2_URL = 'https://cdn.cntrl.site/client-app-files/bayer16.png';
|
|
9
|
-
function useImageFx(canvas, enabled, { imageUrl, fragmentShader,
|
|
9
|
+
function useImageFx(canvas, enabled, { imageUrl, fragmentShader, controlsValues }, width, height) {
|
|
10
10
|
const [isFXAllowed, setIsFXAllowed] = (0, react_1.useState)(true);
|
|
11
|
-
const mousePos = (0, react_1.useRef)([0.0, 0.0]);
|
|
12
11
|
const imageTextureManager = (0, react_1.useMemo)(() => {
|
|
13
12
|
if (!imageUrl || !enabled)
|
|
14
13
|
return;
|
|
15
14
|
return new effects_1.ImageTextureManager(imageUrl);
|
|
16
15
|
}, [imageUrl, enabled]);
|
|
17
16
|
const imageFx = (0, react_1.useMemo)(() => {
|
|
18
|
-
if (!
|
|
17
|
+
if (!imageTextureManager)
|
|
19
18
|
return;
|
|
20
|
-
|
|
21
|
-
return new effects_1.MediaEffect(imageTextureManager, PATTERN_URL, PATTERN_2_URL, fragmentShader, Object.assign({ time: 0, cursor: type === 'mouse' ? mousePos.current : [x, y] }, controls), width, height);
|
|
19
|
+
return new effects_1.MediaEffect(imageTextureManager, PATTERN_URL, PATTERN_2_URL, fragmentShader, Object.assign({ time: 0, cursor: [0, 0] }, controlsValues), width, height);
|
|
22
20
|
}, [imageTextureManager, fragmentShader, width, height]);
|
|
23
21
|
(0, react_1.useEffect)(() => {
|
|
24
|
-
if (!
|
|
22
|
+
if (!imageFx || !controlsValues)
|
|
23
|
+
return;
|
|
24
|
+
for (const [key, value] of Object.entries(controlsValues)) {
|
|
25
|
+
imageFx.setParam(key, value);
|
|
26
|
+
}
|
|
27
|
+
}, [imageFx, controlsValues]);
|
|
28
|
+
(0, react_1.useEffect)(() => {
|
|
29
|
+
if (!canvas || !imageFx)
|
|
25
30
|
return;
|
|
26
31
|
const handleMouseMove = (evt) => {
|
|
27
32
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -33,7 +38,7 @@ function useImageFx(canvas, enabled, { imageUrl, fragmentShader, cursor, control
|
|
|
33
38
|
return () => {
|
|
34
39
|
window.removeEventListener('mousemove', handleMouseMove);
|
|
35
40
|
};
|
|
36
|
-
}, [canvas, imageFx
|
|
41
|
+
}, [canvas, imageFx]);
|
|
37
42
|
(0, react_1.useEffect)(() => {
|
|
38
43
|
const gl = canvas === null || canvas === void 0 ? void 0 : canvas.getContext('webgl2');
|
|
39
44
|
if (!enabled || !canvas || !gl || !imageFx)
|
|
@@ -6,11 +6,10 @@ const effects_1 = require("@cntrl-site/effects");
|
|
|
6
6
|
const rangeMap_1 = require("../rangeMap");
|
|
7
7
|
const PATTERN_URL = 'https://cdn.cntrl.site/client-app-files/texture2.png';
|
|
8
8
|
const PATTERN_2_URL = 'https://cdn.cntrl.site/client-app-files/bayer16.png';
|
|
9
|
-
function useVideoFx(canvas, enabled, { videoUrl, fragmentShader,
|
|
9
|
+
function useVideoFx(canvas, enabled, { videoUrl, fragmentShader, controls }, width, height) {
|
|
10
10
|
const [isFXAllowed, setIsFXAllowed] = (0, react_1.useState)(true);
|
|
11
11
|
const [isReady, setIsReady] = (0, react_1.useState)(false);
|
|
12
12
|
const active = enabled && isReady;
|
|
13
|
-
const mousePos = (0, react_1.useRef)([0.0, 0.0]);
|
|
14
13
|
const videoTextureManager = (0, react_1.useMemo)(() => {
|
|
15
14
|
if (!videoUrl || !enabled)
|
|
16
15
|
return;
|
|
@@ -20,10 +19,9 @@ function useVideoFx(canvas, enabled, { videoUrl, fragmentShader, cursor, control
|
|
|
20
19
|
return new effects_1.VideoTextureManager(videoUrl, handlePlayError);
|
|
21
20
|
}, [videoUrl, enabled]);
|
|
22
21
|
const videoFx = (0, react_1.useMemo)(() => {
|
|
23
|
-
if (!
|
|
22
|
+
if (!videoTextureManager)
|
|
24
23
|
return;
|
|
25
|
-
|
|
26
|
-
return new effects_1.MediaEffect(videoTextureManager, PATTERN_URL, PATTERN_2_URL, fragmentShader, Object.assign({ time: 0, cursor: type === 'mouse' ? mousePos.current : [x, y] }, controls), width, height);
|
|
24
|
+
return new effects_1.MediaEffect(videoTextureManager, PATTERN_URL, PATTERN_2_URL, fragmentShader, Object.assign({ time: 0, cursor: [0, 0] }, controls), width, height);
|
|
27
25
|
}, [videoTextureManager, fragmentShader, width, height]);
|
|
28
26
|
(0, react_1.useEffect)(() => {
|
|
29
27
|
if (!videoTextureManager)
|
|
@@ -31,7 +29,7 @@ function useVideoFx(canvas, enabled, { videoUrl, fragmentShader, cursor, control
|
|
|
31
29
|
videoTextureManager.onReadyStatusChange(setIsReady);
|
|
32
30
|
}, [videoTextureManager]);
|
|
33
31
|
(0, react_1.useEffect)(() => {
|
|
34
|
-
if (!
|
|
32
|
+
if (!canvas || !videoFx)
|
|
35
33
|
return;
|
|
36
34
|
const handleMouseMove = (evt) => {
|
|
37
35
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -43,7 +41,7 @@ function useVideoFx(canvas, enabled, { videoUrl, fragmentShader, cursor, control
|
|
|
43
41
|
return () => {
|
|
44
42
|
window.removeEventListener('mousemove', handleMouseMove);
|
|
45
43
|
};
|
|
46
|
-
}, [canvas, videoFx
|
|
44
|
+
}, [canvas, videoFx]);
|
|
47
45
|
(0, react_1.useEffect)(() => {
|
|
48
46
|
const gl = canvas === null || canvas === void 0 ? void 0 : canvas.getContext('webgl2');
|
|
49
47
|
if (!active || !canvas || !gl || !videoFx)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cntrl-site/sdk-nextjs",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.4",
|
|
4
4
|
"description": "SDK for Next.js",
|
|
5
5
|
"author": "arsen@momdesign.nyc",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@antfu/eslint-config": "^3.8.0",
|
|
32
32
|
"@cntrl-site/color": "^1.0.0",
|
|
33
33
|
"@cntrl-site/effects": "^1.3.2",
|
|
34
|
-
"@cntrl-site/sdk": "^1.19.
|
|
34
|
+
"@cntrl-site/sdk": "^1.19.4",
|
|
35
35
|
"@types/vimeo__player": "^2.18.0",
|
|
36
36
|
"@vimeo/player": "^2.25.0",
|
|
37
37
|
"html-react-parser": "^3.0.1",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ImageItem, KeyframeType, VideoItem } from '@cntrl-site/sdk';
|
|
2
|
+
import { useKeyframeValue } from './useKeyframeValue';
|
|
3
|
+
|
|
4
|
+
const baseVariables = `precision mediump float;
|
|
5
|
+
uniform sampler2D u_image;
|
|
6
|
+
uniform sampler2D u_pattern;
|
|
7
|
+
uniform vec2 u_imgDimensions;
|
|
8
|
+
uniform vec2 u_patternDimensions;
|
|
9
|
+
uniform float u_time;
|
|
10
|
+
uniform vec2 u_cursor;
|
|
11
|
+
varying vec2 v_texCoord;`;
|
|
12
|
+
|
|
13
|
+
export function useItemFXData(item: ImageItem | VideoItem, sectionId: string): FXData {
|
|
14
|
+
const { fragmentShader: shaderBody, FXControls } = item.commonParams;
|
|
15
|
+
const controls = FXControls ?? [];
|
|
16
|
+
const controlsVariables = controls.map((c) => `uniform ${c.type} ${c.shaderParam};`)
|
|
17
|
+
.join('\n');
|
|
18
|
+
const fragmentShader = `${baseVariables}\n${controlsVariables}\n${shaderBody}`;
|
|
19
|
+
const controlsValues = useKeyframeValue(
|
|
20
|
+
item,
|
|
21
|
+
KeyframeType.FXParams,
|
|
22
|
+
() => {
|
|
23
|
+
const defaultValue = controls.reduce<Record<string, ControlValue>>((acc, control) => {
|
|
24
|
+
if (Array.isArray(control.value)) {
|
|
25
|
+
acc[control.shaderParam] = control.value[0];
|
|
26
|
+
} else {
|
|
27
|
+
acc[control.shaderParam] = control.value;
|
|
28
|
+
}
|
|
29
|
+
return acc;
|
|
30
|
+
}, {});
|
|
31
|
+
return defaultValue;
|
|
32
|
+
},
|
|
33
|
+
(animator, scroll, value) => animator.getFXParams(value, scroll),
|
|
34
|
+
sectionId,
|
|
35
|
+
);
|
|
36
|
+
return {
|
|
37
|
+
fragmentShader,
|
|
38
|
+
controlsValues
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type FXData = {
|
|
43
|
+
fragmentShader: string;
|
|
44
|
+
controlsValues: Record<string, ControlValue>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type ControlValue = number;
|
|
@@ -10,14 +10,14 @@ export type AnimatorGetter<T> = (animator: Animator, scroll: number, value: T) =
|
|
|
10
10
|
type ItemParamGetter<T> = (item: ItemAny, layoutId: string | undefined) => T;
|
|
11
11
|
const emptyDeps: DependencyList = [];
|
|
12
12
|
|
|
13
|
-
export
|
|
13
|
+
export function useKeyframeValue<T>(
|
|
14
14
|
item: ItemAny,
|
|
15
15
|
type: KeyframeType,
|
|
16
16
|
itemParamsGetter: ItemParamGetter<T>,
|
|
17
17
|
animatorGetter: AnimatorGetter<T>,
|
|
18
18
|
sectionId: string,
|
|
19
19
|
deps: DependencyList = emptyDeps
|
|
20
|
-
): T
|
|
20
|
+
): T {
|
|
21
21
|
const animatorGetterRef = useRef(animatorGetter);
|
|
22
22
|
const itemParamsGetterRef = useRef(itemParamsGetter);
|
|
23
23
|
|
|
@@ -64,7 +64,7 @@ export const useKeyframeValue = <T>(
|
|
|
64
64
|
if (!articleRectObserver || !animator) return;
|
|
65
65
|
const scroll = articleRectObserver.getSectionScroll(sectionId);
|
|
66
66
|
handleKeyframeValue(scroll);
|
|
67
|
-
}, [articleRectObserver, handleKeyframeValue, animator])
|
|
67
|
+
}, [articleRectObserver, handleKeyframeValue, animator]);
|
|
68
68
|
|
|
69
69
|
useEffect(() => {
|
|
70
70
|
if (!articleRectObserver || !animator) return;
|
|
@@ -82,5 +82,4 @@ export const useKeyframeValue = <T>(
|
|
|
82
82
|
});
|
|
83
83
|
}, [handleKeyframeValue, articleRectObserver, animator]);
|
|
84
84
|
return keyframes.length ? adjustedValue : paramValue;
|
|
85
|
-
}
|
|
86
|
-
|
|
85
|
+
}
|
|
@@ -12,7 +12,7 @@ import { useImageFx } from '../../../utils/effects/useImageFx';
|
|
|
12
12
|
import { useElementRect } from '../../../utils/useElementRect';
|
|
13
13
|
import { useLayoutContext } from '../../useLayoutContext';
|
|
14
14
|
import { getStyleFromItemStateAndParams } from '../../../utils/getStyleFromItemStateAndParams';
|
|
15
|
-
import {
|
|
15
|
+
import { useItemFXData } from '../../../common/useItemFXData';
|
|
16
16
|
|
|
17
17
|
export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
18
18
|
const id = useId();
|
|
@@ -28,18 +28,12 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
28
28
|
const itemAngle = useItemAngle(item, sectionId);
|
|
29
29
|
const [wrapperRef, setWrapperRef] = useState<HTMLDivElement | null>(null);
|
|
30
30
|
useRegisterResize(wrapperRef, onResize);
|
|
31
|
-
const { url, hasGLEffect
|
|
31
|
+
const { url, hasGLEffect } = item.commonParams;
|
|
32
32
|
const fxCanvas = useRef<HTMLCanvasElement | null>(null);
|
|
33
33
|
const isInitialRef = useRef(true);
|
|
34
|
-
|
|
35
|
-
const controlsVariables = controls.map((c) => `uniform ${c.type} ${c.shaderParam};`)
|
|
36
|
-
.join('\n');
|
|
37
|
-
const controlValues = controls.reduce<Record<string, ControlValue>>((acc, control) => {
|
|
38
|
-
acc[control.shaderParam] = control.value;
|
|
39
|
-
return acc;
|
|
40
|
-
}, {});
|
|
34
|
+
|
|
41
35
|
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams];
|
|
42
|
-
const
|
|
36
|
+
const { controlsValues, fragmentShader } = useItemFXData(item, sectionId);
|
|
43
37
|
const area = layoutId ? item.area[layoutId] : null;
|
|
44
38
|
const exemplary = layouts?.find(l => l.id === layoutId)?.exemplary;
|
|
45
39
|
const width = area && exemplary ? area.width * exemplary : 0;
|
|
@@ -55,9 +49,8 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
55
49
|
!!(hasGLEffect && !isInitialRef.current),
|
|
56
50
|
{
|
|
57
51
|
imageUrl: url,
|
|
58
|
-
fragmentShader
|
|
59
|
-
|
|
60
|
-
controls: controlValues
|
|
52
|
+
fragmentShader,
|
|
53
|
+
controlsValues
|
|
61
54
|
},
|
|
62
55
|
width,
|
|
63
56
|
height
|
|
@@ -143,7 +136,7 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
143
136
|
box-sizing: border-box;
|
|
144
137
|
}
|
|
145
138
|
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams]) => {
|
|
146
|
-
|
|
139
|
+
return (`
|
|
147
140
|
.image-wrapper-${item.id} {
|
|
148
141
|
opacity: ${layoutParams.opacity};
|
|
149
142
|
transform: rotate(${area.angle}deg);
|
|
@@ -155,11 +148,9 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
155
148
|
border-width: ${layoutParams.strokeWidth * 100}vw;
|
|
156
149
|
}
|
|
157
150
|
`);
|
|
158
|
-
|
|
151
|
+
})}
|
|
159
152
|
`}</JSXStyle>
|
|
160
153
|
</>
|
|
161
154
|
</LinkWrapper>
|
|
162
155
|
);
|
|
163
156
|
};
|
|
164
|
-
|
|
165
|
-
type ControlValue = number | [number, number];
|
|
@@ -11,9 +11,9 @@ import { useRegisterResize } from '../../../common/useRegisterResize';
|
|
|
11
11
|
import { useLayoutContext } from '../../useLayoutContext';
|
|
12
12
|
import { ScrollPlaybackVideo } from '../../ScrollPlaybackVideo';
|
|
13
13
|
import { getStyleFromItemStateAndParams } from '../../../utils/getStyleFromItemStateAndParams';
|
|
14
|
-
import { baseVariables } from './shaderBaseVars';
|
|
15
14
|
import { useVideoFx } from '../../../utils/effects/useVideoFx';
|
|
16
15
|
import { useElementRect } from '../../../utils/useElementRect';
|
|
16
|
+
import { useItemFXData } from '../../../common/useItemFXData';
|
|
17
17
|
|
|
18
18
|
export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
19
19
|
const id = useId();
|
|
@@ -30,20 +30,13 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
30
30
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
31
31
|
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
32
32
|
const fxCanvas = useRef<HTMLCanvasElement | null>(null);
|
|
33
|
-
const { url, hasGLEffect
|
|
33
|
+
const { url, hasGLEffect } = item.commonParams;
|
|
34
34
|
const isInitialRef = useRef(true);
|
|
35
35
|
const area = layoutId ? item.area[layoutId] : null;
|
|
36
36
|
const exemplary = layouts?.find(l => l.id === layoutId)?.exemplary;
|
|
37
37
|
const width = area && exemplary ? area.width * exemplary : 0;
|
|
38
38
|
const height = area && exemplary ? area.height * exemplary : 0;
|
|
39
|
-
const
|
|
40
|
-
const controlsVariables = controls.map((c) => `uniform ${c.type} ${c.shaderParam};`)
|
|
41
|
-
.join('\n');
|
|
42
|
-
const controlValues = controls.reduce<Record<string, ControlValue>>((acc, control) => {
|
|
43
|
-
acc[control.shaderParam] = control.value;
|
|
44
|
-
return acc;
|
|
45
|
-
}, {});
|
|
46
|
-
const fullShaderCode = `${baseVariables}\n${controlsVariables}\n${fragmentShader}`;
|
|
39
|
+
const { controlsValues, fragmentShader } = useItemFXData(item, sectionId);
|
|
47
40
|
const rect = useElementRect(ref);
|
|
48
41
|
const rectWidth = Math.floor(rect?.width ?? 0);
|
|
49
42
|
const rectHeight = Math.floor(rect?.height ?? 0);
|
|
@@ -69,9 +62,8 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
69
62
|
!!(hasGLEffect && !isInitialRef.current),
|
|
70
63
|
{
|
|
71
64
|
videoUrl: url,
|
|
72
|
-
fragmentShader
|
|
73
|
-
|
|
74
|
-
controls: controlValues
|
|
65
|
+
fragmentShader,
|
|
66
|
+
controls: controlsValues
|
|
75
67
|
},
|
|
76
68
|
width,
|
|
77
69
|
height
|
|
@@ -191,5 +183,3 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
191
183
|
</LinkWrapper>
|
|
192
184
|
);
|
|
193
185
|
};
|
|
194
|
-
|
|
195
|
-
type ControlValue = number | [number, number];
|
|
@@ -3,7 +3,7 @@ import { useKeyframeValue } from '../../../common/useKeyframeValue';
|
|
|
3
3
|
import { useLayoutContext } from '../../useLayoutContext';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_COLOR = 'rgba(0, 0, 0, 1)';
|
|
6
|
-
export
|
|
6
|
+
export function useFileItem(item: ImageItem | VideoItem, sectionId: string) {
|
|
7
7
|
const layoutId = useLayoutContext();
|
|
8
8
|
const radius = useKeyframeValue(
|
|
9
9
|
item,
|
|
@@ -11,7 +11,7 @@ export const useFileItem = (item: ImageItem | VideoItem, sectionId: string) => {
|
|
|
11
11
|
(item, layoutId) => {
|
|
12
12
|
if (!layoutId) return;
|
|
13
13
|
const layoutParams = item.layoutParams[layoutId];
|
|
14
|
-
return
|
|
14
|
+
return 'radius' in layoutParams ? layoutParams.radius : 0;
|
|
15
15
|
},
|
|
16
16
|
(animator, scroll, value) => value !== undefined ? animator.getRadius({ radius: value }, scroll).radius : undefined,
|
|
17
17
|
sectionId,
|
|
@@ -70,4 +70,4 @@ export const useFileItem = (item: ImageItem | VideoItem, sectionId: string) => {
|
|
|
70
70
|
);
|
|
71
71
|
|
|
72
72
|
return { radius, strokeWidth, opacity, strokeColor, blur };
|
|
73
|
-
}
|
|
73
|
+
}
|
|
@@ -25,6 +25,7 @@ export class Animator {
|
|
|
25
25
|
private static pushKeyframeToMap<T extends KeyframeType>(keyframe: AnimationData<T>, map: KeyframesMap): void {
|
|
26
26
|
insertBin(map[keyframe.type], keyframe);
|
|
27
27
|
}
|
|
28
|
+
|
|
28
29
|
private keyframesMap: KeyframesMap = createKeyframesMap();
|
|
29
30
|
constructor(
|
|
30
31
|
private keyframes: AnimationData<KeyframeType>[]
|
|
@@ -32,6 +33,26 @@ export class Animator {
|
|
|
32
33
|
this.fillKeyframesMap();
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
getFXParams(
|
|
37
|
+
valuesMap: Record<string, number>,
|
|
38
|
+
pos: number
|
|
39
|
+
): KeyframeValueMap[KeyframeType.FXParams] {
|
|
40
|
+
const keyframes = this.keyframesMap[KeyframeType.FXParams];
|
|
41
|
+
if (!keyframes.length) return valuesMap;
|
|
42
|
+
if (keyframes.length === 1) {
|
|
43
|
+
const [keyframe] = keyframes;
|
|
44
|
+
return Object.entries(valuesMap).reduce<Record<string, number>>((acc, [key, fallbackValue]) => {
|
|
45
|
+
acc[key] = keyframe.value[key] ?? fallbackValue;
|
|
46
|
+
return acc;
|
|
47
|
+
}, {});
|
|
48
|
+
}
|
|
49
|
+
const { start, end } = this.getStartEnd<KeyframeType.FXParams>(pos, keyframes);
|
|
50
|
+
return Object.entries(valuesMap).reduce<Record<string, number>>((acc, [key, fallbackValue]) => {
|
|
51
|
+
acc[key] = rangeMap(pos, start.position, end.position, start.value[key] ?? fallbackValue, end.value[key] ?? fallbackValue, true);
|
|
52
|
+
return acc;
|
|
53
|
+
}, {});
|
|
54
|
+
}
|
|
55
|
+
|
|
35
56
|
getDimensions(
|
|
36
57
|
values: KeyframeValueMap[KeyframeType.Dimensions],
|
|
37
58
|
pos: number
|
|
@@ -302,7 +323,6 @@ export class Animator {
|
|
|
302
323
|
};
|
|
303
324
|
}
|
|
304
325
|
|
|
305
|
-
|
|
306
326
|
getStartEnd<T extends KeyframeType>(position: number, keyframes: AnimationData<T>[]): PositionKeyframes<T> {
|
|
307
327
|
const index = binSearchInsertAt(keyframes, { position }, compare);
|
|
308
328
|
const end = index === keyframes.length ? index - 1 : index;
|
|
@@ -330,7 +350,6 @@ export class Animator {
|
|
|
330
350
|
}
|
|
331
351
|
}
|
|
332
352
|
|
|
333
|
-
|
|
334
353
|
function createKeyframesMap(): KeyframesMap {
|
|
335
354
|
return {
|
|
336
355
|
[KeyframeType.Dimensions]: [],
|
|
@@ -346,6 +365,7 @@ function createKeyframesMap(): KeyframesMap {
|
|
|
346
365
|
[KeyframeType.BackdropBlur]: [],
|
|
347
366
|
[KeyframeType.LetterSpacing]: [],
|
|
348
367
|
[KeyframeType.WordSpacing]: [],
|
|
349
|
-
[KeyframeType.TextColor]: []
|
|
368
|
+
[KeyframeType.TextColor]: [],
|
|
369
|
+
[KeyframeType.FXParams]: []
|
|
350
370
|
};
|
|
351
371
|
}
|
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
import { useEffect, useMemo,
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { MediaEffect, ImageTextureManager } from '@cntrl-site/effects';
|
|
3
3
|
import { rangeMap } from '../rangeMap';
|
|
4
4
|
|
|
5
|
-
export interface FXCursor {
|
|
6
|
-
type: 'mouse' | 'manual';
|
|
7
|
-
x: number;
|
|
8
|
-
y: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
5
|
interface FxParams {
|
|
12
6
|
imageUrl?: string;
|
|
13
7
|
fragmentShader: string | null;
|
|
14
|
-
|
|
15
|
-
controls?: Record<string, number | [number, number]>;
|
|
8
|
+
controlsValues?: Record<string, number | [number, number]>;
|
|
16
9
|
}
|
|
17
10
|
|
|
18
11
|
const PATTERN_URL = 'https://cdn.cntrl.site/client-app-files/texture2.png';
|
|
@@ -24,21 +17,18 @@ export function useImageFx(
|
|
|
24
17
|
{
|
|
25
18
|
imageUrl,
|
|
26
19
|
fragmentShader,
|
|
27
|
-
|
|
28
|
-
controls
|
|
20
|
+
controlsValues
|
|
29
21
|
}: FxParams,
|
|
30
22
|
width: number,
|
|
31
23
|
height: number
|
|
32
24
|
): boolean {
|
|
33
25
|
const [isFXAllowed, setIsFXAllowed] = useState(true);
|
|
34
|
-
const mousePos = useRef<[number, number]>([0.0, 0.0]);
|
|
35
26
|
const imageTextureManager = useMemo(() => {
|
|
36
27
|
if (!imageUrl || !enabled) return;
|
|
37
28
|
return new ImageTextureManager(imageUrl);
|
|
38
29
|
}, [imageUrl, enabled]);
|
|
39
30
|
const imageFx = useMemo<MediaEffect | undefined>(() => {
|
|
40
|
-
if (!
|
|
41
|
-
const { type, x, y } = cursor;
|
|
31
|
+
if (!imageTextureManager) return;
|
|
42
32
|
return new MediaEffect(
|
|
43
33
|
imageTextureManager,
|
|
44
34
|
PATTERN_URL,
|
|
@@ -46,8 +36,8 @@ export function useImageFx(
|
|
|
46
36
|
fragmentShader!,
|
|
47
37
|
{
|
|
48
38
|
time: 0,
|
|
49
|
-
cursor:
|
|
50
|
-
...
|
|
39
|
+
cursor: [0, 0],
|
|
40
|
+
...controlsValues
|
|
51
41
|
},
|
|
52
42
|
width,
|
|
53
43
|
height
|
|
@@ -55,7 +45,14 @@ export function useImageFx(
|
|
|
55
45
|
}, [imageTextureManager, fragmentShader, width, height]);
|
|
56
46
|
|
|
57
47
|
useEffect(() => {
|
|
58
|
-
if (!
|
|
48
|
+
if (!imageFx || !controlsValues) return;
|
|
49
|
+
for (const [key, value] of Object.entries(controlsValues)) {
|
|
50
|
+
imageFx.setParam(key, value);
|
|
51
|
+
}
|
|
52
|
+
}, [imageFx, controlsValues]);
|
|
53
|
+
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (!canvas || !imageFx) return;
|
|
59
56
|
const handleMouseMove = (evt: MouseEvent) => {
|
|
60
57
|
const rect = canvas.getBoundingClientRect();
|
|
61
58
|
const x = rangeMap(evt.clientX, rect.left, rect.left + rect.width, 0, 1, true);
|
|
@@ -66,7 +63,7 @@ export function useImageFx(
|
|
|
66
63
|
return () => {
|
|
67
64
|
window.removeEventListener('mousemove', handleMouseMove);
|
|
68
65
|
};
|
|
69
|
-
}, [canvas, imageFx
|
|
66
|
+
}, [canvas, imageFx]);
|
|
70
67
|
|
|
71
68
|
useEffect(() => {
|
|
72
69
|
const gl = canvas?.getContext('webgl2');
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import { useEffect, useMemo,
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { MediaEffect, VideoTextureManager } from '@cntrl-site/effects';
|
|
3
3
|
import { rangeMap } from '../rangeMap';
|
|
4
4
|
|
|
5
|
-
export interface FXCursor {
|
|
6
|
-
type: 'mouse' | 'manual';
|
|
7
|
-
x: number;
|
|
8
|
-
y: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
5
|
interface FxParams {
|
|
12
6
|
videoUrl?: string;
|
|
13
7
|
fragmentShader: string | null;
|
|
14
|
-
cursor: FXCursor | null;
|
|
15
8
|
controls?: Record<string, number | [number, number]>;
|
|
16
9
|
}
|
|
17
10
|
|
|
@@ -24,7 +17,6 @@ export function useVideoFx(
|
|
|
24
17
|
{
|
|
25
18
|
videoUrl,
|
|
26
19
|
fragmentShader,
|
|
27
|
-
cursor,
|
|
28
20
|
controls
|
|
29
21
|
}: FxParams,
|
|
30
22
|
width: number,
|
|
@@ -33,7 +25,6 @@ export function useVideoFx(
|
|
|
33
25
|
const [isFXAllowed, setIsFXAllowed] = useState(true);
|
|
34
26
|
const [isReady, setIsReady] = useState(false);
|
|
35
27
|
const active = enabled && isReady;
|
|
36
|
-
const mousePos = useRef<[number, number]>([0.0, 0.0]);
|
|
37
28
|
const videoTextureManager = useMemo(() => {
|
|
38
29
|
if (!videoUrl || !enabled) return;
|
|
39
30
|
const handlePlayError = () => {
|
|
@@ -42,8 +33,7 @@ export function useVideoFx(
|
|
|
42
33
|
return new VideoTextureManager(videoUrl, handlePlayError);
|
|
43
34
|
}, [videoUrl, enabled]);
|
|
44
35
|
const videoFx = useMemo<MediaEffect | undefined>(() => {
|
|
45
|
-
if (!
|
|
46
|
-
const { type, x, y } = cursor;
|
|
36
|
+
if (!videoTextureManager) return;
|
|
47
37
|
return new MediaEffect(
|
|
48
38
|
videoTextureManager,
|
|
49
39
|
PATTERN_URL,
|
|
@@ -51,7 +41,7 @@ export function useVideoFx(
|
|
|
51
41
|
fragmentShader!,
|
|
52
42
|
{
|
|
53
43
|
time: 0,
|
|
54
|
-
cursor:
|
|
44
|
+
cursor: [0, 0],
|
|
55
45
|
...controls
|
|
56
46
|
},
|
|
57
47
|
width,
|
|
@@ -65,7 +55,7 @@ export function useVideoFx(
|
|
|
65
55
|
}, [videoTextureManager]);
|
|
66
56
|
|
|
67
57
|
useEffect(() => {
|
|
68
|
-
if (!
|
|
58
|
+
if (!canvas || !videoFx) return;
|
|
69
59
|
const handleMouseMove = (evt: MouseEvent) => {
|
|
70
60
|
const rect = canvas.getBoundingClientRect();
|
|
71
61
|
const x = rangeMap(evt.clientX, rect.left, rect.left + rect.width, 0, 1, true);
|
|
@@ -76,7 +66,7 @@ export function useVideoFx(
|
|
|
76
66
|
return () => {
|
|
77
67
|
window.removeEventListener('mousemove', handleMouseMove);
|
|
78
68
|
};
|
|
79
|
-
}, [canvas, videoFx
|
|
69
|
+
}, [canvas, videoFx]);
|
|
80
70
|
|
|
81
71
|
useEffect(() => {
|
|
82
72
|
const gl = canvas?.getContext('webgl2');
|
|
Binary file
|
|
Binary file
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.baseVariables = void 0;
|
|
4
|
-
exports.baseVariables = `precision mediump float;
|
|
5
|
-
uniform sampler2D u_image;
|
|
6
|
-
uniform sampler2D u_pattern;
|
|
7
|
-
uniform vec2 u_imgDimensions;
|
|
8
|
-
uniform vec2 u_patternDimensions;
|
|
9
|
-
uniform float u_time;
|
|
10
|
-
uniform vec2 u_cursor;
|
|
11
|
-
varying vec2 v_texCoord;`;
|