@revenuecat/purchases-ui-js 0.0.19 → 0.0.20
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/dist/components/image/Image.stories.svelte +124 -13
- package/dist/components/image/Image.svelte +104 -9
- package/dist/components/image/image-utils.d.ts +10 -2
- package/dist/components/image/image-utils.js +8 -16
- package/dist/data/entities.d.ts +1 -1
- package/dist/utils/style-utils.d.ts +24 -24
- package/dist/utils/style-utils.js +51 -53
- package/package.json +1 -1
|
@@ -64,6 +64,38 @@
|
|
|
64
64
|
mask_shape: { type: "rectangle" },
|
|
65
65
|
}}
|
|
66
66
|
/>
|
|
67
|
+
|
|
68
|
+
<!-- Rounded Rectangle story -->
|
|
69
|
+
<Story
|
|
70
|
+
name="Rounded Rectangle"
|
|
71
|
+
args={{
|
|
72
|
+
purchaseState,
|
|
73
|
+
id: "example-id",
|
|
74
|
+
fit_mode: "fit",
|
|
75
|
+
size: {
|
|
76
|
+
width: { type: "fill" },
|
|
77
|
+
height: { type: "fill" },
|
|
78
|
+
},
|
|
79
|
+
source: {
|
|
80
|
+
light: {
|
|
81
|
+
original: "https://placehold.co/600x400",
|
|
82
|
+
heic: "https://placehold.co/600x400",
|
|
83
|
+
heic_low_res: "https://placehold.co/600x400",
|
|
84
|
+
webp: "https://placehold.co/600x400",
|
|
85
|
+
webp_low_res: "https://placehold.co/600x400",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
mask_shape: {
|
|
89
|
+
type: "rectangle",
|
|
90
|
+
corners: {
|
|
91
|
+
top_leading: 32,
|
|
92
|
+
top_trailing: 32,
|
|
93
|
+
bottom_leading: 32,
|
|
94
|
+
bottom_trailing: 32,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
}}
|
|
98
|
+
/>
|
|
67
99
|
<!-- Circle story -->
|
|
68
100
|
<Story
|
|
69
101
|
name="Circle"
|
|
@@ -133,9 +165,50 @@
|
|
|
133
165
|
mask_shape: { type: "convex" },
|
|
134
166
|
}}
|
|
135
167
|
/>
|
|
136
|
-
<!-- Gradient story -->
|
|
168
|
+
<!-- Radial Gradient story -->
|
|
169
|
+
<Story
|
|
170
|
+
name="Overlay Radial Gradient"
|
|
171
|
+
args={{
|
|
172
|
+
purchaseState,
|
|
173
|
+
id: "example-id",
|
|
174
|
+
fit_mode: "fit",
|
|
175
|
+
size: {
|
|
176
|
+
width: { type: "fill" },
|
|
177
|
+
height: { type: "fill" },
|
|
178
|
+
},
|
|
179
|
+
source: {
|
|
180
|
+
light: {
|
|
181
|
+
original: "https://placehold.co/600x400",
|
|
182
|
+
heic: "https://placehold.co/600x400",
|
|
183
|
+
heic_low_res: "https://placehold.co/600x400",
|
|
184
|
+
webp: "https://placehold.co/600x400",
|
|
185
|
+
webp_low_res: "https://placehold.co/600x400",
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
color_overlay: {
|
|
189
|
+
dark: {
|
|
190
|
+
type: "hex",
|
|
191
|
+
value: "#000000FF",
|
|
192
|
+
},
|
|
193
|
+
light: {
|
|
194
|
+
points: [
|
|
195
|
+
{
|
|
196
|
+
color: "#020024ff",
|
|
197
|
+
percent: 0,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
color: "#00d4ff00",
|
|
201
|
+
percent: 100,
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
type: "radial",
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
}}
|
|
208
|
+
/>
|
|
209
|
+
<!-- Linear Gradient story -->
|
|
137
210
|
<Story
|
|
138
|
-
name="
|
|
211
|
+
name="Overlay Linear Gradient"
|
|
139
212
|
args={{
|
|
140
213
|
purchaseState,
|
|
141
214
|
id: "example-id",
|
|
@@ -153,19 +226,57 @@
|
|
|
153
226
|
webp_low_res: "https://placehold.co/600x400",
|
|
154
227
|
},
|
|
155
228
|
},
|
|
156
|
-
|
|
157
|
-
{
|
|
158
|
-
|
|
159
|
-
|
|
229
|
+
color_overlay: {
|
|
230
|
+
dark: {
|
|
231
|
+
type: "hex",
|
|
232
|
+
value: "#000000FF",
|
|
233
|
+
},
|
|
234
|
+
light: {
|
|
235
|
+
degrees: 180,
|
|
236
|
+
points: [
|
|
237
|
+
{
|
|
238
|
+
color: "#020024ff",
|
|
239
|
+
percent: 0,
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
color: "#00d4ff00",
|
|
243
|
+
percent: 100,
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
type: "linear",
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
}}
|
|
250
|
+
/>
|
|
251
|
+
<!-- Solid overlay -->
|
|
252
|
+
<Story
|
|
253
|
+
name="Overlay Solid"
|
|
254
|
+
args={{
|
|
255
|
+
purchaseState,
|
|
256
|
+
id: "example-id",
|
|
257
|
+
fit_mode: "fit",
|
|
258
|
+
size: {
|
|
259
|
+
width: { type: "fill" },
|
|
260
|
+
height: { type: "fill" },
|
|
261
|
+
},
|
|
262
|
+
source: {
|
|
263
|
+
light: {
|
|
264
|
+
original: "https://placehold.co/600x400",
|
|
265
|
+
heic: "https://placehold.co/600x400",
|
|
266
|
+
heic_low_res: "https://placehold.co/600x400",
|
|
267
|
+
webp: "https://placehold.co/600x400",
|
|
268
|
+
webp_low_res: "https://placehold.co/600x400",
|
|
160
269
|
},
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
270
|
+
},
|
|
271
|
+
color_overlay: {
|
|
272
|
+
dark: {
|
|
273
|
+
type: "hex",
|
|
274
|
+
value: "#000000FF",
|
|
164
275
|
},
|
|
165
|
-
{
|
|
166
|
-
|
|
167
|
-
|
|
276
|
+
light: {
|
|
277
|
+
type: "hex",
|
|
278
|
+
value: "#e7c00069",
|
|
168
279
|
},
|
|
169
|
-
|
|
280
|
+
},
|
|
170
281
|
}}
|
|
171
282
|
/>
|
|
@@ -4,13 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
const { id, source, purchaseState, ...restProps }: ImageProps = $props();
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
let imageAspectRatio = $state(0);
|
|
8
|
+
let imageElement: HTMLImageElement | null;
|
|
9
|
+
|
|
10
|
+
// Calculate aspect ratio once image loads
|
|
11
|
+
function onImageLoad() {
|
|
12
|
+
if (imageElement) {
|
|
13
|
+
imageAspectRatio = imageElement.naturalHeight / imageElement.naturalWidth;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const { imageStyles, maskPath, linearGradientAngle } = $derived(
|
|
8
17
|
getImageComponentStyles({
|
|
9
18
|
id,
|
|
10
19
|
colorMode: purchaseState.colorMode,
|
|
11
20
|
source,
|
|
12
21
|
purchaseState,
|
|
13
22
|
...restProps,
|
|
23
|
+
imageAspectRatio,
|
|
14
24
|
}),
|
|
15
25
|
);
|
|
16
26
|
|
|
@@ -24,24 +34,110 @@
|
|
|
24
34
|
});
|
|
25
35
|
</script>
|
|
26
36
|
|
|
27
|
-
<
|
|
37
|
+
<img
|
|
38
|
+
src={imageSource}
|
|
39
|
+
bind:this={imageElement}
|
|
40
|
+
onload={onImageLoad}
|
|
41
|
+
style="display: none;"
|
|
42
|
+
alt=""
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
<svg
|
|
28
46
|
class="rc-pw-image-container"
|
|
29
47
|
id={`rc-pw-image-container-${id}`}
|
|
30
48
|
style={imageStyles}
|
|
49
|
+
preserveAspectRatio="xMidYMid slice"
|
|
50
|
+
viewBox={`0 0 100 ${imageAspectRatio * 100}`}
|
|
31
51
|
>
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
52
|
+
<defs>
|
|
53
|
+
<clipPath id={`clip-path-${id}`}>
|
|
54
|
+
{#if restProps.mask_shape?.type === "circle"}
|
|
55
|
+
<ellipse
|
|
56
|
+
cx="50"
|
|
57
|
+
cy={imageAspectRatio * 50}
|
|
58
|
+
rx="50"
|
|
59
|
+
ry={imageAspectRatio * 50}
|
|
60
|
+
/>
|
|
61
|
+
{:else}
|
|
62
|
+
<path d={maskPath} />
|
|
63
|
+
{/if}
|
|
64
|
+
</clipPath>
|
|
65
|
+
|
|
66
|
+
{#if restProps.color_overlay?.[purchaseState.colorMode]?.type === "linear"}
|
|
67
|
+
<linearGradient
|
|
68
|
+
id={`gradient-${id}`}
|
|
69
|
+
x1={linearGradientAngle.x1}
|
|
70
|
+
y1={linearGradientAngle.y1}
|
|
71
|
+
x2={linearGradientAngle.x2}
|
|
72
|
+
y2={linearGradientAngle.y2}
|
|
73
|
+
>
|
|
74
|
+
{#each restProps.color_overlay?.[purchaseState.colorMode]?.points || restProps.color_overlay?.["light"]?.points || [] as stop}
|
|
75
|
+
<stop
|
|
76
|
+
offset={`${stop.percent}%`}
|
|
77
|
+
style={`stop-color: ${stop.color}`}
|
|
78
|
+
/>
|
|
79
|
+
{/each}
|
|
80
|
+
</linearGradient>
|
|
81
|
+
{:else if restProps.color_overlay?.[purchaseState.colorMode]?.type === "radial"}
|
|
82
|
+
<radialGradient
|
|
83
|
+
id={`gradient-${id}`}
|
|
84
|
+
cx="50%"
|
|
85
|
+
cy="50%"
|
|
86
|
+
r="50%"
|
|
87
|
+
fx="50%"
|
|
88
|
+
fy="50%"
|
|
89
|
+
>
|
|
90
|
+
{#each restProps.color_overlay?.[purchaseState.colorMode]?.points || restProps.color_overlay?.["light"]?.points || [] as stop}
|
|
91
|
+
<stop
|
|
92
|
+
offset={`${stop.percent}%`}
|
|
93
|
+
style={`stop-color: ${stop.color}`}
|
|
94
|
+
/>
|
|
95
|
+
{/each}
|
|
96
|
+
</radialGradient>
|
|
97
|
+
{:else if restProps.color_overlay?.[purchaseState.colorMode]?.type === "hex"}
|
|
98
|
+
<linearGradient id={`gradient-${id}`}>
|
|
99
|
+
<stop
|
|
100
|
+
offset="0%"
|
|
101
|
+
style={`stop-color: ${
|
|
102
|
+
restProps.color_overlay[purchaseState.colorMode]?.value ||
|
|
103
|
+
restProps.color_overlay?.["light"]?.value
|
|
104
|
+
}`}
|
|
105
|
+
/>
|
|
106
|
+
</linearGradient>
|
|
107
|
+
{/if}
|
|
108
|
+
</defs>
|
|
109
|
+
|
|
110
|
+
<image
|
|
111
|
+
class="rc-pw-image"
|
|
112
|
+
href={imageSource}
|
|
113
|
+
x="0"
|
|
114
|
+
y="0"
|
|
115
|
+
width="100"
|
|
116
|
+
height={imageAspectRatio * 100}
|
|
117
|
+
clip-path={`url(#clip-path-${id})`}
|
|
118
|
+
preserveAspectRatio="xMidYMid slice"
|
|
119
|
+
{id}
|
|
120
|
+
/>
|
|
121
|
+
|
|
122
|
+
<rect
|
|
123
|
+
class="rc-pw-image-overlay"
|
|
124
|
+
x="0"
|
|
125
|
+
y="0"
|
|
126
|
+
width="100"
|
|
127
|
+
height={imageAspectRatio * 100}
|
|
128
|
+
clip-path={`url(#clip-path-${id})`}
|
|
129
|
+
fill={`url(#gradient-${id})`}
|
|
130
|
+
/>
|
|
131
|
+
</svg>
|
|
35
132
|
|
|
36
133
|
<style>
|
|
37
134
|
.rc-pw-image-container {
|
|
38
|
-
position: relative;
|
|
39
|
-
overflow: hidden;
|
|
40
135
|
border-end-start-radius: var(--image-border-end-start-radius, 0px);
|
|
41
136
|
border-end-end-radius: var(--image-border-end-end-radius, 0px);
|
|
42
137
|
border-start-start-radius: var(--image-border-start-start-radius, 0px);
|
|
43
138
|
border-start-end-radius: var(--image-border-start-end-radius, 0px);
|
|
44
|
-
|
|
139
|
+
position: relative;
|
|
140
|
+
overflow: hidden;
|
|
45
141
|
display: flex;
|
|
46
142
|
flex: var(--image-flex, 1 1 auto);
|
|
47
143
|
position: var(--image-position, relative);
|
|
@@ -61,6 +157,5 @@
|
|
|
61
157
|
.rc-pw-image-overlay {
|
|
62
158
|
position: absolute;
|
|
63
159
|
inset: 0;
|
|
64
|
-
background: var(--image-background, none);
|
|
65
160
|
}
|
|
66
161
|
</style>
|
|
@@ -4,7 +4,15 @@ import type { ImageProps } from "../../data/entities";
|
|
|
4
4
|
* @param props - Image component properties including gradient, mask and size
|
|
5
5
|
* @returns Object containing image style variables and gradient style variables
|
|
6
6
|
*/
|
|
7
|
-
export declare const getImageComponentStyles: (props: ImageProps
|
|
7
|
+
export declare const getImageComponentStyles: (props: ImageProps & {
|
|
8
|
+
imageAspectRatio: number;
|
|
9
|
+
}) => {
|
|
8
10
|
imageStyles: string;
|
|
9
|
-
|
|
11
|
+
maskPath: string;
|
|
12
|
+
linearGradientAngle: {
|
|
13
|
+
x1: string;
|
|
14
|
+
y1: string;
|
|
15
|
+
x2: string;
|
|
16
|
+
y2: string;
|
|
17
|
+
};
|
|
10
18
|
};
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import { getActiveStateProps,
|
|
1
|
+
import { getActiveStateProps, getLinearGradientAngle, getMaskPath, getMaskStyle, getSizeStyle, prefixObject, stringifyStyles, } from "../../utils/style-utils";
|
|
2
2
|
/**
|
|
3
3
|
* Generates comprehensive styles for image components by combining gradient and size styles
|
|
4
4
|
* @param props - Image component properties including gradient, mask and size
|
|
5
5
|
* @returns Object containing image style variables and gradient style variables
|
|
6
6
|
*/
|
|
7
7
|
export const getImageComponentStyles = (props) => {
|
|
8
|
-
const {
|
|
9
|
-
// max_height, // TODO: implement this. still waiting on spec
|
|
10
|
-
// override_source_lid, // TODO: Implement this once structure is defined
|
|
11
|
-
overrides, componentState, purchaseState, zStackChildStyles, } = props;
|
|
8
|
+
const { size, overrides, componentState, zStackChildStyles } = props;
|
|
12
9
|
const imageStyles = {
|
|
13
10
|
"--height": "unset",
|
|
14
11
|
"--width": "unset",
|
|
@@ -21,21 +18,16 @@ export const getImageComponentStyles = (props) => {
|
|
|
21
18
|
"--inset": "0",
|
|
22
19
|
"--transform": "initial",
|
|
23
20
|
};
|
|
24
|
-
Object.assign(imageStyles, zStackChildStyles);
|
|
25
|
-
const backgroundStyles = {
|
|
26
|
-
"--background": "none",
|
|
27
|
-
};
|
|
28
21
|
const activeStateProps = getActiveStateProps(overrides, componentState);
|
|
29
|
-
Object.assign(
|
|
22
|
+
Object.assign(imageStyles, zStackChildStyles);
|
|
30
23
|
Object.assign(imageStyles, getSizeStyle({ ...size, ...activeStateProps }));
|
|
31
|
-
Object.assign(imageStyles, getMaskStyle(
|
|
32
|
-
...mask_shape,
|
|
33
|
-
...activeStateProps,
|
|
34
|
-
}));
|
|
24
|
+
Object.assign(imageStyles, getMaskStyle(props.mask_shape));
|
|
35
25
|
const prefixedImageStyles = prefixObject(imageStyles, "image");
|
|
36
|
-
const
|
|
26
|
+
const maskPath = getMaskPath(props);
|
|
27
|
+
const linearGradientAngle = getLinearGradientAngle(props);
|
|
37
28
|
return {
|
|
38
29
|
imageStyles: stringifyStyles(prefixedImageStyles),
|
|
39
|
-
|
|
30
|
+
maskPath,
|
|
31
|
+
linearGradientAngle,
|
|
40
32
|
};
|
|
41
33
|
};
|
package/dist/data/entities.d.ts
CHANGED
|
@@ -194,7 +194,7 @@ export interface ImageProps extends SharedComponentProps {
|
|
|
194
194
|
fit_mode: FitTypes;
|
|
195
195
|
size: SizeType;
|
|
196
196
|
source: ImageSourceType;
|
|
197
|
-
|
|
197
|
+
color_overlay?: ColorType;
|
|
198
198
|
mask_shape?: ImageMaskShapeType;
|
|
199
199
|
max_height?: number;
|
|
200
200
|
override_source_lid?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ComponentState, ImageMaskShapeType, PaywallData, TextNodeProps } from "../data/entities.js";
|
|
1
|
+
import type { ComponentState, ImageMaskShapeType, ImageProps, PaywallData, TextNodeProps } from "../data/entities.js";
|
|
2
2
|
import { type BorderType, type ColorMode, type ColorType, type CornerRadiusType, type DimensionType, FontSizeTags, type ShadowType, type ShapeType, type SizeType, type Spacing } from "../types.js";
|
|
3
3
|
type MarginVariables = {
|
|
4
4
|
"--margin-block-start": string;
|
|
@@ -81,29 +81,6 @@ type SizeStyleVariables = {
|
|
|
81
81
|
* @returns CSS style object with size properties
|
|
82
82
|
*/
|
|
83
83
|
export declare function getSizeStyle(size: SizeType): SizeStyleVariables;
|
|
84
|
-
type GradientStyleVariables = {
|
|
85
|
-
"--background": string;
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Generates gradient background styles
|
|
89
|
-
* @param colorMode - Color mode (light/dark)
|
|
90
|
-
* @param gradientColors - Array of colors for gradient
|
|
91
|
-
* @returns CSS style object with gradient background
|
|
92
|
-
*/
|
|
93
|
-
export declare function getGradientStyle(colorMode: ColorMode, gradientColors?: ColorType[]): GradientStyleVariables;
|
|
94
|
-
type MaskStyleVariables = {
|
|
95
|
-
"--border-start-start-radius": string;
|
|
96
|
-
"--border-start-end-radius": string;
|
|
97
|
-
"--border-end-start-radius": string;
|
|
98
|
-
"--border-end-end-radius": string;
|
|
99
|
-
"--clip-path": string;
|
|
100
|
-
};
|
|
101
|
-
/**
|
|
102
|
-
* Generates mask styles for images
|
|
103
|
-
* @param maskShape - Shape configuration for image mask
|
|
104
|
-
* @returns CSS style object with mask properties
|
|
105
|
-
*/
|
|
106
|
-
export declare const getMaskStyle: (maskShape?: ImageMaskShapeType) => MaskStyleVariables;
|
|
107
84
|
type InsetStyleVariables = {
|
|
108
85
|
"--inset": string;
|
|
109
86
|
"--transform": string;
|
|
@@ -155,4 +132,27 @@ export declare const getActiveStateProps: <T>(overrides?: {
|
|
|
155
132
|
states?: Record<string, T>;
|
|
156
133
|
}, componentState?: ComponentState) => T;
|
|
157
134
|
export declare function prefixObject(object?: Record<string, string | number>, prefix?: string): Record<string, string | number>;
|
|
135
|
+
export declare function getMaskPath(props: ImageProps & {
|
|
136
|
+
imageAspectRatio: number;
|
|
137
|
+
}): string;
|
|
138
|
+
type MaskStyleVariables = {
|
|
139
|
+
"--border-start-start-radius": string;
|
|
140
|
+
"--border-start-end-radius": string;
|
|
141
|
+
"--border-end-start-radius": string;
|
|
142
|
+
"--border-end-end-radius": string;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Generates mask styles for images
|
|
146
|
+
* @param maskShape - Shape configuration for image mask
|
|
147
|
+
* @returns CSS style object with mask properties
|
|
148
|
+
*/
|
|
149
|
+
export declare const getMaskStyle: (maskShape?: ImageMaskShapeType) => MaskStyleVariables;
|
|
150
|
+
export declare function getLinearGradientAngle(props: ImageProps & {
|
|
151
|
+
imageAspectRatio: number;
|
|
152
|
+
}): {
|
|
153
|
+
x1: string;
|
|
154
|
+
y1: string;
|
|
155
|
+
x2: string;
|
|
156
|
+
y2: string;
|
|
157
|
+
};
|
|
158
158
|
export {};
|
|
@@ -182,59 +182,6 @@ export function getSizeStyle(size) {
|
|
|
182
182
|
});
|
|
183
183
|
return styles;
|
|
184
184
|
}
|
|
185
|
-
/**
|
|
186
|
-
* Generates gradient background styles
|
|
187
|
-
* @param colorMode - Color mode (light/dark)
|
|
188
|
-
* @param gradientColors - Array of colors for gradient
|
|
189
|
-
* @returns CSS style object with gradient background
|
|
190
|
-
*/
|
|
191
|
-
export function getGradientStyle(colorMode, gradientColors) {
|
|
192
|
-
if (!gradientColors)
|
|
193
|
-
return { "--background": "none" };
|
|
194
|
-
return {
|
|
195
|
-
"--background": `linear-gradient(${gradientColors.map((color) => color[colorMode]?.value || color["light"].value).join(", ")})`,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Generates mask styles for images
|
|
200
|
-
* @param maskShape - Shape configuration for image mask
|
|
201
|
-
* @returns CSS style object with mask properties
|
|
202
|
-
*/
|
|
203
|
-
export const getMaskStyle = (maskShape) => {
|
|
204
|
-
const maskStyles = {
|
|
205
|
-
"--border-end-start-radius": "0px",
|
|
206
|
-
"--border-end-end-radius": "0px",
|
|
207
|
-
"--border-start-start-radius": "0px",
|
|
208
|
-
"--border-start-end-radius": "0px",
|
|
209
|
-
"--clip-path": "none",
|
|
210
|
-
};
|
|
211
|
-
if (maskShape?.type === "circle") {
|
|
212
|
-
Object.assign(maskStyles, {
|
|
213
|
-
"--border-end-start-radius": "50%",
|
|
214
|
-
"--border-end-end-radius": "50%",
|
|
215
|
-
"--border-start-start-radius": "50%",
|
|
216
|
-
"--border-start-end-radius": "50%",
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
if (maskShape?.type === "rectangle" && maskShape.corners) {
|
|
220
|
-
Object.assign(maskStyles, getCornerRadiusStyle(maskShape.corners));
|
|
221
|
-
}
|
|
222
|
-
// TODO: rework this implementation
|
|
223
|
-
if (maskShape?.type === "convex") {
|
|
224
|
-
Object.assign(maskStyles, {
|
|
225
|
-
"--border-start-start-radius": "0%",
|
|
226
|
-
"--border-start-end-radius": "0%",
|
|
227
|
-
"--border-end-start-radius": "50%",
|
|
228
|
-
"--border-end-end-radius": "50%",
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
if (maskShape?.type === "concave") {
|
|
232
|
-
Object.assign(maskStyles, {
|
|
233
|
-
"--clip-path": "polygon(0 0, 100% 0, 100% 100%, 50% 110%, 0 100%);",
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
return maskStyles;
|
|
237
|
-
};
|
|
238
185
|
export function getInsetStyles(dimension) {
|
|
239
186
|
const defaultStyles = {
|
|
240
187
|
"--inset": "initial",
|
|
@@ -413,3 +360,54 @@ export function prefixObject(object, prefix) {
|
|
|
413
360
|
return acc;
|
|
414
361
|
}, {});
|
|
415
362
|
}
|
|
363
|
+
export function getMaskPath(props) {
|
|
364
|
+
const { mask_shape: maskShape, imageAspectRatio } = props;
|
|
365
|
+
let maskPath = "";
|
|
366
|
+
if (maskShape?.type === "concave") {
|
|
367
|
+
maskPath = `M 0 0
|
|
368
|
+
H 100
|
|
369
|
+
V ${imageAspectRatio * 100}
|
|
370
|
+
Q 50 ${imageAspectRatio * 80} 0 ${imageAspectRatio * 100}
|
|
371
|
+
Z`;
|
|
372
|
+
}
|
|
373
|
+
else if (maskShape?.type === "convex") {
|
|
374
|
+
maskPath = `M 0 0
|
|
375
|
+
H 100
|
|
376
|
+
V ${imageAspectRatio * 80}
|
|
377
|
+
Q 50 ${imageAspectRatio * 120} 0 ${imageAspectRatio * 80}
|
|
378
|
+
Z`;
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
maskPath = `M 0 0 H 100 V ${imageAspectRatio * 100} H 0 Z`;
|
|
382
|
+
}
|
|
383
|
+
return maskPath;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Generates mask styles for images
|
|
387
|
+
* @param maskShape - Shape configuration for image mask
|
|
388
|
+
* @returns CSS style object with mask properties
|
|
389
|
+
*/
|
|
390
|
+
export const getMaskStyle = (maskShape) => {
|
|
391
|
+
const maskStyles = {
|
|
392
|
+
"--border-end-start-radius": "0px",
|
|
393
|
+
"--border-end-end-radius": "0px",
|
|
394
|
+
"--border-start-start-radius": "0px",
|
|
395
|
+
"--border-start-end-radius": "0px",
|
|
396
|
+
};
|
|
397
|
+
if (maskShape?.corners) {
|
|
398
|
+
Object.assign(maskStyles, getCornerRadiusStyle(maskShape.corners));
|
|
399
|
+
}
|
|
400
|
+
return maskStyles;
|
|
401
|
+
};
|
|
402
|
+
export function getLinearGradientAngle(props) {
|
|
403
|
+
if (props.color_overlay?.[props.purchaseState.colorMode]?.type !== "linear") {
|
|
404
|
+
return { x1: "0%", y1: "0%", x2: "0%", y2: "0%" };
|
|
405
|
+
}
|
|
406
|
+
const { color_overlay: colorOverlay } = props;
|
|
407
|
+
const angle = colorOverlay?.["light"]?.degrees || 0;
|
|
408
|
+
const x1 = "50%";
|
|
409
|
+
const y1 = "0%";
|
|
410
|
+
const x2 = `${Math.round(50 + Math.sin(((angle + 90) * Math.PI) / 90) * 50)}%`;
|
|
411
|
+
const y2 = `${Math.round(50 - Math.cos(((angle + 90) * Math.PI) / 90) * 50)}%`;
|
|
412
|
+
return { x1, y1, x2, y2 };
|
|
413
|
+
}
|