@cntrl-site/sdk-nextjs 0.21.7 → 0.23.0
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/cntrl-site-sdk-nextjs-0.23.0.tgz +0 -0
- package/lib/components/Item.js +3 -2
- package/lib/components/items/GroupItem.js +49 -0
- package/lib/components/items/VideoItem.js +44 -1
- package/lib/components/items/useGroupItem.js +16 -0
- package/package.json +2 -2
- package/src/components/Item.tsx +4 -2
- package/src/components/items/GroupItem.tsx +62 -0
- package/src/components/items/VideoItem.tsx +47 -1
- package/src/components/items/useGroupItem.ts +20 -0
- package/.idea/inspectionProfiles/Project_Default.xml +0 -15
|
Binary file
|
package/lib/components/Item.js
CHANGED
|
@@ -28,6 +28,7 @@ const getAnchoredItemTop_1 = require("../utils/getAnchoredItemTop");
|
|
|
28
28
|
const useLayoutContext_1 = require("./useLayoutContext");
|
|
29
29
|
const ArticleRectContext_1 = require("../provider/ArticleRectContext");
|
|
30
30
|
const useExemplary_1 = require("../common/useExemplary");
|
|
31
|
+
const GroupItem_1 = require("./items/GroupItem");
|
|
31
32
|
const itemsMap = {
|
|
32
33
|
[sdk_1.ArticleItemType.Rectangle]: RectangleItem_1.RectangleItem,
|
|
33
34
|
[sdk_1.ArticleItemType.Image]: ImageItem_1.ImageItem,
|
|
@@ -36,7 +37,7 @@ const itemsMap = {
|
|
|
36
37
|
[sdk_1.ArticleItemType.YoutubeEmbed]: YoutubeEmbed_1.YoutubeEmbedItem,
|
|
37
38
|
[sdk_1.ArticleItemType.VimeoEmbed]: VimeoEmbed_1.VimeoEmbedItem,
|
|
38
39
|
[sdk_1.ArticleItemType.Custom]: CustomItem_1.CustomItem,
|
|
39
|
-
[sdk_1.ArticleItemType.Group]:
|
|
40
|
+
[sdk_1.ArticleItemType.Group]: GroupItem_1.GroupItem
|
|
40
41
|
};
|
|
41
42
|
const RichTextWrapper = ({ isRichText, children }) => {
|
|
42
43
|
if (!isRichText)
|
|
@@ -107,7 +108,7 @@ const Item = ({ item, sectionId, articleHeight }) => {
|
|
|
107
108
|
height: `${sizingAxis.y === 'manual' ? `${height * 100}vw` : 'unset'}`,
|
|
108
109
|
transform: `scale(${scale})`,
|
|
109
110
|
transformOrigin: ScaleAnchorMap_1.ScaleAnchorMap[scaleAnchor]
|
|
110
|
-
} }, { children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, onResize: handleItemResize }) })) })) })), (0, jsx_runtime_1.jsx)(style_1.default, Object.assign({ id: id }, { children: `
|
|
111
|
+
} }, { children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, onResize: handleItemResize, articleHeight: articleHeight }) })) })) })), (0, jsx_runtime_1.jsx)(style_1.default, Object.assign({ id: id }, { children: `
|
|
111
112
|
${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, hidden, hoverParams, sticky, sectionHeight, layoutParams]) => {
|
|
112
113
|
const sizingAxis = parseSizing(layoutParams.sizing);
|
|
113
114
|
return (`
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GroupItem = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const Item_1 = require("../Item");
|
|
10
|
+
const style_1 = __importDefault(require("styled-jsx/style"));
|
|
11
|
+
const sdk_1 = require("@cntrl-site/sdk");
|
|
12
|
+
const HoverStyles_1 = require("../../utils/HoverStyles/HoverStyles");
|
|
13
|
+
const LinkWrapper_1 = require("../LinkWrapper");
|
|
14
|
+
const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
15
|
+
const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
16
|
+
const useItemAngle_1 = require("../useItemAngle");
|
|
17
|
+
const useGroupItem_1 = require("./useGroupItem");
|
|
18
|
+
const GroupItem = ({ item, sectionId, onResize, articleHeight }) => {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
const id = (0, react_1.useId)();
|
|
21
|
+
const { items } = item;
|
|
22
|
+
const angle = (0, useItemAngle_1.useItemAngle)(item, sectionId);
|
|
23
|
+
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
24
|
+
const { opacity } = (0, useGroupItem_1.useGroupItem)(item, sectionId);
|
|
25
|
+
const [ref, setRef] = (0, react_1.useState)(null);
|
|
26
|
+
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
27
|
+
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, Object.assign({ url: (_a = item.link) === null || _a === void 0 ? void 0 : _a.url, target: (_b = item.link) === null || _b === void 0 ? void 0 : _b.target }, { children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: `group-${item.id}`, ref: setRef, style: {
|
|
28
|
+
opacity,
|
|
29
|
+
transform: `rotate(${angle}deg)`,
|
|
30
|
+
} }, { children: items && items.map(item => ((0, jsx_runtime_1.jsx)(Item_1.Item, { item: item, sectionId: sectionId, articleHeight: articleHeight }, item.id))) })), (0, jsx_runtime_1.jsx)(style_1.default, Object.assign({ id: id }, { children: `
|
|
31
|
+
.group-${item.id} {
|
|
32
|
+
position: absolute;
|
|
33
|
+
width: 100%;
|
|
34
|
+
height: 100%;
|
|
35
|
+
box-sizing: border-box;
|
|
36
|
+
}
|
|
37
|
+
${(0, sdk_1.getLayoutStyles)(layouts, [item.state.hover], ([hoverParams]) => {
|
|
38
|
+
return (`
|
|
39
|
+
.group-${item.id} {
|
|
40
|
+
transition: ${(0, HoverStyles_1.getTransitions)(['opacity'], hoverParams)};
|
|
41
|
+
}
|
|
42
|
+
.group-${item.id}:hover {
|
|
43
|
+
${(0, HoverStyles_1.getHoverStyles)(['opacity'], hoverParams)}
|
|
44
|
+
}
|
|
45
|
+
`);
|
|
46
|
+
})}
|
|
47
|
+
` }))] }) })));
|
|
48
|
+
};
|
|
49
|
+
exports.GroupItem = GroupItem;
|
|
@@ -15,6 +15,12 @@ const useItemAngle_1 = require("../useItemAngle");
|
|
|
15
15
|
const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
16
16
|
const HoverStyles_1 = require("../../utils/HoverStyles/HoverStyles");
|
|
17
17
|
const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
18
|
+
const rangeMap_1 = require("../../utils/rangeMap");
|
|
19
|
+
const ArticleRectContext_1 = require("../../provider/ArticleRectContext");
|
|
20
|
+
const useLayoutContext_1 = require("../useLayoutContext");
|
|
21
|
+
// To prevent video behaviour that drops to the first frame
|
|
22
|
+
// when close to the end
|
|
23
|
+
const SCROLL_TIME_SHIFT = 0.1;
|
|
18
24
|
const VideoItem = ({ item, sectionId, onResize }) => {
|
|
19
25
|
var _a, _b;
|
|
20
26
|
const id = (0, react_1.useId)();
|
|
@@ -23,12 +29,46 @@ const VideoItem = ({ item, sectionId, onResize }) => {
|
|
|
23
29
|
const angle = (0, useItemAngle_1.useItemAngle)(item, sectionId);
|
|
24
30
|
const borderColor = (0, react_1.useMemo)(() => color_1.CntrlColor.parse(strokeColor), [strokeColor]);
|
|
25
31
|
const [ref, setRef] = (0, react_1.useState)(null);
|
|
32
|
+
const videoRef = (0, react_1.useRef)(null);
|
|
33
|
+
const articleRectObserver = (0, react_1.useContext)(ArticleRectContext_1.ArticleRectContext);
|
|
34
|
+
const rafId = (0, react_1.useRef)();
|
|
35
|
+
const layoutId = (0, useLayoutContext_1.useLayoutContext)();
|
|
36
|
+
const scrollPlayback = item.layoutParams[layoutId].scrollPlayback;
|
|
37
|
+
(0, react_1.useEffect)(() => {
|
|
38
|
+
const video = videoRef.current;
|
|
39
|
+
if (!video || !scrollPlayback) {
|
|
40
|
+
video === null || video === void 0 ? void 0 : video.play();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
video === null || video === void 0 ? void 0 : video.pause();
|
|
44
|
+
const scrollVideo = () => {
|
|
45
|
+
rafId.current = window.requestAnimationFrame(scrollVideo);
|
|
46
|
+
if (!articleRectObserver)
|
|
47
|
+
return;
|
|
48
|
+
const scrollPos = articleRectObserver.getSectionScroll(sectionId);
|
|
49
|
+
if (!video.duration)
|
|
50
|
+
return;
|
|
51
|
+
const time = (0, rangeMap_1.rangeMap)(scrollPos, scrollPlayback.from, scrollPlayback.to, 0, video.duration, true);
|
|
52
|
+
if (scrollPos > scrollPlayback.from && scrollPos < scrollPlayback.to) {
|
|
53
|
+
if (toFixed(video.currentTime) === toFixed(time - SCROLL_TIME_SHIFT))
|
|
54
|
+
return;
|
|
55
|
+
video.currentTime = Math.max(0, time - SCROLL_TIME_SHIFT);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
rafId.current = window.requestAnimationFrame(scrollVideo);
|
|
59
|
+
return () => {
|
|
60
|
+
if (rafId.current) {
|
|
61
|
+
window.cancelAnimationFrame(rafId.current);
|
|
62
|
+
rafId.current = undefined;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}, [scrollPlayback]);
|
|
26
66
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
27
67
|
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, Object.assign({ url: (_a = item.link) === null || _a === void 0 ? void 0 : _a.url, target: (_b = item.link) === null || _b === void 0 ? void 0 : _b.target }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: `video-wrapper-${item.id}`, ref: setRef, style: {
|
|
28
68
|
opacity: `${opacity}`,
|
|
29
69
|
transform: `rotate(${angle}deg)`,
|
|
30
70
|
filter: `blur(${blur * 100}vw)`
|
|
31
|
-
} }, { children: (0, jsx_runtime_1.jsx)("video", Object.assign({ autoPlay: true, muted: true, loop: true, playsInline: true, className: `video video-${item.id}`, style: {
|
|
71
|
+
} }, { children: (0, jsx_runtime_1.jsx)("video", Object.assign({ ref: videoRef, autoPlay: true, muted: true, loop: true, playsInline: true, className: `video video-${item.id}`, style: {
|
|
32
72
|
borderRadius: `${radius * 100}vw`,
|
|
33
73
|
borderWidth: `${strokeWidth * 100}vw`,
|
|
34
74
|
borderColor: `${borderColor.toCss()}`
|
|
@@ -76,3 +116,6 @@ const VideoItem = ({ item, sectionId, onResize }) => {
|
|
|
76
116
|
` }))] })));
|
|
77
117
|
};
|
|
78
118
|
exports.VideoItem = VideoItem;
|
|
119
|
+
function toFixed(num) {
|
|
120
|
+
return Number(num.toFixed(5));
|
|
121
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useGroupItem = void 0;
|
|
4
|
+
const useKeyframeValue_1 = require("../../common/useKeyframeValue");
|
|
5
|
+
const useLayoutContext_1 = require("../useLayoutContext");
|
|
6
|
+
function useGroupItem(item, sectionId) {
|
|
7
|
+
const layoutId = (0, useLayoutContext_1.useLayoutContext)();
|
|
8
|
+
const opacity = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
|
|
9
|
+
if (!layoutId)
|
|
10
|
+
return 0;
|
|
11
|
+
const layoutParams = item.layoutParams[layoutId];
|
|
12
|
+
return 'opacity' in layoutParams ? layoutParams.opacity : 0;
|
|
13
|
+
}, (animator, scroll, value) => animator.getOpacity({ opacity: value }, scroll).opacity, sectionId, [layoutId]);
|
|
14
|
+
return { opacity };
|
|
15
|
+
}
|
|
16
|
+
exports.useGroupItem = useGroupItem;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cntrl-site/sdk-nextjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "SDK for Next.js",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@cntrl-site/color": "^1.0.0",
|
|
25
25
|
"@cntrl-site/effects": "^1.0.5-1",
|
|
26
|
-
"@cntrl-site/sdk": "^1.
|
|
26
|
+
"@cntrl-site/sdk": "^1.6.0",
|
|
27
27
|
"@types/vimeo__player": "^2.18.0",
|
|
28
28
|
"@vimeo/player": "^2.20.1",
|
|
29
29
|
"html-react-parser": "^3.0.1",
|
package/src/components/Item.tsx
CHANGED
|
@@ -27,11 +27,13 @@ import { getAnchoredItemTop } from '../utils/getAnchoredItemTop';
|
|
|
27
27
|
import { useLayoutContext } from './useLayoutContext';
|
|
28
28
|
import { ArticleRectContext } from "../provider/ArticleRectContext";
|
|
29
29
|
import { useExemplary } from "../common/useExemplary";
|
|
30
|
+
import { GroupItem } from './items/GroupItem';
|
|
30
31
|
|
|
31
32
|
export interface ItemProps<I extends ItemAny> {
|
|
32
33
|
item: I;
|
|
33
34
|
sectionId: string;
|
|
34
35
|
onResize?: (height: number) => void;
|
|
36
|
+
articleHeight: number;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export interface ItemWrapperProps extends ItemProps<ItemAny> {
|
|
@@ -46,7 +48,7 @@ const itemsMap: Record<ArticleItemType, ComponentType<ItemProps<any>>> = {
|
|
|
46
48
|
[ArticleItemType.YoutubeEmbed]: YoutubeEmbedItem,
|
|
47
49
|
[ArticleItemType.VimeoEmbed]: VimeoEmbedItem,
|
|
48
50
|
[ArticleItemType.Custom]: CustomItem,
|
|
49
|
-
[ArticleItemType.Group]:
|
|
51
|
+
[ArticleItemType.Group]: GroupItem
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
interface RTWrapperProps {
|
|
@@ -147,7 +149,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight }) =
|
|
|
147
149
|
transformOrigin: ScaleAnchorMap[scaleAnchor]
|
|
148
150
|
}}
|
|
149
151
|
>
|
|
150
|
-
<ItemComponent item={item} sectionId={sectionId} onResize={handleItemResize} />
|
|
152
|
+
<ItemComponent item={item} sectionId={sectionId} onResize={handleItemResize} articleHeight={articleHeight} />
|
|
151
153
|
</div>
|
|
152
154
|
</RichTextWrapper>
|
|
153
155
|
</div>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React, { FC, useId, useState } from 'react';
|
|
2
|
+
import { Item, ItemProps } from '../Item';
|
|
3
|
+
import JSXStyle from 'styled-jsx/style';
|
|
4
|
+
import { ArticleItemType, getLayoutStyles, GroupItem as TGroupItem } from '@cntrl-site/sdk';
|
|
5
|
+
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
6
|
+
import { LinkWrapper } from '../LinkWrapper';
|
|
7
|
+
import { useRegisterResize } from '../../common/useRegisterResize';
|
|
8
|
+
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
9
|
+
import { useItemAngle } from '../useItemAngle';
|
|
10
|
+
import { useGroupItem } from './useGroupItem';
|
|
11
|
+
|
|
12
|
+
export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize, articleHeight }) => {
|
|
13
|
+
const id = useId();
|
|
14
|
+
const { items } = item;
|
|
15
|
+
const angle = useItemAngle(item, sectionId);
|
|
16
|
+
const { layouts } = useCntrlContext();
|
|
17
|
+
const { opacity } = useGroupItem(item, sectionId);
|
|
18
|
+
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
19
|
+
useRegisterResize(ref, onResize);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
23
|
+
<>
|
|
24
|
+
<div
|
|
25
|
+
className={`group-${item.id}`}
|
|
26
|
+
ref={setRef}
|
|
27
|
+
style={{
|
|
28
|
+
opacity,
|
|
29
|
+
transform: `rotate(${angle}deg)`,
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
32
|
+
{items && items.map(item => (
|
|
33
|
+
<Item
|
|
34
|
+
item={item}
|
|
35
|
+
key={item.id}
|
|
36
|
+
sectionId={sectionId}
|
|
37
|
+
articleHeight={articleHeight}
|
|
38
|
+
/>
|
|
39
|
+
))}
|
|
40
|
+
</div>
|
|
41
|
+
<JSXStyle id={id}>{`
|
|
42
|
+
.group-${item.id} {
|
|
43
|
+
position: absolute;
|
|
44
|
+
width: 100%;
|
|
45
|
+
height: 100%;
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
}
|
|
48
|
+
${getLayoutStyles(layouts, [item.state.hover], ([hoverParams]) => {
|
|
49
|
+
return (`
|
|
50
|
+
.group-${item.id} {
|
|
51
|
+
transition: ${getTransitions<ArticleItemType.Group>(['opacity'], hoverParams)};
|
|
52
|
+
}
|
|
53
|
+
.group-${item.id}:hover {
|
|
54
|
+
${getHoverStyles<ArticleItemType.Group>(['opacity'], hoverParams)}
|
|
55
|
+
}
|
|
56
|
+
`);
|
|
57
|
+
})}
|
|
58
|
+
`}</JSXStyle>
|
|
59
|
+
</>
|
|
60
|
+
</LinkWrapper>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FC, useId, useMemo, useState } from 'react';
|
|
1
|
+
import { FC, useContext, useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import JSXStyle from 'styled-jsx/style';
|
|
3
3
|
import { CntrlColor } from '@cntrl-site/color';
|
|
4
4
|
import { ArticleItemType, getLayoutStyles, VideoItem as TVideoItem } from '@cntrl-site/sdk';
|
|
@@ -9,6 +9,13 @@ import { useItemAngle } from '../useItemAngle';
|
|
|
9
9
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
10
10
|
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
11
11
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
12
|
+
import { rangeMap } from '../../utils/rangeMap';
|
|
13
|
+
import { ArticleRectContext } from '../../provider/ArticleRectContext';
|
|
14
|
+
import { useLayoutContext } from '../useLayoutContext';
|
|
15
|
+
|
|
16
|
+
// To prevent video behaviour that drops to the first frame
|
|
17
|
+
// when close to the end
|
|
18
|
+
const SCROLL_TIME_SHIFT = 0.1;
|
|
12
19
|
|
|
13
20
|
export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize }) => {
|
|
14
21
|
const id = useId();
|
|
@@ -17,6 +24,40 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
17
24
|
const angle = useItemAngle(item, sectionId);
|
|
18
25
|
const borderColor = useMemo(() => CntrlColor.parse(strokeColor), [strokeColor]);
|
|
19
26
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
27
|
+
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
28
|
+
const articleRectObserver = useContext(ArticleRectContext);
|
|
29
|
+
const rafId = useRef<number | undefined>();
|
|
30
|
+
const layoutId = useLayoutContext();
|
|
31
|
+
const scrollPlayback = item.layoutParams[layoutId!].scrollPlayback
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const video = videoRef.current;
|
|
35
|
+
if (!video || !scrollPlayback) {
|
|
36
|
+
video?.play();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
video?.pause();
|
|
40
|
+
const scrollVideo = () => {
|
|
41
|
+
rafId.current = window.requestAnimationFrame(scrollVideo);
|
|
42
|
+
if (!articleRectObserver) return;
|
|
43
|
+
const scrollPos = articleRectObserver.getSectionScroll(sectionId);
|
|
44
|
+
if (!video.duration) return;
|
|
45
|
+
const time = rangeMap(scrollPos, scrollPlayback.from, scrollPlayback.to, 0, video.duration, true);
|
|
46
|
+
if (scrollPos > scrollPlayback.from && scrollPos < scrollPlayback.to) {
|
|
47
|
+
if (toFixed(video.currentTime) === toFixed(time - SCROLL_TIME_SHIFT)) return;
|
|
48
|
+
video.currentTime = Math.max(0, time - SCROLL_TIME_SHIFT);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
rafId.current = window.requestAnimationFrame(scrollVideo);
|
|
52
|
+
|
|
53
|
+
return () => {
|
|
54
|
+
if (rafId.current) {
|
|
55
|
+
window.cancelAnimationFrame(rafId.current);
|
|
56
|
+
rafId.current = undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}, [scrollPlayback]);
|
|
60
|
+
|
|
20
61
|
useRegisterResize(ref, onResize);
|
|
21
62
|
return (
|
|
22
63
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
@@ -30,6 +71,7 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
30
71
|
}}
|
|
31
72
|
>
|
|
32
73
|
<video
|
|
74
|
+
ref={videoRef}
|
|
33
75
|
autoPlay
|
|
34
76
|
muted
|
|
35
77
|
loop
|
|
@@ -89,3 +131,7 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
89
131
|
</LinkWrapper>
|
|
90
132
|
);
|
|
91
133
|
};
|
|
134
|
+
|
|
135
|
+
function toFixed(num: number) {
|
|
136
|
+
return Number(num.toFixed(5));
|
|
137
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useKeyframeValue } from '../../common/useKeyframeValue';
|
|
2
|
+
import { GroupItem } from '@cntrl-site/sdk';
|
|
3
|
+
import { useLayoutContext } from '../useLayoutContext';
|
|
4
|
+
|
|
5
|
+
export function useGroupItem(item: GroupItem, sectionId: string) {
|
|
6
|
+
const layoutId = useLayoutContext();
|
|
7
|
+
const opacity = useKeyframeValue(
|
|
8
|
+
item,
|
|
9
|
+
(item, layoutId) => {
|
|
10
|
+
if (!layoutId) return 0;
|
|
11
|
+
const layoutParams = item.layoutParams[layoutId];
|
|
12
|
+
return 'opacity' in layoutParams ? layoutParams.opacity : 0;
|
|
13
|
+
},
|
|
14
|
+
(animator, scroll, value) => animator.getOpacity({ opacity: value }, scroll).opacity,
|
|
15
|
+
sectionId,
|
|
16
|
+
[layoutId]
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return { opacity };
|
|
20
|
+
}
|
|
@@ -1,15 +0,0 @@
|
|
|
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>
|