@cntrl-site/sdk-nextjs 1.8.18 → 1.8.19
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-1.8.19.tgz +0 -0
- package/lib/components/items/FileItem/PlayIcon.js +8 -0
- package/lib/components/items/FileItem/VideoItem.js +59 -11
- package/package.json +1 -1
- package/src/components/items/FileItem/PlayIcon.tsx +17 -0
- package/src/components/items/FileItem/VideoItem.tsx +53 -2
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlayIcon = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const PlayIcon = ({ className, onClick }) => {
|
|
6
|
+
return ((0, jsx_runtime_1.jsx)("svg", { height: "32px", version: "1.1", viewBox: "0 0 32 32", width: "32px", className: className, onClick: onClick, children: (0, jsx_runtime_1.jsx)("g", { id: "play_x5F_alt", children: (0, jsx_runtime_1.jsx)("path", { fill: "#4E4E50", d: "M16,0C7.164,0,0,7.164,0,16s7.164,16,16,16s16-7.164,16-16S24.836,0,16,0z M10,24V8l16.008,8L10,24z " }) }) }));
|
|
7
|
+
};
|
|
8
|
+
exports.PlayIcon = PlayIcon;
|
|
@@ -20,6 +20,7 @@ const getStyleFromItemStateAndParams_1 = require("../../../utils/getStyleFromIte
|
|
|
20
20
|
const useVideoFx_1 = require("../../../utils/effects/useVideoFx");
|
|
21
21
|
const useElementRect_1 = require("../../../utils/useElementRect");
|
|
22
22
|
const useItemFXData_1 = require("../../../common/useItemFXData");
|
|
23
|
+
const PlayIcon_1 = require("./PlayIcon");
|
|
23
24
|
const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
24
25
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
25
26
|
const id = (0, react_1.useId)();
|
|
@@ -30,6 +31,8 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
30
31
|
const [ref, setRef] = (0, react_1.useState)(null);
|
|
31
32
|
const videoRef = (0, react_1.useRef)(null);
|
|
32
33
|
const fxCanvas = (0, react_1.useRef)(null);
|
|
34
|
+
const [isPlaying, setIsPlaying] = (0, react_1.useState)(false);
|
|
35
|
+
const [isEventTriggered, setIsEventTriggered] = (0, react_1.useState)(false);
|
|
33
36
|
const { url, hasGLEffect } = item.commonParams;
|
|
34
37
|
const isInitialRef = (0, react_1.useRef)(true);
|
|
35
38
|
const area = layoutId ? item.area[layoutId] : null;
|
|
@@ -69,17 +72,45 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
69
72
|
(0, react_1.useEffect)(() => {
|
|
70
73
|
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
71
74
|
}, [isInteractive, onVisibilityChange]);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
const playVideo = () => {
|
|
76
|
+
if (videoRef.current) {
|
|
77
|
+
videoRef.current.play();
|
|
78
|
+
setIsEventTriggered(true);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
(0, react_1.useEffect)(() => {
|
|
82
|
+
if (!isEventTriggered || !ref)
|
|
83
|
+
return;
|
|
84
|
+
const intersectionObserver = new IntersectionObserver((entries) => {
|
|
85
|
+
entries.forEach((entry) => {
|
|
86
|
+
if (!videoRef.current)
|
|
87
|
+
return;
|
|
88
|
+
if (entry.isIntersecting) {
|
|
89
|
+
videoRef.current.play();
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
videoRef.current.pause();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
intersectionObserver.observe(ref);
|
|
97
|
+
return () => {
|
|
98
|
+
intersectionObserver.disconnect();
|
|
99
|
+
};
|
|
100
|
+
}, [isEventTriggered, ref]);
|
|
101
|
+
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (_l = item.link) === null || _l === void 0 ? void 0 : _l.url, target: (_m = item.link) === null || _m === void 0 ? void 0 : _m.target, children: [(0, jsx_runtime_1.jsxs)("div", { className: `video-wrapper-${item.id}`, ref: setRef, style: Object.assign(Object.assign(Object.assign(Object.assign({}, (opacity !== undefined ? { opacity } : {})), (angle !== undefined ? { transform: `rotate(${angle}deg) translateZ(0)` } : {})), (blur !== undefined ? { filter: `blur(${blur * 100}vw)` } : {})), { transition: (_o = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.transition) !== null && _o !== void 0 ? _o : 'none' }), children: [!isPlaying && ((0, jsx_runtime_1.jsx)("div", { className: `play-btn-wrapper-${item.id}`, children: (0, jsx_runtime_1.jsx)(PlayIcon_1.PlayIcon, { className: `play-btn-${item.id}`, onClick: playVideo }) })), hasScrollPlayback
|
|
102
|
+
? ((0, jsx_runtime_1.jsx)(ScrollPlaybackVideo_1.ScrollPlaybackVideo, { sectionId: sectionId, src: item.commonParams.url, playbackParams: scrollPlayback, style: inlineStyles, className: `video video-playback-wrapper video-${item.id}` }))
|
|
103
|
+
: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: hasGLEffect && isFXAllowed
|
|
104
|
+
? ((0, jsx_runtime_1.jsx)("canvas", { style: inlineStyles, ref: fxCanvas, className: `video-canvas video-${item.id}`, width: rectWidth, height: rectHeight }))
|
|
105
|
+
: ((0, jsx_runtime_1.jsx)("video", { poster: (_p = item.commonParams.coverUrl) !== null && _p !== void 0 ? _p : '', ref: videoRef, controls: true, onPlay: () => {
|
|
106
|
+
setIsPlaying(true);
|
|
107
|
+
console.log('play');
|
|
108
|
+
}, onPause: () => {
|
|
109
|
+
setIsPlaying(false);
|
|
110
|
+
console.log('pause');
|
|
111
|
+
}, onEnded: () => {
|
|
112
|
+
console.log('ended');
|
|
113
|
+
}, loop: true, playsInline: true, className: `video video-${item.id}`, style: inlineStyles, children: (0, jsx_runtime_1.jsx)("source", { src: item.commonParams.url }) })) }))] }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
83
114
|
.video-wrapper-${item.id} {
|
|
84
115
|
position: absolute;
|
|
85
116
|
overflow: hidden;
|
|
@@ -88,6 +119,23 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
88
119
|
box-sizing: border-box;
|
|
89
120
|
opacity: ${opacity};
|
|
90
121
|
}
|
|
122
|
+
.play-btn-wrapper-${item.id} {
|
|
123
|
+
position: absolute;
|
|
124
|
+
top: 0;
|
|
125
|
+
left: 0;
|
|
126
|
+
width: 100%;
|
|
127
|
+
display: flex;
|
|
128
|
+
justify-content: center;
|
|
129
|
+
align-items: center;
|
|
130
|
+
height: 100%;
|
|
131
|
+
}
|
|
132
|
+
.play-btn-${item.id} {
|
|
133
|
+
width: 100px;
|
|
134
|
+
position: relative;
|
|
135
|
+
z-index: 1;
|
|
136
|
+
pointer-events: auto;
|
|
137
|
+
height: 100px;
|
|
138
|
+
}
|
|
91
139
|
.video {
|
|
92
140
|
width: 100%;
|
|
93
141
|
height: 100%;
|
package/package.json
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
interface Props {
|
|
4
|
+
className?: string;
|
|
5
|
+
onClick?: () => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const PlayIcon: FC<Props> = ({ className, onClick }) => {
|
|
9
|
+
return (
|
|
10
|
+
<svg height="32px" version="1.1" viewBox="0 0 32 32" width="32px" className={className} onClick={onClick}>
|
|
11
|
+
<g id="play_x5F_alt">
|
|
12
|
+
<path fill="#4E4E50" d="M16,0C7.164,0,0,7.164,0,16s7.164,16,16,16s16-7.164,16-16S24.836,0,16,0z M10,24V8l16.008,8L10,24z " />
|
|
13
|
+
</g>
|
|
14
|
+
</svg>
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
@@ -14,6 +14,7 @@ import { getStyleFromItemStateAndParams } from '../../../utils/getStyleFromItemS
|
|
|
14
14
|
import { useVideoFx } from '../../../utils/effects/useVideoFx';
|
|
15
15
|
import { useElementRect } from '../../../utils/useElementRect';
|
|
16
16
|
import { useItemFXData } from '../../../common/useItemFXData';
|
|
17
|
+
import { PlayIcon } from './PlayIcon';
|
|
17
18
|
|
|
18
19
|
export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
19
20
|
const id = useId();
|
|
@@ -30,6 +31,8 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
30
31
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
31
32
|
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
32
33
|
const fxCanvas = useRef<HTMLCanvasElement | null>(null);
|
|
34
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
35
|
+
const [isEventTriggered, setIsEventTriggered] = useState(false);
|
|
33
36
|
const { url, hasGLEffect } = item.commonParams;
|
|
34
37
|
const isInitialRef = useRef(true);
|
|
35
38
|
const area = layoutId ? item.area[layoutId] : null;
|
|
@@ -80,6 +83,31 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
80
83
|
onVisibilityChange?.(isInteractive);
|
|
81
84
|
}, [isInteractive, onVisibilityChange]);
|
|
82
85
|
|
|
86
|
+
const playVideo = () => {
|
|
87
|
+
if (videoRef.current) {
|
|
88
|
+
videoRef.current.play();
|
|
89
|
+
setIsEventTriggered(true);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (!isEventTriggered || !ref) return;
|
|
95
|
+
const intersectionObserver = new IntersectionObserver((entries) => {
|
|
96
|
+
entries.forEach((entry) => {
|
|
97
|
+
if (!videoRef.current) return;
|
|
98
|
+
if (entry.isIntersecting) {
|
|
99
|
+
videoRef.current.play();
|
|
100
|
+
} else {
|
|
101
|
+
videoRef.current.pause();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
intersectionObserver.observe(ref);
|
|
106
|
+
return () => {
|
|
107
|
+
intersectionObserver.disconnect();
|
|
108
|
+
};
|
|
109
|
+
}, [isEventTriggered, ref]);
|
|
110
|
+
|
|
83
111
|
return (
|
|
84
112
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
85
113
|
<div
|
|
@@ -92,6 +120,11 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
92
120
|
transition: wrapperStateParams?.transition ?? 'none'
|
|
93
121
|
}}
|
|
94
122
|
>
|
|
123
|
+
{!isPlaying && (
|
|
124
|
+
<div className={`play-btn-wrapper-${item.id}`}>
|
|
125
|
+
<PlayIcon className={`play-btn-${item.id}`} onClick={playVideo} />
|
|
126
|
+
</div>
|
|
127
|
+
)}
|
|
95
128
|
{hasScrollPlayback
|
|
96
129
|
? (
|
|
97
130
|
<ScrollPlaybackVideo
|
|
@@ -118,12 +151,13 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
118
151
|
<video
|
|
119
152
|
poster={item.commonParams.coverUrl ?? ''}
|
|
120
153
|
ref={videoRef}
|
|
121
|
-
|
|
122
|
-
muted
|
|
154
|
+
controls={true}
|
|
123
155
|
onPlay={() => {
|
|
156
|
+
setIsPlaying(true);
|
|
124
157
|
console.log('play');
|
|
125
158
|
}}
|
|
126
159
|
onPause={() => {
|
|
160
|
+
setIsPlaying(false);
|
|
127
161
|
console.log('pause');
|
|
128
162
|
}}
|
|
129
163
|
onEnded={() => {
|
|
@@ -150,6 +184,23 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
150
184
|
box-sizing: border-box;
|
|
151
185
|
opacity: ${opacity};
|
|
152
186
|
}
|
|
187
|
+
.play-btn-wrapper-${item.id} {
|
|
188
|
+
position: absolute;
|
|
189
|
+
top: 0;
|
|
190
|
+
left: 0;
|
|
191
|
+
width: 100%;
|
|
192
|
+
display: flex;
|
|
193
|
+
justify-content: center;
|
|
194
|
+
align-items: center;
|
|
195
|
+
height: 100%;
|
|
196
|
+
}
|
|
197
|
+
.play-btn-${item.id} {
|
|
198
|
+
width: 100px;
|
|
199
|
+
position: relative;
|
|
200
|
+
z-index: 1;
|
|
201
|
+
pointer-events: auto;
|
|
202
|
+
height: 100px;
|
|
203
|
+
}
|
|
153
204
|
.video {
|
|
154
205
|
width: 100%;
|
|
155
206
|
height: 100%;
|