@cntrl-site/sdk-nextjs 0.22.0 → 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.
@@ -0,0 +1,5 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <state>
3
+ <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
4
+ </state>
5
+ </component>
Binary file
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "0.22.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.5.5",
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",
@@ -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
+ }
Binary file