awesome-coverflow-carousel 0.1.3
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/LICENSE +22 -0
- package/LICENSE.txt +21 -0
- package/README.md +578 -0
- package/dist/carousel-data.json +37 -0
- package/dist/index.js +310 -0
- package/dist/index.umd.cjs +1 -0
- package/dist/style.css +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 AwesomeCoverflowCarousel Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [2026-27] [Pravinkumar Dabade]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
# AwesomeCoverflowCarousel
|
|
2
|
+
|
|
3
|
+
A beautiful, interactive 3D Coverflowcarousel component for React with smooth animations, multiple themes, and flexible data handling. Perfect for showcasing products, portfolios, or any collection of items in an eye-catching carousel format.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **3D CoverflowCarousel** - Visually stunning 3D perspective effects
|
|
8
|
+
- **4 Built-in Themes** - Dark, Light, Neon, and Glass themes
|
|
9
|
+
- **Multiple Control Methods** - Mouse drag, keyboard arrows, touch & programmatic
|
|
10
|
+
- **Auto-Rotate** - Automatic carousel rotation with customizable speed
|
|
11
|
+
- **Responsive** - Works seamlessly on different screen sizes
|
|
12
|
+
- **Smooth Physics** - Realistic inertia and friction animations
|
|
13
|
+
- **Glow Effects** - Beautiful focus glow for the active item
|
|
14
|
+
- **Highly Customizable** - Full control over speed, friction, perspective, and more
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install awesome-coverflow-carousel
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or with pnpm:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add awesome-coverflow-carousel
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or with yarn:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
yarn add awesome-coverflow-carousel
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```jsx
|
|
37
|
+
import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
|
|
38
|
+
import 'awesome-coverflow-carousel/dist/style.css';
|
|
39
|
+
|
|
40
|
+
const slides = [
|
|
41
|
+
{ title: 'Slide 1', description: 'First slide', image: 'url1.jpg' },
|
|
42
|
+
{ title: 'Slide 2', description: 'Second slide', image: 'url2.jpg' },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
export default function App() {
|
|
46
|
+
return (
|
|
47
|
+
<div
|
|
48
|
+
style={{
|
|
49
|
+
minHeight: '100vh',
|
|
50
|
+
padding: '48px 20px 64px',
|
|
51
|
+
background:
|
|
52
|
+
'radial-gradient(70% 50% at 50% 35%, rgba(0,245,255,0.18) 0%, rgba(0,0,0,0) 60%), linear-gradient(180deg, #05070f 0%, #060b1a 55%, #070b12 100%)',
|
|
53
|
+
color: '#e6f0ff',
|
|
54
|
+
display: 'flex',
|
|
55
|
+
flexDirection: 'column',
|
|
56
|
+
alignItems: 'center',
|
|
57
|
+
justifyContent: 'center',
|
|
58
|
+
gap: '18px',
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
<h1 style={{ margin: 0, fontSize: 'clamp(28px, 5vw, 56px)', letterSpacing: '-0.02em' }}>
|
|
62
|
+
Explore the Universe of <span style={{ color: '#00f5ff' }}>Possibilities</span>
|
|
63
|
+
</h1>
|
|
64
|
+
<p style={{ margin: 0, opacity: 0.7 }}>
|
|
65
|
+
Explore the full spectrum of products by clicking on any card
|
|
66
|
+
</p>
|
|
67
|
+
|
|
68
|
+
<div style={{ width: '100%', maxWidth: 980, height: '60vh', minHeight: 420 }}>
|
|
69
|
+
<AwesomeCoverflowCarousel data={slides} theme="dark" />
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Data Format
|
|
77
|
+
|
|
78
|
+
Each item in the carousel requires the following structure:
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
const slide = {
|
|
82
|
+
title: 'Slide 1', // Required: Title displayed on the card
|
|
83
|
+
description: 'First slide', // Optional: Subtitle or description
|
|
84
|
+
image: 'url1.jpg', // Optional: Image URL
|
|
85
|
+
tag: 'Featured', // Optional: Tag label
|
|
86
|
+
color: '#ff6b6b', // Optional: Background color (hex)
|
|
87
|
+
onClick: () => {}, // Optional: Click handler
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
For TypeScript users, this object shape maps directly to the `SlideData` type exported by the package.
|
|
92
|
+
|
|
93
|
+
## Component Props
|
|
94
|
+
|
|
95
|
+
| Prop | Type | Default | Description |
|
|
96
|
+
|------|------|---------|-------------|
|
|
97
|
+
| `data` | `SlideData[]` | **Required** | Array of slide objects to display in the carousel |
|
|
98
|
+
| `autoRotate` | `boolean` | `true` | Enable automatic carousel rotation |
|
|
99
|
+
| `rotationSpeed` | `number` | `2800` | Time in milliseconds between auto-rotations |
|
|
100
|
+
| `friction` | `number` | `0.88` | Friction coefficient for inertia animations (0-1). Higher = more damping |
|
|
101
|
+
| `focusGlow` | `boolean` | `true` | Enable glow effect on the focused card |
|
|
102
|
+
| `theme` | `'dark' \| 'light' \| 'neon' \| 'glass'` | `'dark'` | Visual theme for the carousel |
|
|
103
|
+
| `perspective` | `number` | `1100` | 3D perspective depth in pixels |
|
|
104
|
+
| `onFocusChange` | `(index: number) => void` | `undefined` | Callback fired when the focused item changes |
|
|
105
|
+
| `className` | `string` | `undefined` | Custom CSS class for the carousel container |
|
|
106
|
+
|
|
107
|
+
## Available Themes
|
|
108
|
+
|
|
109
|
+
### Dark Theme
|
|
110
|
+
Modern dark theme with cyan accents. Perfect for tech products and modern designs.
|
|
111
|
+
|
|
112
|
+
```jsx
|
|
113
|
+
<AwesomeCoverflowCarousel data={slides} theme="dark" />
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Light Theme
|
|
117
|
+
Clean light theme with violet accents. Great for portfolios and creative showcases.
|
|
118
|
+
|
|
119
|
+
```jsx
|
|
120
|
+
<AwesomeCoverflowCarousel data={slides} theme="light" />
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Neon Theme
|
|
124
|
+
Vibrant neon magenta and cyan theme. Bold and eye-catching for entertainment and gaming.
|
|
125
|
+
|
|
126
|
+
```jsx
|
|
127
|
+
<AwesomeCoverflowCarousel data={slides} theme="neon" />
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Glass Theme
|
|
131
|
+
Frosted glass effect with semi-transparent cards. Modern and elegant for premium brands.
|
|
132
|
+
|
|
133
|
+
```jsx
|
|
134
|
+
<AwesomeCoverflowCarousel data={slides} theme="glass" />
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Usage Examples
|
|
138
|
+
|
|
139
|
+
### Example 1: Static Data Source
|
|
140
|
+
|
|
141
|
+
Use hardcoded data directly in your component:
|
|
142
|
+
|
|
143
|
+
```jsx
|
|
144
|
+
import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
|
|
145
|
+
import 'awesome-coverflow-carousel/dist/style.css';
|
|
146
|
+
|
|
147
|
+
export default function StaticDataExample() {
|
|
148
|
+
const staticSlides = [
|
|
149
|
+
{
|
|
150
|
+
title: 'Product A',
|
|
151
|
+
description: 'Premium quality product',
|
|
152
|
+
image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=500&h=300&fit=crop',
|
|
153
|
+
tag: 'Featured',
|
|
154
|
+
onClick: () => console.log('Product A clicked')
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
title: 'Product B',
|
|
158
|
+
description: 'Best seller item',
|
|
159
|
+
image: 'https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=500&h=300&fit=crop',
|
|
160
|
+
tag: 'Sale',
|
|
161
|
+
onClick: () => console.log('Product B clicked')
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
title: 'Product C',
|
|
165
|
+
description: 'New arrival',
|
|
166
|
+
image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=500&h=300&fit=crop',
|
|
167
|
+
tag: 'New',
|
|
168
|
+
onClick: () => console.log('Product C clicked')
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
title: 'Product D',
|
|
172
|
+
description: 'Limited edition',
|
|
173
|
+
image: 'https://images.unsplash.com/photo-1517457373614-b7152f800fd1?w=500&h=300&fit=crop',
|
|
174
|
+
tag: 'Limited',
|
|
175
|
+
onClick: () => console.log('Product D clicked')
|
|
176
|
+
},
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
181
|
+
<h1 style={{ textAlign: 'center', padding: '20px' }}>Static Data Example</h1>
|
|
182
|
+
<div style={{ flex: 1 }}>
|
|
183
|
+
<AwesomeCoverflowCarousel
|
|
184
|
+
data={staticSlides}
|
|
185
|
+
theme="dark"
|
|
186
|
+
onFocusChange={(index) => console.log('Focused item:', index)}
|
|
187
|
+
/>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Example 2: JSON File Data Source
|
|
195
|
+
|
|
196
|
+
Load carousel data from a JSON file:
|
|
197
|
+
|
|
198
|
+
```jsx
|
|
199
|
+
import { useEffect, useState } from 'react';
|
|
200
|
+
import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
|
|
201
|
+
import 'awesome-coverflow-carousel/dist/style.css';
|
|
202
|
+
|
|
203
|
+
export default function JSONDataExample() {
|
|
204
|
+
const [slides, setSlides] = useState([]);
|
|
205
|
+
const [loading, setLoading] = useState(true);
|
|
206
|
+
const [error, setError] = useState(null);
|
|
207
|
+
|
|
208
|
+
useEffect(() => {
|
|
209
|
+
// Load slides from JSON file in public folder
|
|
210
|
+
fetch('/carousel-data.json')
|
|
211
|
+
.then((response) => {
|
|
212
|
+
if (!response.ok) throw new Error('Failed to load data');
|
|
213
|
+
return response.json();
|
|
214
|
+
})
|
|
215
|
+
.then((data) => {
|
|
216
|
+
setSlides(data);
|
|
217
|
+
setLoading(false);
|
|
218
|
+
})
|
|
219
|
+
.catch((err) => {
|
|
220
|
+
setError(err.message);
|
|
221
|
+
setLoading(false);
|
|
222
|
+
});
|
|
223
|
+
}, []);
|
|
224
|
+
|
|
225
|
+
if (loading) return <div style={{ textAlign: 'center', padding: '20px' }}>Loading...</div>;
|
|
226
|
+
if (error) return <div style={{ textAlign: 'center', padding: '20px', color: 'red' }}>Error: {error}</div>;
|
|
227
|
+
|
|
228
|
+
return (
|
|
229
|
+
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
230
|
+
<h1 style={{ textAlign: 'center', padding: '20px' }}>JSON File Data Example</h1>
|
|
231
|
+
<div style={{ flex: 1 }}>
|
|
232
|
+
<AwesomeCoverflowCarousel
|
|
233
|
+
data={slides}
|
|
234
|
+
theme="light"
|
|
235
|
+
autoRotate={true}
|
|
236
|
+
rotationSpeed={3000}
|
|
237
|
+
onFocusChange={(index) => console.log('Focused item:', index)}
|
|
238
|
+
/>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Sample `carousel-data.json` (place in `public` folder):**
|
|
246
|
+
|
|
247
|
+
```json
|
|
248
|
+
[
|
|
249
|
+
{
|
|
250
|
+
"title": "Portfolio Project 1",
|
|
251
|
+
"description": "Award-winning design system",
|
|
252
|
+
"image": "https://images.unsplash.com/photo-1561070791-2526d30994b5?w=500&h=300&fit=crop",
|
|
253
|
+
"tag": "Design",
|
|
254
|
+
"color": "#1e3a8a"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"title": "Portfolio Project 2",
|
|
258
|
+
"description": "Enterprise web application",
|
|
259
|
+
"image": "https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=500&h=300&fit=crop",
|
|
260
|
+
"tag": "Development",
|
|
261
|
+
"color": "#064e3b"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"title": "Portfolio Project 3",
|
|
265
|
+
"description": "Mobile app with 10M+ downloads",
|
|
266
|
+
"image": "https://images.unsplash.com/photo-1560807707-38cc612d91b3?w=500&h=300&fit=crop",
|
|
267
|
+
"tag": "Mobile",
|
|
268
|
+
"color": "#5b1f39"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"title": "Portfolio Project 4",
|
|
272
|
+
"description": "Real-time data visualization",
|
|
273
|
+
"image": "https://images.unsplash.com/photo-1516321295223-4f2d3f2cf1e1?w=500&h=300&fit=crop",
|
|
274
|
+
"tag": "Analytics",
|
|
275
|
+
"color": "#78350f"
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Example 3: REST API Data Source
|
|
281
|
+
|
|
282
|
+
Fetch carousel data from a REST API:
|
|
283
|
+
|
|
284
|
+
```jsx
|
|
285
|
+
import { useEffect, useState } from 'react';
|
|
286
|
+
import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
|
|
287
|
+
import 'awesome-coverflow-carousel/dist/style.css';
|
|
288
|
+
|
|
289
|
+
export default function RESTAPIExample() {
|
|
290
|
+
const [slides, setSlides] = useState([]);
|
|
291
|
+
const [loading, setLoading] = useState(true);
|
|
292
|
+
const [error, setError] = useState(null);
|
|
293
|
+
const [focusedItem, setFocusedItem] = useState(null);
|
|
294
|
+
|
|
295
|
+
useEffect(() => {
|
|
296
|
+
// Fetch from a REST API endpoint
|
|
297
|
+
fetch('https://api.example.com/carousel-items')
|
|
298
|
+
.then((response) => {
|
|
299
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
300
|
+
return response.json();
|
|
301
|
+
})
|
|
302
|
+
.then((data) => {
|
|
303
|
+
// Transform API response to match SlideData format
|
|
304
|
+
const transformedData = data.map((item) => ({
|
|
305
|
+
title: item.name || item.title,
|
|
306
|
+
description: item.summary || item.description,
|
|
307
|
+
image: item.thumbnail || item.image,
|
|
308
|
+
tag: item.category || item.type,
|
|
309
|
+
color: item.accentColor,
|
|
310
|
+
onClick: () => console.log(`Clicked: ${item.id}`)
|
|
311
|
+
}));
|
|
312
|
+
setSlides(transformedData);
|
|
313
|
+
setLoading(false);
|
|
314
|
+
})
|
|
315
|
+
.catch((err) => {
|
|
316
|
+
setError(err.message);
|
|
317
|
+
setLoading(false);
|
|
318
|
+
});
|
|
319
|
+
}, []);
|
|
320
|
+
|
|
321
|
+
const handleFocusChange = (index) => {
|
|
322
|
+
setFocusedItem(slides[index] || null);
|
|
323
|
+
console.log(`Focused on: ${slides[index]?.title}`);
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
if (loading) {
|
|
327
|
+
return (
|
|
328
|
+
<div style={{ textAlign: 'center', padding: '20px', color: '#999' }}>
|
|
329
|
+
Loading carousel data...
|
|
330
|
+
</div>
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (error) {
|
|
335
|
+
return (
|
|
336
|
+
<div style={{ textAlign: 'center', padding: '20px', color: 'red' }}>
|
|
337
|
+
Error loading data: {error}
|
|
338
|
+
</div>
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return (
|
|
343
|
+
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
344
|
+
<h1 style={{ textAlign: 'center', padding: '20px' }}>REST API Data Example</h1>
|
|
345
|
+
|
|
346
|
+
{focusedItem && (
|
|
347
|
+
<div style={{
|
|
348
|
+
textAlign: 'center',
|
|
349
|
+
padding: '10px 20px',
|
|
350
|
+
backgroundColor: 'rgba(0, 245, 255, 0.1)',
|
|
351
|
+
borderBottom: '1px solid rgba(0, 245, 255, 0.2)',
|
|
352
|
+
}}>
|
|
353
|
+
<p>Currently viewing: <strong>{focusedItem.title}</strong></p>
|
|
354
|
+
{focusedItem.description && <p style={{ fontSize: '0.9em', color: '#aaa' }}>{focusedItem.description}</p>}
|
|
355
|
+
</div>
|
|
356
|
+
)}
|
|
357
|
+
|
|
358
|
+
<div style={{ flex: 1 }}>
|
|
359
|
+
<AwesomeCoverflowCarousel
|
|
360
|
+
data={slides}
|
|
361
|
+
theme="neon"
|
|
362
|
+
autoRotate={false}
|
|
363
|
+
friction={0.85}
|
|
364
|
+
perspective={1200}
|
|
365
|
+
focusGlow={true}
|
|
366
|
+
onFocusChange={handleFocusChange}
|
|
367
|
+
/>
|
|
368
|
+
</div>
|
|
369
|
+
|
|
370
|
+
<div style={{
|
|
371
|
+
textAlign: 'center',
|
|
372
|
+
padding: '15px',
|
|
373
|
+
fontSize: '0.85em',
|
|
374
|
+
color: '#888',
|
|
375
|
+
borderTop: '1px solid rgba(255, 255, 255, 0.1)',
|
|
376
|
+
}}>
|
|
377
|
+
Use arrow keys or drag to navigate • Current count: {slides.length} items
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## Customization Examples
|
|
385
|
+
|
|
386
|
+
### Custom Styling with Themes
|
|
387
|
+
|
|
388
|
+
```jsx
|
|
389
|
+
import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
|
|
390
|
+
import 'awesome-coverflow-carousel/dist/style.css';
|
|
391
|
+
|
|
392
|
+
export default function CustomizedCarousel() {
|
|
393
|
+
const carouselContainer = {
|
|
394
|
+
width: '100%',
|
|
395
|
+
height: '100vh',
|
|
396
|
+
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const slides = [/* your slides */];
|
|
400
|
+
|
|
401
|
+
return (
|
|
402
|
+
<div style={carouselContainer}>
|
|
403
|
+
<AwesomeCoverflowCarousel
|
|
404
|
+
data={slides}
|
|
405
|
+
theme="glass"
|
|
406
|
+
autoRotate={true}
|
|
407
|
+
rotationSpeed={3500}
|
|
408
|
+
friction={0.90}
|
|
409
|
+
perspective={1300}
|
|
410
|
+
focusGlow={true}
|
|
411
|
+
onFocusChange={(index) => {
|
|
412
|
+
// Custom handler
|
|
413
|
+
}}
|
|
414
|
+
/>
|
|
415
|
+
</div>
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Controlled Carousel with External Controls
|
|
421
|
+
|
|
422
|
+
```jsx
|
|
423
|
+
import { useRef, useState } from 'react';
|
|
424
|
+
import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
|
|
425
|
+
import 'awesome-coverflow-carousel/dist/style.css';
|
|
426
|
+
|
|
427
|
+
export default function ControlledCarousel() {
|
|
428
|
+
const carouselRef = useRef(null);
|
|
429
|
+
const [focusedIndex, setFocusedIndex] = useState(0);
|
|
430
|
+
|
|
431
|
+
const slides = [
|
|
432
|
+
{ title: 'Slide 1', description: 'First', image: 'url1.jpg' },
|
|
433
|
+
{ title: 'Slide 2', description: 'Second', image: 'url2.jpg' },
|
|
434
|
+
{ title: 'Slide 3', description: 'Third', image: 'url3.jpg' },
|
|
435
|
+
];
|
|
436
|
+
|
|
437
|
+
return (
|
|
438
|
+
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
439
|
+
<div style={{ flex: 1 }}>
|
|
440
|
+
<AwesomeCoverflowCarousel
|
|
441
|
+
ref={carouselRef}
|
|
442
|
+
data={slides}
|
|
443
|
+
theme="dark"
|
|
444
|
+
onFocusChange={setFocusedIndex}
|
|
445
|
+
/>
|
|
446
|
+
</div>
|
|
447
|
+
|
|
448
|
+
<div style={{ display: 'flex', gap: '10px', justifyContent: 'center', padding: '20px' }}>
|
|
449
|
+
<button onClick={() => {/* prev */}}>← Previous</button>
|
|
450
|
+
<span>{focusedIndex + 1} / {slides.length}</span>
|
|
451
|
+
<button onClick={() => {/* next */}}>Next →</button>
|
|
452
|
+
</div>
|
|
453
|
+
</div>
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## Interaction Methods
|
|
459
|
+
|
|
460
|
+
### Mouse Interactions
|
|
461
|
+
- **Drag**: Click and drag left/right to rotate the carousel
|
|
462
|
+
- **Click**: Click on a side item to bring it to center
|
|
463
|
+
|
|
464
|
+
### Keyboard Interactions
|
|
465
|
+
- **Arrow Left**: Rotate to previous item
|
|
466
|
+
- **Arrow Right**: Rotate to next item
|
|
467
|
+
|
|
468
|
+
### Mouse Events
|
|
469
|
+
- **Hover**: Pauses auto-rotation when hovering over the carousel
|
|
470
|
+
- **Leave**: Resumes auto-rotation when mouse leaves
|
|
471
|
+
|
|
472
|
+
## Performance Tips
|
|
473
|
+
|
|
474
|
+
1. **Optimize Images**: Use optimized image URLs for better performance
|
|
475
|
+
2. **Lazy Loading**: Load large datasets progressively
|
|
476
|
+
3. **Memoize Callbacks**: Use `useCallback` for `onFocusChange` handlers
|
|
477
|
+
4. **Responsive Container**: Set appropriate dimensions for different screen sizes
|
|
478
|
+
|
|
479
|
+
```jsx
|
|
480
|
+
// Example with responsive sizing
|
|
481
|
+
<div style={{
|
|
482
|
+
width: '100%',
|
|
483
|
+
height: window.innerWidth < 768 ? '60vh' : '100vh'
|
|
484
|
+
}}>
|
|
485
|
+
<AwesomeCoverflowCarousel data={slides} />
|
|
486
|
+
</div>
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## Styling
|
|
490
|
+
|
|
491
|
+
The component comes with built-in styles. Import the CSS file:
|
|
492
|
+
|
|
493
|
+
```jsx
|
|
494
|
+
import 'awesome-coverflow-carousel/dist/style.css';
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
All theme colors and styles are defined in the included CSS. You can override default styles with custom CSS classes:
|
|
498
|
+
|
|
499
|
+
```css
|
|
500
|
+
/* Override carousel styles */
|
|
501
|
+
.custom-carousel {
|
|
502
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
```jsx
|
|
507
|
+
<AwesomeCoverflowCarousel
|
|
508
|
+
data={slides}
|
|
509
|
+
className="custom-carousel"
|
|
510
|
+
/>
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
## Browser Support
|
|
514
|
+
|
|
515
|
+
- Chrome/Edge (latest)
|
|
516
|
+
- Firefox (latest)
|
|
517
|
+
- Safari (latest)
|
|
518
|
+
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
519
|
+
|
|
520
|
+
## API Reference
|
|
521
|
+
|
|
522
|
+
### Component Props (Detailed)
|
|
523
|
+
|
|
524
|
+
#### `data: SlideData[]` (Required)
|
|
525
|
+
Array of slide objects. Each object must have at least a `title` property. See [Data Format](#data-format) above.
|
|
526
|
+
|
|
527
|
+
#### `autoRotate: boolean` (Default: `true`)
|
|
528
|
+
When enabled, the carousel automatically rotates to the next item after `rotationSpeed` milliseconds.
|
|
529
|
+
|
|
530
|
+
#### `rotationSpeed: number` (Default: `2800`)
|
|
531
|
+
Time in milliseconds between auto-rotations. Only applies if `autoRotate` is `true`.
|
|
532
|
+
|
|
533
|
+
#### `friction: number` (Default: `0.88`)
|
|
534
|
+
Controls how quickly animations decelerate. Range: 0-1
|
|
535
|
+
- `0.8` - More responsive, snappier animations
|
|
536
|
+
- `0.88` - Default, balanced feel
|
|
537
|
+
- `0.95` - Slower, smoother animations
|
|
538
|
+
|
|
539
|
+
#### `focusGlow: boolean` (Default: `true`)
|
|
540
|
+
Displays a glowing effect around the currently focused card. The glow color matches the selected theme.
|
|
541
|
+
|
|
542
|
+
#### `theme: 'dark' | 'light' | 'neon' | 'glass'` (Default: `'dark'`)
|
|
543
|
+
Selects the visual appearance of the carousel. See [Available Themes](#available-themes).
|
|
544
|
+
|
|
545
|
+
#### `perspective: number` (Default: `1100`)
|
|
546
|
+
Controls the 3D perspective depth in pixels. Higher values create less dramatic 3D effects.
|
|
547
|
+
- `800` - Strong 3D effect, cards spread wider
|
|
548
|
+
- `1100` - Default, balanced 3D
|
|
549
|
+
- `1500` - Subtle 3D, cards closer together
|
|
550
|
+
|
|
551
|
+
#### `onFocusChange: (index: number) => void`
|
|
552
|
+
Callback function fired whenever the focused item changes. Receives the index of the newly focused item.
|
|
553
|
+
|
|
554
|
+
#### `className: string`
|
|
555
|
+
Custom CSS class applied to the carousel container for additional customization.
|
|
556
|
+
|
|
557
|
+
## Troubleshooting
|
|
558
|
+
|
|
559
|
+
### Carousel not rotating
|
|
560
|
+
- Check that `autoRotate` is set to `true`
|
|
561
|
+
- Verify `rotationSpeed` is not too high (should be in milliseconds)
|
|
562
|
+
- Ensure the data array has at least 2 items
|
|
563
|
+
|
|
564
|
+
### Images not displaying
|
|
565
|
+
- Verify image URLs are accessible and correct
|
|
566
|
+
- Check browser console for CORS errors
|
|
567
|
+
- Use absolute URLs for remote images
|
|
568
|
+
|
|
569
|
+
### 3D effects not visible
|
|
570
|
+
- Ensure CSS is imported: `import 'awesome-coverflow-carousel/dist/style.css'`
|
|
571
|
+
- Check that `perspective` prop is not set too high
|
|
572
|
+
- Verify browser supports 3D transforms (all modern browsers)
|
|
573
|
+
|
|
574
|
+
### Performance issues on mobile
|
|
575
|
+
- Reduce the number of images or use smaller dimensions
|
|
576
|
+
- Set `autoRotate={false}` if performance is critical
|
|
577
|
+
- Use optimized/compressed images
|
|
578
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"title": "Portfolio Project 1",
|
|
4
|
+
"description": "Award-winning design system",
|
|
5
|
+
"image": "https://images.unsplash.com/photo-1561070791-2526d30994b5?w=500&h=300&fit=crop",
|
|
6
|
+
"tag": "Design",
|
|
7
|
+
"color": "#1e3a8a"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"title": "Portfolio Project 2",
|
|
11
|
+
"description": "Enterprise web application",
|
|
12
|
+
"image": "https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=500&h=300&fit=crop",
|
|
13
|
+
"tag": "Development",
|
|
14
|
+
"color": "#064e3b"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"title": "Portfolio Project 3",
|
|
18
|
+
"description": "Mobile app with 10M+ downloads",
|
|
19
|
+
"image": "https://images.unsplash.com/photo-1560807707-38cc612d91b3?w=500&h=300&fit=crop",
|
|
20
|
+
"tag": "Mobile",
|
|
21
|
+
"color": "#5b1f39"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"title": "Portfolio Project 4",
|
|
25
|
+
"description": "Real-time data visualization",
|
|
26
|
+
"image": "https://images.unsplash.com/photo-1516321295223-4f2d3f2cf1e1?w=500&h=300&fit=crop",
|
|
27
|
+
"tag": "Analytics",
|
|
28
|
+
"color": "#78350f"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"title": "E-Commerce Platform",
|
|
32
|
+
"description": "Full-stack shopping experience",
|
|
33
|
+
"image": "https://images.unsplash.com/photo-1460925895917-adf4e565e6c1?w=500&h=300&fit=crop",
|
|
34
|
+
"tag": "Commerce",
|
|
35
|
+
"color": "#4c0519"
|
|
36
|
+
}
|
|
37
|
+
]
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { jsx as c, jsxs as A } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as d, useState as tt, useCallback as v, useEffect as z, useMemo as rt } from "react";
|
|
3
|
+
const et = {
|
|
4
|
+
name: "dark",
|
|
5
|
+
background: "transparent",
|
|
6
|
+
cardBg: "rgba(10, 15, 30, 0.85)",
|
|
7
|
+
cardBorder: "rgba(0, 245, 255, 0.2)",
|
|
8
|
+
cardText: "#f1f5f9",
|
|
9
|
+
cardSubtext: "#94a3b8",
|
|
10
|
+
focusGlow: "0 0 40px rgba(0, 245, 255, 0.5), 0 0 80px rgba(0, 245, 255, 0.2)",
|
|
11
|
+
navBg: "rgba(0, 245, 255, 0.1)",
|
|
12
|
+
navText: "#00f5ff",
|
|
13
|
+
indicatorActive: "#00f5ff",
|
|
14
|
+
indicatorInactive: "rgba(0, 245, 255, 0.25)"
|
|
15
|
+
}, nt = {
|
|
16
|
+
name: "light",
|
|
17
|
+
background: "transparent",
|
|
18
|
+
cardBg: "rgba(255, 255, 255, 0.92)",
|
|
19
|
+
cardBorder: "rgba(124, 58, 237, 0.25)",
|
|
20
|
+
cardText: "#1e293b",
|
|
21
|
+
cardSubtext: "#64748b",
|
|
22
|
+
focusGlow: "0 0 40px rgba(124, 58, 237, 0.35), 0 8px 32px rgba(0,0,0,0.15)",
|
|
23
|
+
navBg: "rgba(124, 58, 237, 0.1)",
|
|
24
|
+
navText: "#7c3aed",
|
|
25
|
+
indicatorActive: "#7c3aed",
|
|
26
|
+
indicatorInactive: "rgba(124, 58, 237, 0.2)"
|
|
27
|
+
}, at = {
|
|
28
|
+
name: "neon",
|
|
29
|
+
background: "transparent",
|
|
30
|
+
cardBg: "rgba(5, 0, 20, 0.9)",
|
|
31
|
+
cardBorder: "rgba(255, 0, 255, 0.4)",
|
|
32
|
+
cardText: "#fff",
|
|
33
|
+
cardSubtext: "#f0abfc",
|
|
34
|
+
focusGlow: "0 0 50px rgba(255,0,255,0.6), 0 0 100px rgba(0,255,255,0.3)",
|
|
35
|
+
navBg: "rgba(255, 0, 255, 0.1)",
|
|
36
|
+
navText: "#ff00ff",
|
|
37
|
+
indicatorActive: "#ff00ff",
|
|
38
|
+
indicatorInactive: "rgba(255,0,255,0.2)"
|
|
39
|
+
}, ot = {
|
|
40
|
+
name: "glass",
|
|
41
|
+
background: "transparent",
|
|
42
|
+
cardBg: "rgba(255, 255, 255, 0.08)",
|
|
43
|
+
cardBorder: "rgba(255, 255, 255, 0.2)",
|
|
44
|
+
cardText: "#ffffff",
|
|
45
|
+
cardSubtext: "rgba(255,255,255,0.65)",
|
|
46
|
+
focusGlow: "0 8px 32px rgba(255,255,255,0.15), inset 0 1px 0 rgba(255,255,255,0.3)",
|
|
47
|
+
navBg: "rgba(255,255,255,0.1)",
|
|
48
|
+
navText: "#ffffff",
|
|
49
|
+
indicatorActive: "#ffffff",
|
|
50
|
+
indicatorInactive: "rgba(255,255,255,0.3)"
|
|
51
|
+
}, W = {
|
|
52
|
+
dark: et,
|
|
53
|
+
light: nt,
|
|
54
|
+
neon: at,
|
|
55
|
+
glass: ot
|
|
56
|
+
}, j = 220, H = 300, X = 155, it = 55, Y = 0.8, ct = 0.64, st = 0.72, dt = 0.4, lt = 3.4;
|
|
57
|
+
function bt({
|
|
58
|
+
data: e,
|
|
59
|
+
autoRotate: s = !0,
|
|
60
|
+
rotationSpeed: l = 2800,
|
|
61
|
+
friction: n = 0.88,
|
|
62
|
+
focusGlow: h = !0,
|
|
63
|
+
theme: q = "dark",
|
|
64
|
+
perspective: F = 1100,
|
|
65
|
+
onFocusChange: f,
|
|
66
|
+
className: U
|
|
67
|
+
}) {
|
|
68
|
+
const o = e.length, Z = W[q] || W.dark, p = d(0), g = d(0), b = d(0), m = d(0), u = d(!1), G = d(0), L = d(0), k = d(null), S = d(!1), [T, I] = tt(0), M = v(() => {
|
|
69
|
+
if (u.current) return;
|
|
70
|
+
const t = p.current, a = g.current, i = a - t;
|
|
71
|
+
b.current = b.current * n + i * (1 - n) * 0.28;
|
|
72
|
+
const r = t + b.current;
|
|
73
|
+
if (p.current = r, I(r), Math.abs(i) < 8e-4 && Math.abs(b.current) < 8e-4) {
|
|
74
|
+
p.current = a, I(a);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
m.current = requestAnimationFrame(M);
|
|
78
|
+
}, [n]), y = v(() => {
|
|
79
|
+
cancelAnimationFrame(m.current), m.current = requestAnimationFrame(M);
|
|
80
|
+
}, [M]), x = v((t) => {
|
|
81
|
+
g.current += t, b.current = 0, y();
|
|
82
|
+
const a = (Math.round(g.current) % o + o) % o;
|
|
83
|
+
f == null || f(a);
|
|
84
|
+
}, [o, y, f]);
|
|
85
|
+
z(() => {
|
|
86
|
+
if (!s) return;
|
|
87
|
+
const t = () => {
|
|
88
|
+
k.current = setTimeout(() => {
|
|
89
|
+
!u.current && !S.current && x(1), t();
|
|
90
|
+
}, l);
|
|
91
|
+
};
|
|
92
|
+
return t(), () => {
|
|
93
|
+
k.current && clearTimeout(k.current);
|
|
94
|
+
};
|
|
95
|
+
}, [s, l, x]);
|
|
96
|
+
const K = v((t) => {
|
|
97
|
+
u.current = !0, G.current = t.clientX, L.current = p.current, b.current = 0, cancelAnimationFrame(m.current), t.target.setPointerCapture(t.pointerId);
|
|
98
|
+
}, []), N = v((t) => {
|
|
99
|
+
if (!u.current) return;
|
|
100
|
+
const i = -((t.clientX - G.current) / X), r = L.current + i;
|
|
101
|
+
p.current = r, g.current = r, I(r);
|
|
102
|
+
}, []), V = v((t) => {
|
|
103
|
+
if (!u.current) return;
|
|
104
|
+
u.current = !1, g.current = Math.round(p.current), y();
|
|
105
|
+
const a = (Math.round(g.current) % o + o) % o;
|
|
106
|
+
f == null || f(a);
|
|
107
|
+
}, [o, y, f]);
|
|
108
|
+
z(() => {
|
|
109
|
+
const t = (a) => {
|
|
110
|
+
a.key === "ArrowLeft" && x(-1), a.key === "ArrowRight" && x(1);
|
|
111
|
+
};
|
|
112
|
+
return window.addEventListener("keydown", t), () => window.removeEventListener("keydown", t);
|
|
113
|
+
}, [x]), z(() => () => cancelAnimationFrame(m.current), []);
|
|
114
|
+
const J = (Math.round(T) % o + o) % o, Q = rt(() => e.map((t, a) => {
|
|
115
|
+
let i = a - T;
|
|
116
|
+
i = i - Math.round(i / o) * o;
|
|
117
|
+
const r = Math.abs(i), R = i >= 0 ? 1 : -1, B = r < lt, E = R * Math.min(it + r * 8, 85), $ = i * X, C = Math.max(0, 100 - r * 70), w = r < 0.05 ? 1 : r < 1.5 ? 1 - (1 - Y) * r : Math.max(ct, Y - (r - 1) * 0.1), D = r < 0.05 ? 1 : r < 1.5 ? 1 - (1 - st) * r : Math.max(0, dt - (r - 2) * 0.25), _ = Math.round(100 - r * 20);
|
|
118
|
+
return { slide: t, i: a, visible: B, rotY: r < 0.05 ? 0 : E, translateX: $, translateZ: C, scale: w, opacity: D, zIndex: _, dist: i };
|
|
119
|
+
}), [e, T, o]);
|
|
120
|
+
return /* @__PURE__ */ c(
|
|
121
|
+
"div",
|
|
122
|
+
{
|
|
123
|
+
className: U,
|
|
124
|
+
style: {
|
|
125
|
+
position: "relative",
|
|
126
|
+
width: "100%",
|
|
127
|
+
height: "100%",
|
|
128
|
+
cursor: u.current ? "grabbing" : "grab",
|
|
129
|
+
userSelect: "none",
|
|
130
|
+
outline: "none",
|
|
131
|
+
overflow: "hidden"
|
|
132
|
+
},
|
|
133
|
+
onPointerDown: K,
|
|
134
|
+
onPointerMove: N,
|
|
135
|
+
onPointerUp: V,
|
|
136
|
+
onMouseEnter: () => {
|
|
137
|
+
S.current = !0;
|
|
138
|
+
},
|
|
139
|
+
onMouseLeave: () => {
|
|
140
|
+
S.current = !1;
|
|
141
|
+
},
|
|
142
|
+
tabIndex: 0,
|
|
143
|
+
role: "region",
|
|
144
|
+
"aria-label": "Coverflow Carousel",
|
|
145
|
+
children: /* @__PURE__ */ c("div", { style: {
|
|
146
|
+
position: "absolute",
|
|
147
|
+
inset: 0,
|
|
148
|
+
perspective: `${F}px`,
|
|
149
|
+
perspectiveOrigin: "50% 50%",
|
|
150
|
+
display: "flex",
|
|
151
|
+
alignItems: "center",
|
|
152
|
+
justifyContent: "center"
|
|
153
|
+
}, children: /* @__PURE__ */ c("div", { style: { position: "relative", width: 0, height: 0, transformStyle: "preserve-3d" }, children: Q.map(({ slide: t, i: a, visible: i, rotY: r, translateX: R, translateZ: B, scale: E, opacity: $, zIndex: C, dist: w }) => {
|
|
154
|
+
if (!i) return null;
|
|
155
|
+
const D = a === J, _ = Math.abs(w);
|
|
156
|
+
return /* @__PURE__ */ c(
|
|
157
|
+
"div",
|
|
158
|
+
{
|
|
159
|
+
style: {
|
|
160
|
+
position: "absolute",
|
|
161
|
+
width: `${j}px`,
|
|
162
|
+
height: `${H}px`,
|
|
163
|
+
left: `${-j / 2}px`,
|
|
164
|
+
top: `${-H / 2}px`,
|
|
165
|
+
transform: `translateX(${R}px) translateZ(${B}px) rotateY(${r}deg) scale(${E})`,
|
|
166
|
+
opacity: $,
|
|
167
|
+
zIndex: C,
|
|
168
|
+
transition: u.current ? "none" : "transform 0.55s cubic-bezier(0.25,0.46,0.45,0.94), opacity 0.5s ease",
|
|
169
|
+
willChange: "transform, opacity",
|
|
170
|
+
cursor: "pointer"
|
|
171
|
+
},
|
|
172
|
+
onClick: () => {
|
|
173
|
+
var P, O;
|
|
174
|
+
_ > 0.3 ? x(Math.round(w)) : ((P = t.onClick) == null || P.call(t), (O = t.imageClick) == null || O.call(t));
|
|
175
|
+
},
|
|
176
|
+
children: /* @__PURE__ */ c(
|
|
177
|
+
ft,
|
|
178
|
+
{
|
|
179
|
+
slide: t,
|
|
180
|
+
isFocused: D,
|
|
181
|
+
focusGlow: h,
|
|
182
|
+
theme: Z
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
},
|
|
186
|
+
a
|
|
187
|
+
);
|
|
188
|
+
}) }) })
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
function ft({ slide: e, isFocused: s, focusGlow: l, theme: n }) {
|
|
193
|
+
const h = s && l ? n.focusGlow : void 0;
|
|
194
|
+
return /* @__PURE__ */ A("div", { style: {
|
|
195
|
+
width: "100%",
|
|
196
|
+
height: "100%",
|
|
197
|
+
borderRadius: "18px",
|
|
198
|
+
overflow: "hidden",
|
|
199
|
+
position: "relative",
|
|
200
|
+
background: n.cardBg,
|
|
201
|
+
border: `1.5px solid ${s ? n.indicatorActive : n.cardBorder}`,
|
|
202
|
+
boxShadow: h || (s ? "0 24px 64px rgba(0,0,0,0.65), 0 8px 24px rgba(0,0,0,0.4)" : "0 8px 32px rgba(0,0,0,0.4)"),
|
|
203
|
+
backdropFilter: "blur(12px)",
|
|
204
|
+
WebkitBackdropFilter: "blur(12px)",
|
|
205
|
+
transition: "border-color 0.4s, box-shadow 0.4s",
|
|
206
|
+
display: "flex",
|
|
207
|
+
flexDirection: "column"
|
|
208
|
+
}, children: [
|
|
209
|
+
/* @__PURE__ */ A("div", { style: { flex: "0 0 65%", position: "relative", overflow: "hidden" }, children: [
|
|
210
|
+
e.image ? /* @__PURE__ */ c(
|
|
211
|
+
"img",
|
|
212
|
+
{
|
|
213
|
+
src: e.image,
|
|
214
|
+
alt: e.title,
|
|
215
|
+
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
216
|
+
}
|
|
217
|
+
) : /* @__PURE__ */ c(ut, { title: e.title, color: e.color, accent: n.indicatorActive }),
|
|
218
|
+
e.tag && /* @__PURE__ */ c("span", { style: {
|
|
219
|
+
position: "absolute",
|
|
220
|
+
top: 10,
|
|
221
|
+
right: 10,
|
|
222
|
+
background: n.indicatorActive,
|
|
223
|
+
color: "#000",
|
|
224
|
+
fontSize: "9px",
|
|
225
|
+
fontWeight: 800,
|
|
226
|
+
letterSpacing: "0.08em",
|
|
227
|
+
padding: "3px 9px",
|
|
228
|
+
borderRadius: "100px",
|
|
229
|
+
fontFamily: "var(--font-display)",
|
|
230
|
+
textTransform: "uppercase"
|
|
231
|
+
}, children: e.tag }),
|
|
232
|
+
/* @__PURE__ */ c("div", { style: {
|
|
233
|
+
position: "absolute",
|
|
234
|
+
bottom: 0,
|
|
235
|
+
left: 0,
|
|
236
|
+
right: 0,
|
|
237
|
+
height: "50%",
|
|
238
|
+
background: `linear-gradient(to bottom, transparent, ${n.cardBg})`
|
|
239
|
+
} })
|
|
240
|
+
] }),
|
|
241
|
+
/* @__PURE__ */ A("div", { style: {
|
|
242
|
+
flex: 1,
|
|
243
|
+
padding: "12px 16px 16px",
|
|
244
|
+
display: "flex",
|
|
245
|
+
flexDirection: "column",
|
|
246
|
+
justifyContent: "center",
|
|
247
|
+
gap: "5px"
|
|
248
|
+
}, children: [
|
|
249
|
+
/* @__PURE__ */ c("div", { style: {
|
|
250
|
+
fontFamily: "var(--font-display)",
|
|
251
|
+
fontWeight: 800,
|
|
252
|
+
fontSize: "15px",
|
|
253
|
+
color: n.cardText,
|
|
254
|
+
lineHeight: 1.25,
|
|
255
|
+
letterSpacing: "-0.02em"
|
|
256
|
+
}, children: e.title }),
|
|
257
|
+
e.description && /* @__PURE__ */ c("div", { style: {
|
|
258
|
+
fontFamily: "var(--font-body)",
|
|
259
|
+
fontSize: "11px",
|
|
260
|
+
color: n.cardSubtext,
|
|
261
|
+
lineHeight: 1.5,
|
|
262
|
+
fontWeight: 300
|
|
263
|
+
}, children: e.description }),
|
|
264
|
+
s && /* @__PURE__ */ c("div", { style: {
|
|
265
|
+
marginTop: "6px",
|
|
266
|
+
padding: "7px 16px",
|
|
267
|
+
borderRadius: "100px",
|
|
268
|
+
background: n.indicatorActive,
|
|
269
|
+
color: "#000",
|
|
270
|
+
fontSize: "10px",
|
|
271
|
+
fontWeight: 800,
|
|
272
|
+
fontFamily: "var(--font-display)",
|
|
273
|
+
letterSpacing: "0.05em",
|
|
274
|
+
textTransform: "uppercase",
|
|
275
|
+
cursor: "pointer",
|
|
276
|
+
alignSelf: "flex-start"
|
|
277
|
+
}, children: "Learn More →" })
|
|
278
|
+
] })
|
|
279
|
+
] });
|
|
280
|
+
}
|
|
281
|
+
function ut({ title: e, color: s, accent: l }) {
|
|
282
|
+
const n = ["#020d2e", "#1e1b4b", "#0c1445", "#1a0533", "#0d2137", "#1f1235", "#0a1400", "#1a1000", "#001820", "#160028"], h = s || n[e.charCodeAt(0) % n.length];
|
|
283
|
+
return /* @__PURE__ */ A("div", { style: {
|
|
284
|
+
width: "100%",
|
|
285
|
+
height: "100%",
|
|
286
|
+
background: `linear-gradient(145deg, ${h} 0%, ${l}22 100%)`,
|
|
287
|
+
display: "flex",
|
|
288
|
+
alignItems: "center",
|
|
289
|
+
justifyContent: "center",
|
|
290
|
+
position: "relative"
|
|
291
|
+
}, children: [
|
|
292
|
+
/* @__PURE__ */ c("div", { style: {
|
|
293
|
+
position: "absolute",
|
|
294
|
+
inset: 0,
|
|
295
|
+
background: `radial-gradient(circle at 60% 40%, ${l}38, transparent 65%)`
|
|
296
|
+
} }),
|
|
297
|
+
/* @__PURE__ */ c("span", { style: {
|
|
298
|
+
fontFamily: "var(--font-display)",
|
|
299
|
+
fontWeight: 900,
|
|
300
|
+
fontSize: "52px",
|
|
301
|
+
color: l,
|
|
302
|
+
opacity: 0.88,
|
|
303
|
+
position: "relative",
|
|
304
|
+
zIndex: 1
|
|
305
|
+
}, children: e.slice(0, 2).toUpperCase() })
|
|
306
|
+
] });
|
|
307
|
+
}
|
|
308
|
+
export {
|
|
309
|
+
bt as AwesomeCoverflowCarousel
|
|
310
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(d,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],t):(d=typeof globalThis<"u"?globalThis:d||self,t(d.AwesomeCoverflowCarousel={},d.jsxRuntime,d.React))})(this,(function(d,t,n){"use strict";const j={dark:{name:"dark",background:"transparent",cardBg:"rgba(10, 15, 30, 0.85)",cardBorder:"rgba(0, 245, 255, 0.2)",cardText:"#f1f5f9",cardSubtext:"#94a3b8",focusGlow:"0 0 40px rgba(0, 245, 255, 0.5), 0 0 80px rgba(0, 245, 255, 0.2)",navBg:"rgba(0, 245, 255, 0.1)",navText:"#00f5ff",indicatorActive:"#00f5ff",indicatorInactive:"rgba(0, 245, 255, 0.25)"},light:{name:"light",background:"transparent",cardBg:"rgba(255, 255, 255, 0.92)",cardBorder:"rgba(124, 58, 237, 0.25)",cardText:"#1e293b",cardSubtext:"#64748b",focusGlow:"0 0 40px rgba(124, 58, 237, 0.35), 0 8px 32px rgba(0,0,0,0.15)",navBg:"rgba(124, 58, 237, 0.1)",navText:"#7c3aed",indicatorActive:"#7c3aed",indicatorInactive:"rgba(124, 58, 237, 0.2)"},neon:{name:"neon",background:"transparent",cardBg:"rgba(5, 0, 20, 0.9)",cardBorder:"rgba(255, 0, 255, 0.4)",cardText:"#fff",cardSubtext:"#f0abfc",focusGlow:"0 0 50px rgba(255,0,255,0.6), 0 0 100px rgba(0,255,255,0.3)",navBg:"rgba(255, 0, 255, 0.1)",navText:"#ff00ff",indicatorActive:"#ff00ff",indicatorInactive:"rgba(255,0,255,0.2)"},glass:{name:"glass",background:"transparent",cardBg:"rgba(255, 255, 255, 0.08)",cardBorder:"rgba(255, 255, 255, 0.2)",cardText:"#ffffff",cardSubtext:"rgba(255,255,255,0.65)",focusGlow:"0 8px 32px rgba(255,255,255,0.15), inset 0 1px 0 rgba(255,255,255,0.3)",navBg:"rgba(255,255,255,0.1)",navText:"#ffffff",indicatorActive:"#ffffff",indicatorInactive:"rgba(255,255,255,0.3)"}},_=220,P=300,z=155,X=55,G=.8,Y=.64,q=.72,F=.4,U=3.4;function Z({data:o,autoRotate:l=!0,rotationSpeed:f=2800,friction:a=.88,focusGlow:v=!0,theme:V="dark",perspective:J=1100,onFocusChange:u,className:Q}){const c=o.length,ee=j[V]||j.dark,g=n.useRef(0),b=n.useRef(0),x=n.useRef(0),y=n.useRef(0),p=n.useRef(!1),L=n.useRef(0),O=n.useRef(0),w=n.useRef(null),A=n.useRef(!1),[T,S]=n.useState(0),C=n.useCallback(()=>{if(p.current)return;const e=g.current,i=b.current,s=i-e;x.current=x.current*a+s*(1-a)*.28;const r=e+x.current;if(g.current=r,S(r),Math.abs(s)<8e-4&&Math.abs(x.current)<8e-4){g.current=i,S(i);return}y.current=requestAnimationFrame(C)},[a]),m=n.useCallback(()=>{cancelAnimationFrame(y.current),y.current=requestAnimationFrame(C)},[C]),h=n.useCallback(e=>{b.current+=e,x.current=0,m();const i=(Math.round(b.current)%c+c)%c;u==null||u(i)},[c,m,u]);n.useEffect(()=>{if(!l)return;const e=()=>{w.current=setTimeout(()=>{!p.current&&!A.current&&h(1),e()},f)};return e(),()=>{w.current&&clearTimeout(w.current)}},[l,f,h]);const te=n.useCallback(e=>{p.current=!0,L.current=e.clientX,O.current=g.current,x.current=0,cancelAnimationFrame(y.current),e.target.setPointerCapture(e.pointerId)},[]),re=n.useCallback(e=>{if(!p.current)return;const s=-((e.clientX-L.current)/z),r=O.current+s;g.current=r,b.current=r,S(r)},[]),ne=n.useCallback(e=>{if(!p.current)return;p.current=!1,b.current=Math.round(g.current),m();const i=(Math.round(b.current)%c+c)%c;u==null||u(i)},[c,m,u]);n.useEffect(()=>{const e=i=>{i.key==="ArrowLeft"&&h(-1),i.key==="ArrowRight"&&h(1)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[h]),n.useEffect(()=>()=>cancelAnimationFrame(y.current),[]);const oe=(Math.round(T)%c+c)%c,ae=n.useMemo(()=>o.map((e,i)=>{let s=i-T;s=s-Math.round(s/c)*c;const r=Math.abs(s),I=s>=0?1:-1,M=r<U,B=I*Math.min(X+r*8,85),E=s*z,$=Math.max(0,100-r*70),k=r<.05?1:r<1.5?1-(1-G)*r:Math.max(Y,G-(r-1)*.1),D=r<.05?1:r<1.5?1-(1-q)*r:Math.max(0,F-(r-2)*.25),R=Math.round(100-r*20);return{slide:e,i,visible:M,rotY:r<.05?0:B,translateX:E,translateZ:$,scale:k,opacity:D,zIndex:R,dist:s}}),[o,T,c]);return t.jsx("div",{className:Q,style:{position:"relative",width:"100%",height:"100%",cursor:p.current?"grabbing":"grab",userSelect:"none",outline:"none",overflow:"hidden"},onPointerDown:te,onPointerMove:re,onPointerUp:ne,onMouseEnter:()=>{A.current=!0},onMouseLeave:()=>{A.current=!1},tabIndex:0,role:"region","aria-label":"Coverflow Carousel",children:t.jsx("div",{style:{position:"absolute",inset:0,perspective:`${J}px`,perspectiveOrigin:"50% 50%",display:"flex",alignItems:"center",justifyContent:"center"},children:t.jsx("div",{style:{position:"relative",width:0,height:0,transformStyle:"preserve-3d"},children:ae.map(({slide:e,i,visible:s,rotY:r,translateX:I,translateZ:M,scale:B,opacity:E,zIndex:$,dist:k})=>{if(!s)return null;const D=i===oe,R=Math.abs(k);return t.jsx("div",{style:{position:"absolute",width:`${_}px`,height:`${P}px`,left:`${-_/2}px`,top:`${-P/2}px`,transform:`translateX(${I}px) translateZ(${M}px) rotateY(${r}deg) scale(${B})`,opacity:E,zIndex:$,transition:p.current?"none":"transform 0.55s cubic-bezier(0.25,0.46,0.45,0.94), opacity 0.5s ease",willChange:"transform, opacity",cursor:"pointer"},onClick:()=>{var W,H;R>.3?h(Math.round(k)):((W=e.onClick)==null||W.call(e),(H=e.imageClick)==null||H.call(e))},children:t.jsx(K,{slide:e,isFocused:D,focusGlow:v,theme:ee})},i)})})})})}function K({slide:o,isFocused:l,focusGlow:f,theme:a}){const v=l&&f?a.focusGlow:void 0;return t.jsxs("div",{style:{width:"100%",height:"100%",borderRadius:"18px",overflow:"hidden",position:"relative",background:a.cardBg,border:`1.5px solid ${l?a.indicatorActive:a.cardBorder}`,boxShadow:v||(l?"0 24px 64px rgba(0,0,0,0.65), 0 8px 24px rgba(0,0,0,0.4)":"0 8px 32px rgba(0,0,0,0.4)"),backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)",transition:"border-color 0.4s, box-shadow 0.4s",display:"flex",flexDirection:"column"},children:[t.jsxs("div",{style:{flex:"0 0 65%",position:"relative",overflow:"hidden"},children:[o.image?t.jsx("img",{src:o.image,alt:o.title,style:{width:"100%",height:"100%",objectFit:"cover",display:"block"}}):t.jsx(N,{title:o.title,color:o.color,accent:a.indicatorActive}),o.tag&&t.jsx("span",{style:{position:"absolute",top:10,right:10,background:a.indicatorActive,color:"#000",fontSize:"9px",fontWeight:800,letterSpacing:"0.08em",padding:"3px 9px",borderRadius:"100px",fontFamily:"var(--font-display)",textTransform:"uppercase"},children:o.tag}),t.jsx("div",{style:{position:"absolute",bottom:0,left:0,right:0,height:"50%",background:`linear-gradient(to bottom, transparent, ${a.cardBg})`}})]}),t.jsxs("div",{style:{flex:1,padding:"12px 16px 16px",display:"flex",flexDirection:"column",justifyContent:"center",gap:"5px"},children:[t.jsx("div",{style:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"15px",color:a.cardText,lineHeight:1.25,letterSpacing:"-0.02em"},children:o.title}),o.description&&t.jsx("div",{style:{fontFamily:"var(--font-body)",fontSize:"11px",color:a.cardSubtext,lineHeight:1.5,fontWeight:300},children:o.description}),l&&t.jsx("div",{style:{marginTop:"6px",padding:"7px 16px",borderRadius:"100px",background:a.indicatorActive,color:"#000",fontSize:"10px",fontWeight:800,fontFamily:"var(--font-display)",letterSpacing:"0.05em",textTransform:"uppercase",cursor:"pointer",alignSelf:"flex-start"},children:"Learn More →"})]})]})}function N({title:o,color:l,accent:f}){const a=["#020d2e","#1e1b4b","#0c1445","#1a0533","#0d2137","#1f1235","#0a1400","#1a1000","#001820","#160028"],v=l||a[o.charCodeAt(0)%a.length];return t.jsxs("div",{style:{width:"100%",height:"100%",background:`linear-gradient(145deg, ${v} 0%, ${f}22 100%)`,display:"flex",alignItems:"center",justifyContent:"center",position:"relative"},children:[t.jsx("div",{style:{position:"absolute",inset:0,background:`radial-gradient(circle at 60% 40%, ${f}38, transparent 65%)`}}),t.jsx("span",{style:{fontFamily:"var(--font-display)",fontWeight:900,fontSize:"52px",color:f,opacity:.88,position:"relative",zIndex:1},children:o.slice(0,2).toUpperCase()})]})}d.AwesomeCoverflowCarousel=Z,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--awesome-carousel-dark-bg: #030712;--awesome-carousel-light-text: #f1f5f9;--awesome-carousel-secondary-text: #94a3b8;--awesome-carousel-cyan: #00f5ff;--awesome-carousel-violet: #7c3aed;--awesome-carousel-amber: #f59e0b;--awesome-carousel-card-dark-bg: rgba(10, 15, 30, .85);--awesome-carousel-card-dark-border: rgba(0, 245, 255, .2);--awesome-carousel-glow-dark: 0 0 40px rgba(0, 245, 255, .5), 0 0 80px rgba(0, 245, 255, .2);--awesome-carousel-nav-dark-bg: rgba(0, 245, 255, .1);--awesome-carousel-nav-dark-text: #00f5ff;--awesome-carousel-indicator-active-dark: #00f5ff;--awesome-carousel-indicator-inactive-dark: rgba(0, 245, 255, .25)}@media(prefers-color-scheme:light){:root{--awesome-carousel-dark-bg: #f8fafc;--awesome-carousel-light-text: #1e293b;--awesome-carousel-secondary-text: #64748b}}.awesome-carousel-root *,.awesome-carousel-root *:before,.awesome-carousel-root *:after{box-sizing:border-box;margin:0;padding:0}.awesome-carousel-root{position:relative;width:100%;height:100%;font-family:DM Sans,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.awesome-coverflow-carousel{position:relative;width:100%;height:100%;overflow:hidden;background:transparent;cursor:grab;-webkit-user-select:none;user-select:none;outline:none}.awesome-coverflow-carousel:active{cursor:grabbing}.awesome-coverflow-carousel[role=region]{outline:none}.awesome-coverflow-carousel:focus-visible{outline:2px solid var(--awesome-carousel-cyan);outline-offset:4px}.awesome-carousel-stage{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;perspective:1100px;perspective-origin:50% 50%;transform-style:preserve-3d}.awesome-carousel-stage__inner{position:relative;width:0;height:0;transform-style:preserve-3d}.awesome-carousel-card{position:absolute;width:220px;height:300px;border-radius:18px;overflow:hidden;will-change:transform,opacity;transform-style:preserve-3d;backface-visibility:hidden}.awesome-carousel-card--transition{transition:transform .55s cubic-bezier(.25,.46,.45,.94),opacity .5s ease}.awesome-carousel-card--no-transition{transition:none}.awesome-carousel-card:hover{z-index:1000!important}.awesome-carousel-card__content{width:100%;height:100%;display:flex;flex-direction:column;border-radius:18px;overflow:hidden;position:relative;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);transition:border-color .4s,box-shadow .4s}.awesome-carousel-card__content--dark{background:var(--awesome-carousel-card-dark-bg);border:1.5px solid var(--awesome-carousel-card-dark-border);color:var(--awesome-carousel-light-text);box-shadow:0 8px 32px #0006}.awesome-carousel-card__content--dark.focused{border-color:var(--awesome-carousel-indicator-active-dark);box-shadow:var(--awesome-carousel-glow-dark)}.awesome-carousel-card__content--light{background:#ffffffeb;border:1.5px solid rgba(124,58,237,.25);color:#1e293b;box-shadow:0 8px 32px #00000026}.awesome-carousel-card__content--light.focused{border-color:var(--awesome-carousel-violet);box-shadow:0 0 40px #7c3aed59,0 8px 32px #00000026}.awesome-carousel-card__content--neon{background:#050014e6;border:1.5px solid rgba(255,0,255,.4);color:#fff;box-shadow:0 8px 32px #0006}.awesome-carousel-card__content--neon.focused{border-color:#f0f;box-shadow:0 0 50px #f0f9,0 0 100px #00ffff4d}.awesome-carousel-card__content--glass{background:#ffffff14;border:1.5px solid rgba(255,255,255,.2);color:#fff;box-shadow:0 8px 32px #ffffff26,inset 0 1px #ffffff4d}.awesome-carousel-card__content--glass.focused{border-color:#fff;box-shadow:0 8px 32px #fff3,inset 0 1px #fff6}.awesome-carousel-card__image-area{flex:0 0 65%;position:relative;overflow:hidden;background:#0000004d}.awesome-carousel-card__image{width:100%;height:100%;object-fit:cover;display:block;transition:transform .3s ease}.awesome-carousel-card:hover .awesome-carousel-card__image{transform:scale(1.05)}.awesome-carousel-card__image-placeholder{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#7c3aed33,#00f5ff33);color:#ffffff4d;font-size:2em}.awesome-carousel-card__text-area{flex:1;padding:16px 14px;display:flex;flex-direction:column;gap:6px;overflow:hidden}.awesome-carousel-card__title{font-size:14px;font-weight:600;line-height:1.4;text-transform:uppercase;letter-spacing:.5px;margin:0}.awesome-carousel-card__description{font-size:12px;line-height:1.3;margin:0;opacity:.8}.awesome-carousel-card__tag{display:inline-block;padding:4px 8px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;width:fit-content;margin-top:auto}.awesome-carousel-card__content--dark .awesome-carousel-card__tag{background:var(--awesome-carousel-nav-dark-bg);color:var(--awesome-carousel-nav-dark-text)}.awesome-carousel-card__content--light .awesome-carousel-card__tag{background:#7c3aed1a;color:var(--awesome-carousel-violet)}.awesome-carousel-card__content--neon .awesome-carousel-card__tag{background:#ff00ff26;color:#f0f}.awesome-carousel-card__content--glass .awesome-carousel-card__tag{background:#ffffff26;color:#fff}.sphere-item{transition:transform .2s ease}.sphere-item--lift:hover{transform:translate(-50%,-52%)!important;filter:brightness(1.1)}.sphere-item--zoom:hover{transform:translate(-50%,-50%) scale(1.12)!important}.sphere-item--tilt:hover{transform:translate(-50%,-50%) rotateY(-5deg) rotateX(5deg)!important}.sphere-item:focus{outline:none}.sphere-item:focus-visible{outline:2px solid var(--awesome-carousel-cyan);outline-offset:4px;border-radius:16px}input[type=range]{-webkit-appearance:none;width:100%;height:4px;border-radius:2px;background:#ffffff1a;outline:none;cursor:pointer}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;border-radius:50%;background:var(--awesome-carousel-cyan);cursor:pointer;transition:box-shadow .2s ease}input[type=range]::-webkit-slider-thumb:hover{box-shadow:0 0 10px var(--awesome-carousel-cyan)}input[type=range]::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--awesome-carousel-cyan);cursor:pointer;border:none;transition:box-shadow .2s ease}input[type=range]::-moz-range-thumb:hover{box-shadow:0 0 10px var(--awesome-carousel-cyan)}input[type=range]::-moz-range-track{background:transparent;border:none}input[type=range]::-moz-range-progress{background:var(--awesome-carousel-cyan);height:4px;border-radius:2px}@keyframes starfield{0%{transform:translateY(0)}to{transform:translateY(-50%)}}@keyframes pulseGlow{0%,to{opacity:.4;transform:scale(1)}50%{opacity:.8;transform:scale(1.05)}}@keyframes fadeUp{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}@keyframes rotate360{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes cardEntrance{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}@keyframes slideIn{0%{transform:translate(-20px);opacity:0}to{transform:translate(0);opacity:1}}.awesome-carousel-nav{display:flex;gap:10px;justify-content:center;padding:20px;background:transparent}.awesome-carousel-nav__button{padding:8px 16px;border:1px solid currentColor;border-radius:6px;background:transparent;color:inherit;cursor:pointer;font-size:14px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;transition:all .3s ease;outline:none}.awesome-carousel-nav__button:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0003}.awesome-carousel-nav__button:active{transform:translateY(0)}.awesome-carousel-nav__button:focus-visible{outline:2px solid var(--awesome-carousel-cyan);outline-offset:2px}.awesome-carousel-nav--dark .awesome-carousel-nav__button{color:var(--awesome-carousel-nav-dark-text);border-color:var(--awesome-carousel-nav-dark-text)}.awesome-carousel-nav--dark .awesome-carousel-nav__button:hover{background:var(--awesome-carousel-nav-dark-bg)}.awesome-carousel-nav--light .awesome-carousel-nav__button{color:var(--awesome-carousel-violet);border-color:var(--awesome-carousel-violet)}.awesome-carousel-nav--light .awesome-carousel-nav__button:hover{background:#7c3aed1a}.awesome-carousel-indicators{display:flex;gap:8px;justify-content:center;padding:16px;background:transparent}.awesome-carousel-indicator{width:8px;height:8px;border-radius:50%;cursor:pointer;transition:all .3s ease;border:none;padding:0}.awesome-carousel-indicator:hover{transform:scale(1.3)}.awesome-carousel-indicator:focus-visible{outline:2px solid var(--awesome-carousel-cyan);outline-offset:2px}.awesome-carousel-indicators--dark .awesome-carousel-indicator{background:var(--awesome-carousel-indicator-inactive-dark)}.awesome-carousel-indicators--dark .awesome-carousel-indicator.active{background:var(--awesome-carousel-indicator-active-dark);box-shadow:0 0 10px var(--awesome-carousel-indicator-active-dark)}.awesome-carousel-indicators--light .awesome-carousel-indicator{background:#7c3aed33}.awesome-carousel-indicators--light .awesome-carousel-indicator.active{background:var(--awesome-carousel-violet);box-shadow:0 0 10px #7c3aed80}.awesome-carousel-indicators--neon .awesome-carousel-indicator{background:#f0f3}.awesome-carousel-indicators--neon .awesome-carousel-indicator.active{background:#f0f;box-shadow:0 0 10px #f0f}.awesome-carousel-indicators--glass .awesome-carousel-indicator{background:#ffffff4d}.awesome-carousel-indicators--glass .awesome-carousel-indicator.active{background:#fff;box-shadow:0 0 10px #fff9}.awesome-carousel-fade-enter{animation:fadeUp .3s ease-out}.awesome-carousel-card-entrance{animation:cardEntrance .4s cubic-bezier(.34,1.56,.64,1)}.awesome-carousel-slide-in{animation:slideIn .3s ease-out}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}.awesome-carousel-card--transition{transition:none}}@media(max-width:768px){.awesome-carousel-card{width:180px;height:240px}.awesome-carousel-card__title{font-size:13px}.awesome-carousel-card__description{font-size:11px}.awesome-carousel-nav{padding:15px;gap:8px}.awesome-carousel-nav__button{padding:6px 12px;font-size:12px}.awesome-carousel-indicators{gap:6px;padding:12px}.awesome-carousel-indicator{width:6px;height:6px}}@media(max-width:480px){.awesome-carousel-card{width:150px;height:200px}.awesome-carousel-card__image-area{flex:0 0 60%}.awesome-carousel-card__text-area{padding:12px 10px;gap:4px}.awesome-carousel-card__title{font-size:12px}.awesome-carousel-card__description{font-size:10px}.awesome-carousel-card__tag{font-size:9px;padding:3px 6px}}.awesome-carousel-a11y-skip{position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden}.awesome-carousel-a11y-skip:focus{position:static;width:auto;height:auto;padding:10px;background:var(--awesome-carousel-cyan);color:var(--awesome-carousel-dark-bg);outline:2px solid var(--awesome-carousel-cyan)}@media(prefers-contrast:more){.awesome-carousel-card__content--dark{border-color:var(--awesome-carousel-indicator-active-dark)}.awesome-carousel-card__content--light{border-color:var(--awesome-carousel-violet)}.awesome-carousel-indicator{border:1px solid currentColor}}@media(forced-colors:active){.awesome-carousel-card__content,.awesome-carousel-nav__button,.awesome-carousel-indicator{border:1px solid}}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "awesome-coverflow-carousel",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "A beautiful, interactive 3D Coverflowcarousel component for React with smooth animations, multiple themes, and flexible data handling",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"require": "./dist/index.umd.cjs"
|
|
17
|
+
},
|
|
18
|
+
"./dist/style.css": "./dist/style.css"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"dev": "vite",
|
|
22
|
+
"build": "tsc -b && vite build",
|
|
23
|
+
"preview": "vite preview",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"react",
|
|
28
|
+
"carousel",
|
|
29
|
+
"coverflow",
|
|
30
|
+
"3d",
|
|
31
|
+
"ring",
|
|
32
|
+
"component",
|
|
33
|
+
"interactive",
|
|
34
|
+
"animation",
|
|
35
|
+
"theme",
|
|
36
|
+
"ui"
|
|
37
|
+
],
|
|
38
|
+
"author": "Pravinkumar Dabade",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"peerDependenciesMeta": {
|
|
41
|
+
"react": {
|
|
42
|
+
"optional": false
|
|
43
|
+
},
|
|
44
|
+
"react-dom": {
|
|
45
|
+
"optional": false
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"react": "^19.0.0",
|
|
50
|
+
"react-dom": "^19.0.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/react": "^19.0.0",
|
|
54
|
+
"@types/react-dom": "^19.0.0",
|
|
55
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
56
|
+
"typescript": "~5.6.2",
|
|
57
|
+
"vite": "^6.0.5"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=14.0.0",
|
|
61
|
+
"npm": ">=6.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|