oddsgate-ds 1.0.125 → 1.0.126
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/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/organisms/ProductsSlider/ProductsSlider.theme.ts +1 -1
- package/src/components/organisms/ProductsSlider//306/222.js +164 -0
package/package.json
CHANGED
|
@@ -65,7 +65,7 @@ export const StyledProductsSliderSlide = styled.div<IProductsSlider>`
|
|
|
65
65
|
|
|
66
66
|
export const StyledProductsSliderContent = styled.div<IProductsSlider>`
|
|
67
67
|
position: absolute;
|
|
68
|
-
|
|
68
|
+
top: 65%;
|
|
69
69
|
left: 50%;
|
|
70
70
|
max-width: 50rem;
|
|
71
71
|
background: ${colors.third10};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
StyledProductsSlider,
|
|
4
|
+
StyledProductsSliderContent,
|
|
5
|
+
StyledProductsSliderSlide,
|
|
6
|
+
StyledProductsSliderSlides,
|
|
7
|
+
StyledProductsSliderWrapper
|
|
8
|
+
} from './ProductsSlider.theme'
|
|
9
|
+
|
|
10
|
+
import Heading from '@/components/atoms/Heading/Heading.component';
|
|
11
|
+
import { IProductsSlider } from './ProductsSlider.interface'
|
|
12
|
+
import ProductCard from '@/components/molecules/ProductCard/ProductCard.component';
|
|
13
|
+
import { debounce } from '@/helpers/events';
|
|
14
|
+
import useMediaMatch from '@/helpers/useMediaMatch';
|
|
15
|
+
|
|
16
|
+
const ProductsSlider = ({
|
|
17
|
+
content,
|
|
18
|
+
style,
|
|
19
|
+
className,
|
|
20
|
+
}: IProductsSlider) => {
|
|
21
|
+
|
|
22
|
+
const [activeElement, setActiveElement] = useState(content && content[0]);
|
|
23
|
+
const slider = useRef<HTMLDivElement>();
|
|
24
|
+
const wrapper = useRef<HTMLDivElement>();
|
|
25
|
+
const slidesHolder = useRef<HTMLDivElement>();
|
|
26
|
+
const contentHolder = useRef<HTMLDivElement>();
|
|
27
|
+
const isMobile = useMediaMatch();
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
//force 26 items
|
|
31
|
+
const newContent = useMemo(() => {
|
|
32
|
+
if (isMobile) {
|
|
33
|
+
return content;
|
|
34
|
+
} else if (content && content.length < 26) {
|
|
35
|
+
let counter = 0;
|
|
36
|
+
for (let i = content.length; i <= 26; i++) {
|
|
37
|
+
content[i] = content[counter];
|
|
38
|
+
counter++;
|
|
39
|
+
}
|
|
40
|
+
return content;
|
|
41
|
+
}
|
|
42
|
+
}, [isMobile, content])
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const _options = {
|
|
46
|
+
type: "equal", // compact, equal
|
|
47
|
+
size: 1, // 0, 1
|
|
48
|
+
reflection: 0.6, // 0, 1
|
|
49
|
+
rotateY: 0, // 0, 360
|
|
50
|
+
reverse: false,
|
|
51
|
+
shiftX: 0,
|
|
52
|
+
shiftY: 0,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const render = () => {
|
|
56
|
+
if (!slidesHolder.current) return //bail out;
|
|
57
|
+
|
|
58
|
+
const targetBound = slidesHolder?.current.getBoundingClientRect();
|
|
59
|
+
const childItems = Array.prototype.slice.call(slidesHolder?.current?.children);
|
|
60
|
+
|
|
61
|
+
let coordinates = equalCoordinates(childItems.length, targetBound.width / 2, targetBound.height, targetBound.width / 2, targetBound.height)
|
|
62
|
+
|
|
63
|
+
childItems.forEach((child, index) => {
|
|
64
|
+
if (coordinates[index]) {
|
|
65
|
+
const left = coordinates[index][0] - (child.clientWidth / 2) + _options.shiftX;
|
|
66
|
+
const top = coordinates[index][1] - (child.clientHeight / 2) + _options.shiftY;
|
|
67
|
+
child.style.left = left + "px";
|
|
68
|
+
child.style.top = top + "px";
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const _computeDpt = (r1, r2, theta, rotateY = 0) => {
|
|
74
|
+
const dpt_sin = Math.pow(r1 * Math.sin(theta + rotateY), 2)
|
|
75
|
+
const dpt_cos = Math.pow(r2 * Math.cos(theta + rotateY), 2)
|
|
76
|
+
return Math.sqrt(dpt_sin + dpt_cos)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const equalCoordinates = (n, r1, r2, centerX, centerY) => {
|
|
80
|
+
// type options
|
|
81
|
+
let reflection = -(_options.reflection);
|
|
82
|
+
|
|
83
|
+
let deltaTheta = 0.001
|
|
84
|
+
|
|
85
|
+
let coordinates: number[][] = [];
|
|
86
|
+
let theta = 0;
|
|
87
|
+
|
|
88
|
+
const twoPi = (Math.PI * 2 * _options.size);
|
|
89
|
+
const numIntegrals = Math.round(twoPi / deltaTheta);
|
|
90
|
+
|
|
91
|
+
let circ = 0;
|
|
92
|
+
let dpt = 0;
|
|
93
|
+
|
|
94
|
+
/* integrate over the ellipse to get the circumference */
|
|
95
|
+
for (let i = 1; i < numIntegrals; i++) {
|
|
96
|
+
theta += i * deltaTheta;
|
|
97
|
+
dpt = _computeDpt(r1, r2, theta);
|
|
98
|
+
circ += dpt;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let nextPoint = 0;
|
|
102
|
+
let run = 0;
|
|
103
|
+
theta = 0;
|
|
104
|
+
|
|
105
|
+
const rotateY = (Math.PI / 2 * (_options.rotateY * 4 / 360));
|
|
106
|
+
for (let i = 0; i < numIntegrals; i++) {
|
|
107
|
+
theta += deltaTheta;
|
|
108
|
+
let subIntegral = n * run / circ;
|
|
109
|
+
if (subIntegral >= nextPoint) {
|
|
110
|
+
let x: number = Math.floor((centerX - r1 * Math.cos(theta + rotateY)) * 100) / 100;
|
|
111
|
+
let y: number = Math.floor((centerY + r2 * Math.sin(theta + rotateY) * reflection) * 100) / 100;
|
|
112
|
+
coordinates.push([x, y]);
|
|
113
|
+
|
|
114
|
+
nextPoint++;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
run += _computeDpt(r1, r2, theta, rotateY);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return coordinates;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
render();
|
|
124
|
+
window.addEventListener("resize", render);
|
|
125
|
+
|
|
126
|
+
return () => {
|
|
127
|
+
window.removeEventListener('resize', render)
|
|
128
|
+
}
|
|
129
|
+
}, [isMobile])
|
|
130
|
+
|
|
131
|
+
if (!content) return <></>
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<StyledProductsSlider ref={slider as any} className={className} style={style}>
|
|
135
|
+
<StyledProductsSliderWrapper ref={wrapper as any}>
|
|
136
|
+
<StyledProductsSliderSlides ref={slidesHolder as any}>
|
|
137
|
+
{newContent?.map((item, index) => {
|
|
138
|
+
return (
|
|
139
|
+
<StyledProductsSliderSlide key={`ProductCard-${index}`}>
|
|
140
|
+
<ProductCard
|
|
141
|
+
imageElement={item.imageElement}
|
|
142
|
+
title={item.title}
|
|
143
|
+
description={isMobile ? item?.description : ""}
|
|
144
|
+
/>
|
|
145
|
+
</StyledProductsSliderSlide>
|
|
146
|
+
)
|
|
147
|
+
})}
|
|
148
|
+
</StyledProductsSliderSlides>
|
|
149
|
+
</StyledProductsSliderWrapper>
|
|
150
|
+
{!isMobile && (
|
|
151
|
+
<StyledProductsSliderContent ref={contentHolder as any}>
|
|
152
|
+
<Heading tag="h5" size="h5">
|
|
153
|
+
<strong>{activeElement?.title}</strong>
|
|
154
|
+
<br />
|
|
155
|
+
{activeElement?.description}
|
|
156
|
+
</Heading>
|
|
157
|
+
</StyledProductsSliderContent>
|
|
158
|
+
)}
|
|
159
|
+
</StyledProductsSlider>
|
|
160
|
+
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export default ProductsSlider
|