@cntrl-site/sdk-nextjs 0.4.1 → 0.4.2
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.4.1.tgz +0 -0
- package/lib/components/items/ImageItem.js +19 -23
- package/lib/components/items/RectangleItem.js +4 -8
- package/lib/components/items/VideoItem.js +21 -23
- package/lib/components/items/useFileItem.js +14 -1
- package/lib/components/items/useRectangleItem.js +7 -1
- package/lib/utils/Animator/Animator.js +33 -1
- package/package.json +5 -5
- package/src/components/items/ImageItem.tsx +20 -25
- package/src/components/items/RectangleItem.tsx +5 -9
- package/src/components/items/VideoItem.tsx +21 -25
- package/src/components/items/useFileItem.ts +24 -1
- package/src/components/items/useRectangleItem.ts +10 -1
- package/src/utils/Animator/Animator.ts +41 -3
|
Binary file
|
|
@@ -2,35 +2,31 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ImageItem = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const sdk_1 = require("@cntrl-site/sdk");
|
|
6
5
|
const LinkWrapper_1 = require("../LinkWrapper");
|
|
7
|
-
const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
8
6
|
const useFileItem_1 = require("./useFileItem");
|
|
9
7
|
const ImageItem = ({ item }) => {
|
|
10
|
-
const {
|
|
11
|
-
const { radius, strokeWidth } = (0, useFileItem_1.useFileItem)(item);
|
|
8
|
+
const { radius, strokeWidth, opacity, strokeColor } = (0, useFileItem_1.useFileItem)(item);
|
|
12
9
|
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `image-wrapper-${item.id}`, style: {
|
|
13
10
|
borderRadius: `${radius * 100}vw`,
|
|
14
|
-
borderWidth: `${strokeWidth * 100}vw
|
|
11
|
+
borderWidth: `${strokeWidth * 100}vw`,
|
|
12
|
+
opacity: `${opacity}`,
|
|
13
|
+
borderColor: `${strokeColor}`
|
|
15
14
|
}, children: (0, jsx_runtime_1.jsx)("img", { className: "image", src: item.commonParams.url }) }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
object-fit: cover;
|
|
32
|
-
pointer-events: none;
|
|
33
|
-
}
|
|
15
|
+
.image-wrapper-${item.id} {
|
|
16
|
+
position: absolute;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
border-style: solid;
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
}
|
|
23
|
+
.image {
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
opacity: 1;
|
|
27
|
+
object-fit: cover;
|
|
28
|
+
pointer-events: none;
|
|
29
|
+
}
|
|
34
30
|
` })] }) }));
|
|
35
31
|
};
|
|
36
32
|
exports.ImageItem = ImageItem;
|
|
@@ -2,27 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RectangleItem = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const sdk_1 = require("@cntrl-site/sdk");
|
|
6
5
|
const LinkWrapper_1 = require("../LinkWrapper");
|
|
7
|
-
const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
8
6
|
const useRectangleItem_1 = require("./useRectangleItem");
|
|
9
7
|
const RectangleItem = ({ item }) => {
|
|
10
|
-
const {
|
|
11
|
-
const { fillColor, radius, strokeWidth } = (0, useRectangleItem_1.useRectangleItem)(item);
|
|
8
|
+
const { fillColor, radius, strokeWidth, strokeColor } = (0, useRectangleItem_1.useRectangleItem)(item);
|
|
12
9
|
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `rectangle-${item.id}`, style: {
|
|
13
10
|
backgroundColor: `${fillColor}`,
|
|
14
11
|
borderRadius: `${radius * 100}vw`,
|
|
15
|
-
borderWidth: `${strokeWidth * 100}vw
|
|
12
|
+
borderWidth: `${strokeWidth * 100}vw`,
|
|
13
|
+
borderColor: `${strokeColor}`
|
|
16
14
|
} }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
|
|
17
|
-
${(0, sdk_1.getLayoutStyles)(layouts, [item.layoutParams], ([{ strokeColor }]) => (`
|
|
18
15
|
.rectangle-${item.id} {
|
|
19
16
|
position: absolute;
|
|
20
17
|
width: 100%;
|
|
21
18
|
height: 100%;
|
|
22
19
|
border-style: solid;
|
|
23
20
|
box-sizing: border-box;
|
|
24
|
-
|
|
25
|
-
}`))}
|
|
21
|
+
}
|
|
26
22
|
` })] }) }));
|
|
27
23
|
};
|
|
28
24
|
exports.RectangleItem = RectangleItem;
|
|
@@ -3,34 +3,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.VideoItem = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const LinkWrapper_1 = require("../LinkWrapper");
|
|
6
|
-
const sdk_1 = require("@cntrl-site/sdk");
|
|
7
|
-
const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
8
6
|
const useFileItem_1 = require("./useFileItem");
|
|
9
7
|
const VideoItem = ({ item }) => {
|
|
10
|
-
const {
|
|
11
|
-
const { radius, strokeWidth } = (0, useFileItem_1.useFileItem)(item);
|
|
8
|
+
const { radius, strokeWidth, strokeColor, opacity } = (0, useFileItem_1.useFileItem)(item);
|
|
12
9
|
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: [(0, jsx_runtime_1.jsx)("div", { className: `video-wrapper-${item.id}`, style: {
|
|
13
10
|
borderRadius: `${radius * 100}vw`,
|
|
14
|
-
borderWidth: `${strokeWidth * 100}vw
|
|
11
|
+
borderWidth: `${strokeWidth * 100}vw`,
|
|
12
|
+
opacity: `${opacity}`,
|
|
13
|
+
borderColor: `${strokeColor}`
|
|
15
14
|
}, children: (0, jsx_runtime_1.jsx)("video", { autoPlay: true, muted: true, loop: true, playsInline: true, className: "video", children: (0, jsx_runtime_1.jsx)("source", { src: item.commonParams.url }) }) }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
15
|
+
.video-wrapper-${item.id} {
|
|
16
|
+
position: absolute;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
border-style: solid;
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
border-color: ${strokeColor};
|
|
23
|
+
opacity: ${opacity};
|
|
24
|
+
}
|
|
25
|
+
.video {
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
opacity: 1;
|
|
29
|
+
object-fit: cover;
|
|
30
|
+
pointer-events: none;
|
|
31
|
+
}
|
|
34
32
|
` })] }));
|
|
35
33
|
};
|
|
36
34
|
exports.VideoItem = VideoItem;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.useFileItem = void 0;
|
|
4
4
|
const useKeyframeValue_1 = require("../../common/useKeyframeValue");
|
|
5
5
|
const useCurrentLayout_1 = require("../../common/useCurrentLayout");
|
|
6
|
+
const defaultColor = 'rgba(0, 0, 0, 1)';
|
|
6
7
|
const useFileItem = (item) => {
|
|
7
8
|
const layoutId = (0, useCurrentLayout_1.useCurrentLayout)();
|
|
8
9
|
const radius = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
|
|
@@ -17,6 +18,18 @@ const useFileItem = (item) => {
|
|
|
17
18
|
const layoutParams = item.layoutParams[layoutId];
|
|
18
19
|
return 'strokeWidth' in layoutParams ? layoutParams.strokeWidth : 0;
|
|
19
20
|
}, (animator, scroll, value) => animator.getBorderWidth({ borderWidth: value }, scroll).borderWidth, [layoutId]);
|
|
20
|
-
|
|
21
|
+
const opacity = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
|
|
22
|
+
if (!layoutId)
|
|
23
|
+
return 0;
|
|
24
|
+
const layoutParams = item.layoutParams[layoutId];
|
|
25
|
+
return 'opacity' in layoutParams ? layoutParams.opacity : 0;
|
|
26
|
+
}, (animator, scroll, value) => animator.getOpacity({ opacity: value }, scroll).opacity, [layoutId]);
|
|
27
|
+
const strokeColor = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
|
|
28
|
+
if (!layoutId)
|
|
29
|
+
return defaultColor;
|
|
30
|
+
const layoutParams = item.layoutParams[layoutId];
|
|
31
|
+
return 'strokeColor' in layoutParams ? layoutParams.strokeColor : defaultColor;
|
|
32
|
+
}, (animator, scroll, value) => animator.getBorderColor({ color: value }, scroll).color);
|
|
33
|
+
return { radius, strokeWidth, opacity, strokeColor };
|
|
21
34
|
};
|
|
22
35
|
exports.useFileItem = useFileItem;
|
|
@@ -24,6 +24,12 @@ const useRectangleItem = (item) => {
|
|
|
24
24
|
const layoutParams = item.layoutParams[layoutId];
|
|
25
25
|
return 'fillColor' in layoutParams ? layoutParams.fillColor : defaultColor;
|
|
26
26
|
}, (animator, scroll, value) => animator.getColor({ color: value }, scroll).color);
|
|
27
|
-
|
|
27
|
+
const strokeColor = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
|
|
28
|
+
if (!layoutId)
|
|
29
|
+
return defaultColor;
|
|
30
|
+
const layoutParams = item.layoutParams[layoutId];
|
|
31
|
+
return 'strokeColor' in layoutParams ? layoutParams.strokeColor : defaultColor;
|
|
32
|
+
}, (animator, scroll, value) => animator.getBorderColor({ color: value }, scroll).color);
|
|
33
|
+
return { fillColor, strokeWidth, radius, strokeColor };
|
|
28
34
|
};
|
|
29
35
|
exports.useRectangleItem = useRectangleItem;
|
|
@@ -63,6 +63,21 @@ class Animator {
|
|
|
63
63
|
color: this.getRgba(start, end, pos)
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
+
getBorderColor(values, pos) {
|
|
67
|
+
const keyframes = this.keyframesMap[sdk_1.KeyframeType.BorderColor];
|
|
68
|
+
if (!keyframes || !keyframes.length)
|
|
69
|
+
return values;
|
|
70
|
+
if (keyframes.length === 1) {
|
|
71
|
+
const [keyframe] = keyframes;
|
|
72
|
+
return {
|
|
73
|
+
color: keyframe.value.color
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const { start, end } = this.getStartEnd(pos, keyframes);
|
|
77
|
+
return {
|
|
78
|
+
color: this.getRgba(start, end, pos)
|
|
79
|
+
};
|
|
80
|
+
}
|
|
66
81
|
getRadius(values, pos) {
|
|
67
82
|
const keyframes = this.keyframesMap[sdk_1.KeyframeType.BorderRadius];
|
|
68
83
|
if (!keyframes || !keyframes.length)
|
|
@@ -108,6 +123,21 @@ class Animator {
|
|
|
108
123
|
angle: rangeMap(pos, start.position, end.position, start.value.angle, end.value.angle, true)
|
|
109
124
|
};
|
|
110
125
|
}
|
|
126
|
+
getOpacity(values, pos) {
|
|
127
|
+
const keyframes = this.keyframesMap[sdk_1.KeyframeType.Opacity];
|
|
128
|
+
if (!keyframes || !keyframes.length)
|
|
129
|
+
return values;
|
|
130
|
+
if (keyframes.length === 1) {
|
|
131
|
+
const [keyframe] = keyframes;
|
|
132
|
+
return {
|
|
133
|
+
opacity: keyframe.value.opacity
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const { start, end } = this.getStartEnd(pos, keyframes);
|
|
137
|
+
return {
|
|
138
|
+
opacity: rangeMap(pos, start.position, end.position, start.value.opacity, end.value.opacity, true)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
111
141
|
getStartEnd(position, keyframes) {
|
|
112
142
|
const index = (0, binSearchInsertAt_1.binSearchInsertAt)(keyframes, { position }, compare);
|
|
113
143
|
const end = index === keyframes.length ? index - 1 : index;
|
|
@@ -146,7 +176,9 @@ function createKeyframesMap() {
|
|
|
146
176
|
[sdk_1.KeyframeType.BorderWidth]: [],
|
|
147
177
|
[sdk_1.KeyframeType.BorderRadius]: [],
|
|
148
178
|
[sdk_1.KeyframeType.Color]: [],
|
|
149
|
-
[sdk_1.KeyframeType.Rotation]: []
|
|
179
|
+
[sdk_1.KeyframeType.Rotation]: [],
|
|
180
|
+
[sdk_1.KeyframeType.BorderColor]: [],
|
|
181
|
+
[sdk_1.KeyframeType.Opacity]: []
|
|
150
182
|
};
|
|
151
183
|
}
|
|
152
184
|
function rangeMap(n, start1, stop1, start2, stop2, withinBounds = false) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cntrl-site/sdk-nextjs",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "SDK for Next.js",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/index.js",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/cntrl-site/sdk-nextjs#readme",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@cntrl-site/sdk": "^0.4.
|
|
24
|
+
"@cntrl-site/sdk": "^0.4.2",
|
|
25
25
|
"html-react-parser": "^3.0.1",
|
|
26
26
|
"styled-jsx": "^5.0.2"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
+
"@types/lodash.isequal": "^4.5.6",
|
|
30
|
+
"lodash.isequal": "^4.5.0",
|
|
29
31
|
"next": "^12.2.3",
|
|
30
32
|
"react": "^18.2.0",
|
|
31
|
-
"react-dom": "^18.2.0"
|
|
32
|
-
"lodash.isequal": "^4.5.0",
|
|
33
|
-
"@types/lodash.isequal": "^4.5.6"
|
|
33
|
+
"react-dom": "^18.2.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@tsconfig/node16": "^1.0.3",
|
|
@@ -1,45 +1,40 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { TImageItem } from '@cntrl-site/sdk';
|
|
3
3
|
import { ItemProps } from '../Item';
|
|
4
4
|
import { LinkWrapper } from '../LinkWrapper';
|
|
5
|
-
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
6
5
|
import { useFileItem } from './useFileItem';
|
|
7
6
|
|
|
8
7
|
export const ImageItem: FC<ItemProps<TImageItem>> = ({ item }) => {
|
|
9
|
-
const {
|
|
10
|
-
const { radius, strokeWidth } = useFileItem(item);
|
|
8
|
+
const { radius, strokeWidth, opacity, strokeColor } = useFileItem(item);
|
|
11
9
|
return (
|
|
12
10
|
<LinkWrapper url={item.link?.url}>
|
|
13
11
|
<>
|
|
14
12
|
<div className={`image-wrapper-${item.id}`}
|
|
15
13
|
style={{
|
|
16
14
|
borderRadius: `${radius * 100}vw`,
|
|
17
|
-
borderWidth: `${strokeWidth * 100}vw
|
|
15
|
+
borderWidth: `${strokeWidth * 100}vw`,
|
|
16
|
+
opacity: `${opacity}`,
|
|
17
|
+
borderColor: `${strokeColor}`
|
|
18
18
|
}}
|
|
19
19
|
>
|
|
20
20
|
<img className="image" src={item.commonParams.url} />
|
|
21
21
|
</div>
|
|
22
22
|
<style jsx>{`
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
height: 100%;
|
|
39
|
-
opacity: 1;
|
|
40
|
-
object-fit: cover;
|
|
41
|
-
pointer-events: none;
|
|
42
|
-
}
|
|
23
|
+
.image-wrapper-${item.id} {
|
|
24
|
+
position: absolute;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
border-style: solid;
|
|
29
|
+
box-sizing: border-box;
|
|
30
|
+
}
|
|
31
|
+
.image {
|
|
32
|
+
width: 100%;
|
|
33
|
+
height: 100%;
|
|
34
|
+
opacity: 1;
|
|
35
|
+
object-fit: cover;
|
|
36
|
+
pointer-events: none;
|
|
37
|
+
}
|
|
43
38
|
`}</style>
|
|
44
39
|
</>
|
|
45
40
|
</LinkWrapper>
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
|
-
import { TRectangleItem
|
|
2
|
+
import { TRectangleItem } from '@cntrl-site/sdk';
|
|
3
3
|
import { ItemProps } from '../Item';
|
|
4
4
|
import { LinkWrapper } from '../LinkWrapper';
|
|
5
|
-
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
6
5
|
import { useRectangleItem } from './useRectangleItem';
|
|
7
6
|
|
|
8
7
|
export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item }) => {
|
|
9
|
-
const {
|
|
10
|
-
const { fillColor, radius, strokeWidth } = useRectangleItem(item);
|
|
8
|
+
const { fillColor, radius, strokeWidth, strokeColor } = useRectangleItem(item);
|
|
11
9
|
return (
|
|
12
10
|
<LinkWrapper url={item.link?.url}>
|
|
13
11
|
<>
|
|
@@ -15,20 +13,18 @@ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item }) => {
|
|
|
15
13
|
style={{
|
|
16
14
|
backgroundColor: `${fillColor}`,
|
|
17
15
|
borderRadius: `${radius * 100}vw`,
|
|
18
|
-
borderWidth: `${strokeWidth * 100}vw
|
|
16
|
+
borderWidth: `${strokeWidth * 100}vw`,
|
|
17
|
+
borderColor: `${strokeColor}`
|
|
19
18
|
}}
|
|
20
19
|
/>
|
|
21
20
|
<style jsx>{`
|
|
22
|
-
${getLayoutStyles(layouts, [item.layoutParams], ([{ strokeColor }]) => (`
|
|
23
21
|
.rectangle-${item.id} {
|
|
24
22
|
position: absolute;
|
|
25
23
|
width: 100%;
|
|
26
24
|
height: 100%;
|
|
27
25
|
border-style: solid;
|
|
28
26
|
box-sizing: border-box;
|
|
29
|
-
|
|
30
|
-
}`
|
|
31
|
-
))}
|
|
27
|
+
}
|
|
32
28
|
`}</style>
|
|
33
29
|
</>
|
|
34
30
|
</LinkWrapper>
|
|
@@ -2,19 +2,18 @@ import { FC } from 'react';
|
|
|
2
2
|
import { TVideoItem } from '@cntrl-site/sdk';
|
|
3
3
|
import { ItemProps } from '../Item';
|
|
4
4
|
import { LinkWrapper } from '../LinkWrapper';
|
|
5
|
-
import { getLayoutStyles } from '@cntrl-site/sdk';
|
|
6
|
-
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
7
5
|
import { useFileItem } from './useFileItem';
|
|
8
6
|
|
|
9
7
|
export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item }) => {
|
|
10
|
-
const {
|
|
11
|
-
const { radius, strokeWidth } = useFileItem(item);
|
|
8
|
+
const { radius, strokeWidth, strokeColor, opacity } = useFileItem(item);
|
|
12
9
|
return (
|
|
13
10
|
<LinkWrapper url={item.link?.url}>
|
|
14
11
|
<div className={`video-wrapper-${item.id}`}
|
|
15
12
|
style={{
|
|
16
13
|
borderRadius: `${radius * 100}vw`,
|
|
17
|
-
borderWidth: `${strokeWidth * 100}vw
|
|
14
|
+
borderWidth: `${strokeWidth * 100}vw`,
|
|
15
|
+
opacity: `${opacity}`,
|
|
16
|
+
borderColor: `${strokeColor}`
|
|
18
17
|
}}
|
|
19
18
|
>
|
|
20
19
|
<video autoPlay muted loop playsInline className="video">
|
|
@@ -22,26 +21,23 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item }) => {
|
|
|
22
21
|
</video>
|
|
23
22
|
</div>
|
|
24
23
|
<style jsx>{`
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
object-fit: cover;
|
|
43
|
-
pointer-events: none;
|
|
44
|
-
}
|
|
24
|
+
.video-wrapper-${item.id} {
|
|
25
|
+
position: absolute;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
width: 100%;
|
|
28
|
+
height: 100%;
|
|
29
|
+
border-style: solid;
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
border-color: ${strokeColor};
|
|
32
|
+
opacity: ${opacity};
|
|
33
|
+
}
|
|
34
|
+
.video {
|
|
35
|
+
width: 100%;
|
|
36
|
+
height: 100%;
|
|
37
|
+
opacity: 1;
|
|
38
|
+
object-fit: cover;
|
|
39
|
+
pointer-events: none;
|
|
40
|
+
}
|
|
45
41
|
`}</style>
|
|
46
42
|
</LinkWrapper>
|
|
47
43
|
);
|
|
@@ -2,6 +2,8 @@ import { TImageItem, TVideoItem } from '@cntrl-site/sdk';
|
|
|
2
2
|
import { useKeyframeValue } from '../../common/useKeyframeValue';
|
|
3
3
|
import { useCurrentLayout } from '../../common/useCurrentLayout';
|
|
4
4
|
|
|
5
|
+
const defaultColor = 'rgba(0, 0, 0, 1)';
|
|
6
|
+
|
|
5
7
|
export const useFileItem = (item: TImageItem | TVideoItem) => {
|
|
6
8
|
const layoutId = useCurrentLayout();
|
|
7
9
|
const radius = useKeyframeValue(
|
|
@@ -25,5 +27,26 @@ export const useFileItem = (item: TImageItem | TVideoItem) => {
|
|
|
25
27
|
[layoutId]
|
|
26
28
|
);
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
const opacity = useKeyframeValue(
|
|
31
|
+
item,
|
|
32
|
+
(item, layoutId) => {
|
|
33
|
+
if (!layoutId) return 0;
|
|
34
|
+
const layoutParams = item.layoutParams[layoutId];
|
|
35
|
+
return 'opacity' in layoutParams ? layoutParams.opacity : 0;
|
|
36
|
+
},
|
|
37
|
+
(animator, scroll, value) => animator.getOpacity({ opacity: value }, scroll).opacity,
|
|
38
|
+
[layoutId]
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const strokeColor = useKeyframeValue(
|
|
42
|
+
item,
|
|
43
|
+
(item, layoutId) => {
|
|
44
|
+
if (!layoutId) return defaultColor;
|
|
45
|
+
const layoutParams = item.layoutParams[layoutId];
|
|
46
|
+
return 'strokeColor' in layoutParams ? layoutParams.strokeColor : defaultColor;
|
|
47
|
+
},
|
|
48
|
+
(animator, scroll, value) => animator.getBorderColor({ color: value }, scroll).color
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return { radius, strokeWidth, opacity, strokeColor };
|
|
29
52
|
};
|
|
@@ -35,6 +35,15 @@ export const useRectangleItem = (item: TRectangleItem) => {
|
|
|
35
35
|
},
|
|
36
36
|
(animator, scroll, value) => animator.getColor({ color: value }, scroll).color
|
|
37
37
|
);
|
|
38
|
+
const strokeColor = useKeyframeValue(
|
|
39
|
+
item,
|
|
40
|
+
(item, layoutId) => {
|
|
41
|
+
if (!layoutId) return defaultColor;
|
|
42
|
+
const layoutParams = item.layoutParams[layoutId];
|
|
43
|
+
return 'strokeColor' in layoutParams ? layoutParams.strokeColor : defaultColor;
|
|
44
|
+
},
|
|
45
|
+
(animator, scroll, value) => animator.getBorderColor({ color: value }, scroll).color
|
|
46
|
+
);
|
|
38
47
|
|
|
39
|
-
return { fillColor, strokeWidth, radius };
|
|
48
|
+
return { fillColor, strokeWidth, radius, strokeColor };
|
|
40
49
|
};
|
|
@@ -88,6 +88,24 @@ export class Animator {
|
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
getBorderColor(
|
|
92
|
+
values: TKeyframeValueMap[KeyframeType.BorderColor],
|
|
93
|
+
pos: number
|
|
94
|
+
): TKeyframeValueMap[KeyframeType.BorderColor] {
|
|
95
|
+
const keyframes = this.keyframesMap[KeyframeType.BorderColor];
|
|
96
|
+
if (!keyframes || !keyframes.length) return values;
|
|
97
|
+
if (keyframes.length === 1) {
|
|
98
|
+
const [keyframe] = keyframes;
|
|
99
|
+
return {
|
|
100
|
+
color: keyframe.value.color
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const { start, end } = this.getStartEnd<KeyframeType.BorderColor>(pos, keyframes);
|
|
104
|
+
return {
|
|
105
|
+
color: this.getRgba(start, end, pos)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
91
109
|
getRadius(
|
|
92
110
|
values: TKeyframeValueMap[KeyframeType.BorderRadius],
|
|
93
111
|
pos: number
|
|
@@ -142,6 +160,24 @@ export class Animator {
|
|
|
142
160
|
};
|
|
143
161
|
}
|
|
144
162
|
|
|
163
|
+
getOpacity(
|
|
164
|
+
values: TKeyframeValueMap[KeyframeType.Opacity],
|
|
165
|
+
pos: number
|
|
166
|
+
): TKeyframeValueMap[KeyframeType.Opacity] {
|
|
167
|
+
const keyframes = this.keyframesMap[KeyframeType.Opacity];
|
|
168
|
+
if (!keyframes || !keyframes.length) return values;
|
|
169
|
+
if (keyframes.length === 1) {
|
|
170
|
+
const [keyframe] = keyframes;
|
|
171
|
+
return {
|
|
172
|
+
opacity: keyframe.value.opacity
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const { start, end } = this.getStartEnd<KeyframeType.Opacity>(pos, keyframes);
|
|
176
|
+
return {
|
|
177
|
+
opacity: rangeMap(pos, start.position, end.position, start.value.opacity, end.value.opacity, true)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
145
181
|
getStartEnd<T extends KeyframeType>(position: number, keyframes: AnimationData<T>[]): PositionKeyframes<T> {
|
|
146
182
|
const index = binSearchInsertAt(keyframes, { position }, compare);
|
|
147
183
|
const end = index === keyframes.length ? index - 1 : index;
|
|
@@ -157,8 +193,8 @@ export class Animator {
|
|
|
157
193
|
}
|
|
158
194
|
|
|
159
195
|
private getRgba(
|
|
160
|
-
start: AnimationData<KeyframeType.Color>,
|
|
161
|
-
end: AnimationData<KeyframeType.Color>,
|
|
196
|
+
start: AnimationData<KeyframeType.Color | KeyframeType.BorderColor>,
|
|
197
|
+
end: AnimationData<KeyframeType.Color | KeyframeType.BorderColor>,
|
|
162
198
|
position: number
|
|
163
199
|
): string {
|
|
164
200
|
const [startR, startG, startB, startA] = parseRgba(start.value.color);
|
|
@@ -187,7 +223,9 @@ function createKeyframesMap(): KeyframesMap {
|
|
|
187
223
|
[KeyframeType.BorderWidth]: [],
|
|
188
224
|
[KeyframeType.BorderRadius]: [],
|
|
189
225
|
[KeyframeType.Color]: [],
|
|
190
|
-
[KeyframeType.Rotation]: []
|
|
226
|
+
[KeyframeType.Rotation]: [],
|
|
227
|
+
[KeyframeType.BorderColor]: [],
|
|
228
|
+
[KeyframeType.Opacity]: []
|
|
191
229
|
};
|
|
192
230
|
}
|
|
193
231
|
|