scroll-slides 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,11 +1,367 @@
1
1
  # scroll-slides
2
2
 
3
- ## Install
3
+ English | [简体中文](./README_zh.md)
4
+
5
+ A smooth and customizable scroll-based slide animation component for Vue 3. Create engaging scroll experiences with dynamic scaling, translation, and occlusion effects.
6
+
7
+ ![npm version](https://img.shields.io/npm/v/scroll-slides.svg)
8
+ ![license](https://img.shields.io/npm/l/scroll-slides.svg)
9
+
10
+ ## ✨ Features
11
+
12
+ - 🎯 **Smooth Scroll Animations** - Transform items as they scroll with elegant scaling and translation effects
13
+ - 📱 **Direction Support** - Both vertical and horizontal scrolling modes
14
+ - 🎨 **Highly Customizable** - Fine-tune animation parameters to match your design
15
+ - 🔄 **Dynamic Item Management** - Add or remove items on the fly
16
+ - 📐 **Flexible Templates** - Use generic or per-item slot templates
17
+ - 🚀 **Performance Optimized** - Efficient event handling and DOM updates
18
+ - 💅 **TypeScript Support** - Full type definitions included
19
+ - 🎭 **Occlusion Effects** - Optional lower item clipping for depth perception
20
+
21
+ ## 📦 Installation
4
22
 
5
23
  ```bash
6
24
  npm install scroll-slides
25
+ ```
7
26
 
27
+ ```bash
8
28
  yarn add scroll-slides
29
+ ```
9
30
 
31
+ ```bash
10
32
  pnpm add scroll-slides
11
33
  ```
34
+
35
+ ## 🚀 Quick Start
36
+
37
+ ### Basic Usage
38
+
39
+ ```vue
40
+ <script setup>
41
+ import { ScrollSlide } from 'scroll-slides';
42
+ </script>
43
+
44
+ <template>
45
+ <ScrollSlide
46
+ direction="vertical"
47
+ :item-count="10"
48
+ style="height: 600px; overflow-y: auto;"
49
+ >
50
+ <template #item="{ index }">
51
+ <div class="slide-item">
52
+ Slide {{ index + 1 }}
53
+ </div>
54
+ </template>
55
+ </ScrollSlide>
56
+ </template>
57
+
58
+ <style scoped>
59
+ .slide-item {
60
+ width: 100%;
61
+ height: 100px;
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
66
+ border-radius: 15px;
67
+ color: white;
68
+ margin-bottom: 10px;
69
+ }
70
+ </style>
71
+ ```
72
+
73
+ ### Horizontal Scrolling
74
+
75
+ ```vue
76
+ <template>
77
+ <ScrollSlide
78
+ direction="horizontal"
79
+ :item-count="15"
80
+ :scale-start-percent="0.95"
81
+ :translate-factor="50"
82
+ :spacer-enabled="true"
83
+ style="width: 100%; height: 200px; overflow-x: auto;"
84
+ >
85
+ <template #item="{ index }">
86
+ <div class="horizontal-item">
87
+ Item {{ index + 1 }}
88
+ </div>
89
+ </template>
90
+ </ScrollSlide>
91
+ </template>
92
+
93
+ <style scoped>
94
+ .horizontal-item {
95
+ width: 200px;
96
+ height: 120px;
97
+ margin-right: 15px;
98
+ background: #4CAF50;
99
+ border-radius: 10px;
100
+ display: flex;
101
+ justify-content: center;
102
+ align-items: center;
103
+ color: white;
104
+ }
105
+ </style>
106
+ ```
107
+
108
+ ### Independent Templates
109
+
110
+ You can define unique content for each item using indexed slots:
111
+
112
+ ```vue
113
+ <template>
114
+ <ScrollSlide direction="vertical" :item-count="3">
115
+ <template #item-0>
116
+ <div class="custom-item">🌸 First Item</div>
117
+ </template>
118
+
119
+ <template #item-1>
120
+ <div class="custom-item">🎨 Second Item</div>
121
+ </template>
122
+
123
+ <template #item-2>
124
+ <div class="custom-item">🚀 Third Item</div>
125
+ </template>
126
+ </ScrollSlide>
127
+ </template>
128
+ ```
129
+
130
+ ## 📖 API Reference
131
+
132
+ ### Props
133
+
134
+ | Prop | Type | Default | Description |
135
+ |------|------|---------|-------------|
136
+ | `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | Scrolling direction |
137
+ | `itemCount` | `number` | `0` | Total number of items in the list |
138
+ | `scaleRatio` | `number` | `0.7` | Final scale of the item when it slides out (0-1) |
139
+ | `scaleStartPercent` | `number` | `0.8` | Threshold percentage for scaling to start (0-1) |
140
+ | `translateFactor` | `number` | `100` | Adjusts the displacement offset during slide-out |
141
+ | `spacerEnabled` | `boolean` | `false` | Adds a spacer at start to allow first item to scroll out |
142
+ | `occludeLowerItems` | `boolean` | `false` | Applies clip-path to prevent visual overlap |
143
+
144
+ ### Slots
145
+
146
+ #### Default Item Slot
147
+
148
+ Used when no specific item slot is defined:
149
+
150
+ ```vue
151
+ <template #item="{ index }">
152
+ <!-- Your content here -->
153
+ <!-- index: number - The zero-based index of the current item -->
154
+ </template>
155
+ ```
156
+
157
+ #### Indexed Item Slots
158
+
159
+ Define unique content for specific items:
160
+
161
+ ```vue
162
+ <template #item-0>
163
+ <!-- Content for first item -->
164
+ </template>
165
+
166
+ <template #item-1>
167
+ <!-- Content for second item -->
168
+ </template>
169
+ ```
170
+
171
+ **Note:** Indexed slots take priority over the generic `#item` slot.
172
+
173
+ #### Spacer Slot
174
+
175
+ Customize the spacer element (when `spacerEnabled` is `true`):
176
+
177
+ ```vue
178
+ <template #spacer="{ size }">
179
+ <!-- size: number - The calculated size of the spacer in pixels -->
180
+ <div>Custom Spacer Content</div>
181
+ </template>
182
+ ```
183
+
184
+ ## 🎨 Customization Examples
185
+
186
+ ### Subtle Animation
187
+
188
+ ```vue
189
+ <ScrollSlide
190
+ :scale-ratio="0.9"
191
+ :scale-start-percent="0.95"
192
+ :translate-factor="20"
193
+ :item-count="10"
194
+ >
195
+ <template #item="{ index }">
196
+ <!-- Your content -->
197
+ </template>
198
+ </ScrollSlide>
199
+ ```
200
+
201
+ ### Dramatic Effect
202
+
203
+ ```vue
204
+ <ScrollSlide
205
+ :scale-ratio="0.5"
206
+ :scale-start-percent="0.7"
207
+ :translate-factor="150"
208
+ :occlude-lower-items="true"
209
+ :item-count="10"
210
+ >
211
+ <template #item="{ index }">
212
+ <!-- Your content -->
213
+ </template>
214
+ </ScrollSlide>
215
+ ```
216
+
217
+ ### Horizontal Card Carousel
218
+
219
+ ```vue
220
+ <ScrollSlide
221
+ direction="horizontal"
222
+ :item-count="20"
223
+ :scale-ratio="0.85"
224
+ :scale-start-percent="0.9"
225
+ :translate-factor="30"
226
+ :spacer-enabled="true"
227
+ style="width: 100%; height: 250px; overflow-x: auto;"
228
+ >
229
+ <template #item="{ index }">
230
+ <div class="card">
231
+ Card {{ index + 1 }}
232
+ </div>
233
+ </template>
234
+ </ScrollSlide>
235
+ ```
236
+
237
+ ## 🔧 Advanced Usage
238
+
239
+ ### Dynamic Item Count
240
+
241
+ ```vue
242
+ <script setup>
243
+ import { ref } from 'vue';
244
+ import { ScrollSlide } from 'scroll-slides';
245
+
246
+ const items = ref([1, 2, 3, 4, 5]);
247
+
248
+ const addItem = () => {
249
+ items.value.push(items.value.length + 1);
250
+ };
251
+
252
+ const removeItem = () => {
253
+ items.value.pop();
254
+ };
255
+ </script>
256
+
257
+ <template>
258
+ <div>
259
+ <button @click="addItem">Add Item</button>
260
+ <button @click="removeItem">Remove Item</button>
261
+
262
+ <ScrollSlide :item-count="items.length">
263
+ <template #item="{ index }">
264
+ <div>Item {{ items[index] }}</div>
265
+ </template>
266
+ </ScrollSlide>
267
+ </div>
268
+ </template>
269
+ ```
270
+
271
+ ### Responsive Configuration
272
+
273
+ ```vue
274
+ <script setup>
275
+ import { ref, computed, onMounted, onUnmounted } from 'vue';
276
+ import { ScrollSlide } from 'scroll-slides';
277
+
278
+ const windowWidth = ref(window.innerWidth);
279
+
280
+ const direction = computed(() =>
281
+ windowWidth.value < 768 ? 'vertical' : 'horizontal'
282
+ );
283
+
284
+ const updateWidth = () => {
285
+ windowWidth.value = window.innerWidth;
286
+ };
287
+
288
+ onMounted(() => window.addEventListener('resize', updateWidth));
289
+ onUnmounted(() => window.removeEventListener('resize', updateWidth));
290
+ </script>
291
+
292
+ <template>
293
+ <ScrollSlide
294
+ :direction="direction"
295
+ :item-count="10"
296
+ :style="direction === 'vertical'
297
+ ? 'height: 500px; overflow-y: auto;'
298
+ : 'width: 100%; overflow-x: auto;'"
299
+ >
300
+ <template #item="{ index }">
301
+ <!-- Responsive content -->
302
+ </template>
303
+ </ScrollSlide>
304
+ </template>
305
+ ```
306
+
307
+ ## 💡 Tips & Best Practices
308
+
309
+ 1. **Container Styling**: Always set explicit dimensions and overflow properties on the ScrollSlide container:
310
+ ```vue
311
+ <ScrollSlide style="height: 600px; overflow-y: auto;">
312
+ ```
313
+
314
+ 2. **Item Spacing**: Add margins to your item content, not the slot wrapper:
315
+ ```css
316
+ .my-item {
317
+ margin-bottom: 10px; /* for vertical */
318
+ margin-right: 10px; /* for horizontal */
319
+ }
320
+ ```
321
+
322
+ 3. **Performance**: For large lists, consider using virtual scrolling techniques in combination with scroll-slides.
323
+
324
+ 4. **Z-Index**: Items are automatically z-indexed in reverse order (first item on top). Plan your designs accordingly.
325
+
326
+ 5. **Spacer Usage**: Enable `spacerEnabled` when you want the first item to be able to scroll to the center/top of the viewport.
327
+
328
+ ## 🛠️ Development
329
+
330
+ ```bash
331
+ # Clone the repository
332
+ git clone https://github.com/agoudbg/scroll-slides.git
333
+
334
+ # Install dependencies
335
+ pnpm install
336
+
337
+ # Run development server
338
+ pnpm dev
339
+
340
+ # Build library
341
+ pnpm build
342
+
343
+ # Build demo
344
+ pnpm build:demo
345
+ ```
346
+
347
+ ## 📄 License
348
+
349
+ MIT License - see [LICENSE](LICENSE) file for details
350
+
351
+ ## 🤝 Contributing
352
+
353
+ Contributions, issues, and feature requests are welcome! Feel free to check the [issues page](https://github.com/agoudbg/scroll-slides/issues).
354
+
355
+ ## 👤 Author
356
+
357
+ **agoudbg**
358
+ - GitHub: [@agoudbg](https://github.com/agoudbg)
359
+ - Email: agoudbg@gmail.com
360
+
361
+ ## 🌟 Show Your Support
362
+
363
+ Give a ⭐️ if this project helped you!
364
+
365
+ ---
366
+
367
+ Made with ❤️ using Vue 3 and TypeScript
@@ -1,144 +1,142 @@
1
- declare const spacerEnabled: import("vue").Ref<boolean, boolean>;
2
- declare const sliderRef: import("vue").Ref<HTMLElement | null, HTMLElement | null>;
3
- declare const itemStates: {
4
- [key: number]: {
5
- scale: number;
6
- translate: number;
7
- opacity: number;
8
- };
9
- };
10
- declare const isVertical: import("vue").ComputedRef<boolean>;
11
- declare const transformProperty: import("vue").ComputedRef<"translateY" | "translateX">;
12
- declare const itemIndices: import("vue").ComputedRef<number[]>;
13
- declare const spacerSize: import("vue").ComputedRef<number>;
14
- declare const __VLS_ctx: InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>;
15
- declare var __VLS_2: `item-${number}`, __VLS_3: {
1
+ declare var __VLS_1: {
2
+ size: number;
3
+ }, __VLS_4: `item-${number}`, __VLS_5: {
16
4
  index: number;
17
- }, __VLS_5: {
5
+ }, __VLS_7: {
18
6
  index: number;
19
7
  };
20
- type __VLS_Slots = __VLS_PrettifyGlobal<__VLS_OmitStringIndex<typeof __VLS_ctx.$slots> & {
21
- [K in NonNullable<typeof __VLS_2>]?: (props: typeof __VLS_3) => any;
8
+ type __VLS_Slots = {} & {
9
+ [K in NonNullable<typeof __VLS_4>]?: (props: typeof __VLS_5) => any;
22
10
  } & {
23
- item?: (props: typeof __VLS_5) => any;
24
- }>;
25
- declare const __VLS_self: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
11
+ spacer?: (props: typeof __VLS_1) => any;
12
+ } & {
13
+ item?: (props: typeof __VLS_7) => any;
14
+ };
15
+ declare const __VLS_component: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
16
+ /**
17
+ * Scrolling direction
18
+ * @default 'vertical'
19
+ * @values 'vertical', 'horizontal'
20
+ */
26
21
  direction: {
27
22
  type: StringConstructor;
28
23
  default: string;
29
24
  validator: (value: string) => boolean;
30
25
  };
26
+ /**
27
+ * Total number of items in the list
28
+ * @default 0
29
+ */
31
30
  itemCount: {
32
31
  type: NumberConstructor;
33
32
  default: number;
34
33
  };
34
+ /**
35
+ * Scaling ratio
36
+ * The final scale of the item when it slides out
37
+ * @default 0.7
38
+ */
35
39
  scaleRatio: {
36
40
  type: NumberConstructor;
37
41
  default: number;
38
42
  };
43
+ /**
44
+ * Threshold percentage for scaling to start
45
+ * Range 0-1, defines where in the viewport the scaling animation begins
46
+ * @default 0.8
47
+ */
39
48
  scaleStartPercent: {
40
49
  type: NumberConstructor;
41
50
  default: number;
42
51
  };
52
+ /**
53
+ * Translation factor
54
+ * Adjusts the displacement offset during the slide-out effect
55
+ * @default 100
56
+ */
43
57
  translateFactor: {
44
58
  type: NumberConstructor;
45
59
  default: number;
46
60
  };
61
+ /**
62
+ * Whether to enable the spacer element
63
+ * If true, adds a spacer at the start to allow the first item to scroll out of view
64
+ * @default false
65
+ */
47
66
  spacerEnabled: {
48
67
  type: BooleanConstructor;
49
68
  default: boolean;
50
69
  };
51
- }>, {
52
- spacerEnabled: typeof spacerEnabled;
53
- sliderRef: typeof sliderRef;
54
- itemStates: typeof itemStates;
55
- isVertical: typeof isVertical;
56
- transformProperty: typeof transformProperty;
57
- itemIndices: typeof itemIndices;
58
- spacerSize: typeof spacerSize;
59
- }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
60
- direction: {
61
- type: StringConstructor;
62
- default: string;
63
- validator: (value: string) => boolean;
64
- };
65
- itemCount: {
66
- type: NumberConstructor;
67
- default: number;
68
- };
69
- scaleRatio: {
70
- type: NumberConstructor;
71
- default: number;
72
- };
73
- scaleStartPercent: {
74
- type: NumberConstructor;
75
- default: number;
76
- };
77
- translateFactor: {
78
- type: NumberConstructor;
79
- default: number;
80
- };
81
- spacerEnabled: {
70
+ /**
71
+ * Whether to occlude lower items
72
+ * If true, applies a clip-path to prevent visual overlap between scaled items
73
+ * @default false
74
+ */
75
+ occludeLowerItems: {
82
76
  type: BooleanConstructor;
83
77
  default: boolean;
84
78
  };
85
- }>> & Readonly<{}>, {
86
- direction: string;
87
- itemCount: number;
88
- scaleRatio: number;
89
- scaleStartPercent: number;
90
- translateFactor: number;
91
- spacerEnabled: boolean;
92
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
93
- declare const __VLS_component: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
79
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
80
+ /**
81
+ * Scrolling direction
82
+ * @default 'vertical'
83
+ * @values 'vertical', 'horizontal'
84
+ */
94
85
  direction: {
95
86
  type: StringConstructor;
96
87
  default: string;
97
88
  validator: (value: string) => boolean;
98
89
  };
90
+ /**
91
+ * Total number of items in the list
92
+ * @default 0
93
+ */
99
94
  itemCount: {
100
95
  type: NumberConstructor;
101
96
  default: number;
102
97
  };
98
+ /**
99
+ * Scaling ratio
100
+ * The final scale of the item when it slides out
101
+ * @default 0.7
102
+ */
103
103
  scaleRatio: {
104
104
  type: NumberConstructor;
105
105
  default: number;
106
106
  };
107
+ /**
108
+ * Threshold percentage for scaling to start
109
+ * Range 0-1, defines where in the viewport the scaling animation begins
110
+ * @default 0.8
111
+ */
107
112
  scaleStartPercent: {
108
113
  type: NumberConstructor;
109
114
  default: number;
110
115
  };
116
+ /**
117
+ * Translation factor
118
+ * Adjusts the displacement offset during the slide-out effect
119
+ * @default 100
120
+ */
111
121
  translateFactor: {
112
122
  type: NumberConstructor;
113
123
  default: number;
114
124
  };
125
+ /**
126
+ * Whether to enable the spacer element
127
+ * If true, adds a spacer at the start to allow the first item to scroll out of view
128
+ * @default false
129
+ */
115
130
  spacerEnabled: {
116
131
  type: BooleanConstructor;
117
132
  default: boolean;
118
133
  };
119
- }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
120
- direction: {
121
- type: StringConstructor;
122
- default: string;
123
- validator: (value: string) => boolean;
124
- };
125
- itemCount: {
126
- type: NumberConstructor;
127
- default: number;
128
- };
129
- scaleRatio: {
130
- type: NumberConstructor;
131
- default: number;
132
- };
133
- scaleStartPercent: {
134
- type: NumberConstructor;
135
- default: number;
136
- };
137
- translateFactor: {
138
- type: NumberConstructor;
139
- default: number;
140
- };
141
- spacerEnabled: {
134
+ /**
135
+ * Whether to occlude lower items
136
+ * If true, applies a clip-path to prevent visual overlap between scaled items
137
+ * @default false
138
+ */
139
+ occludeLowerItems: {
142
140
  type: BooleanConstructor;
143
141
  default: boolean;
144
142
  };
@@ -149,6 +147,7 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
149
147
  scaleStartPercent: number;
150
148
  translateFactor: number;
151
149
  spacerEnabled: boolean;
150
+ occludeLowerItems: boolean;
152
151
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
153
152
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
154
153
  export default _default;
@@ -1 +1 @@
1
- .slider[data-v-68d7cf0e]{position:relative;width:100%;height:100%;overflow-y:auto;overflow-x:hidden;box-sizing:border-box}.slider.horizontal[data-v-68d7cf0e]{overflow-x:auto;overflow-y:hidden;white-space:nowrap}.slider-item[data-v-68d7cf0e]{position:relative}.slider-item .slider-slot[data-v-68d7cf0e]{position:relative;transition:transform .04s}.horizontal .slider-item[data-v-68d7cf0e]{display:inline-block;vertical-align:middle;transform-origin:center right}.slider-spacer[data-v-68d7cf0e]{pointer-events:none}
1
+ .slider[data-v-30dc45e5]{position:relative;width:100%;height:100%;overflow-y:auto;overflow-x:hidden;box-sizing:border-box}.slider.horizontal[data-v-30dc45e5]{display:flex;align-items:center;overflow-x:auto;overflow-y:hidden;white-space:nowrap}.slider-item[data-v-30dc45e5]{position:relative}.slider-item .slider-slot[data-v-30dc45e5]{position:relative;transition:transform .04s}.horizontal .slider-item[data-v-30dc45e5]{display:inline-block;vertical-align:middle;transform-origin:center right}.slider-spacer[data-v-30dc45e5]{width:100%;height:100%;pointer-events:none}
@@ -1,129 +1,204 @@
1
- import { defineComponent as A, toRefs as F, ref as R, reactive as H, computed as h, watch as b, onMounted as V, onUnmounted as W, createElementBlock as y, openBlock as g, normalizeClass as O, createCommentVNode as T, unref as j, normalizeStyle as z, Fragment as q, renderList as U, createElementVNode as X, renderSlot as P } from "vue";
2
- const Y = /* @__PURE__ */ A({
1
+ import { defineComponent as te, toRefs as ae, ref as $, reactive as le, computed as I, watch as W, onMounted as oe, nextTick as x, onUnmounted as se, createElementBlock as S, openBlock as P, normalizeClass as ne, createCommentVNode as re, unref as ce, normalizeStyle as L, renderSlot as b, Fragment as ie, renderList as ue, createElementVNode as ve } from "vue";
2
+ const de = /* @__PURE__ */ te({
3
3
  __name: "ScrollSlide",
4
4
  props: {
5
+ /**
6
+ * Scrolling direction
7
+ * @default 'vertical'
8
+ * @values 'vertical', 'horizontal'
9
+ */
5
10
  direction: {
6
11
  type: String,
7
12
  default: "vertical",
8
13
  // 'vertical' or 'horizontal'
9
- validator: (c) => ["vertical", "horizontal"].includes(c)
14
+ validator: (u) => ["vertical", "horizontal"].includes(u)
10
15
  },
16
+ /**
17
+ * Total number of items in the list
18
+ * @default 0
19
+ */
11
20
  itemCount: {
12
21
  type: Number,
13
22
  default: 0
14
23
  },
24
+ /**
25
+ * Scaling ratio
26
+ * The final scale of the item when it slides out
27
+ * @default 0.7
28
+ */
15
29
  scaleRatio: {
16
30
  type: Number,
17
31
  default: 0.7
18
32
  },
33
+ /**
34
+ * Threshold percentage for scaling to start
35
+ * Range 0-1, defines where in the viewport the scaling animation begins
36
+ * @default 0.8
37
+ */
19
38
  scaleStartPercent: {
20
39
  type: Number,
21
40
  default: 0.8
22
41
  },
42
+ /**
43
+ * Translation factor
44
+ * Adjusts the displacement offset during the slide-out effect
45
+ * @default 100
46
+ */
23
47
  translateFactor: {
24
48
  type: Number,
25
49
  default: 100
26
50
  },
51
+ /**
52
+ * Whether to enable the spacer element
53
+ * If true, adds a spacer at the start to allow the first item to scroll out of view
54
+ * @default false
55
+ */
27
56
  spacerEnabled: {
28
57
  type: Boolean,
29
58
  default: !1
59
+ },
60
+ /**
61
+ * Whether to occlude lower items
62
+ * If true, applies a clip-path to prevent visual overlap between scaled items
63
+ * @default false
64
+ */
65
+ occludeLowerItems: {
66
+ type: Boolean,
67
+ default: !1
30
68
  }
31
69
  },
32
- setup(c) {
33
- const n = c, {
34
- spacerEnabled: v
35
- } = F(n), t = R(null), u = R([]), r = H({}), o = h(() => n.direction === "vertical"), $ = h(() => o.value ? "translateY" : "translateX"), k = (e, a) => Math.min(Math.max(e / a, 0), 1), M = (e) => e * e * (3 - 2 * e), S = h(() => Array.from({ length: n.itemCount }, (e, a) => a)), s = () => {
36
- if (!t.value) return;
37
- const e = t.value, a = e[o.value ? "clientHeight" : "clientWidth"];
38
- u.value.forEach((l, i) => {
39
- const m = l.getBoundingClientRect(), f = o.value ? m.top : m.left, w = e.getBoundingClientRect(), L = f - (o.value ? w.top : w.left), N = Math.min(
40
- Math.max(0, (a - L) / a),
70
+ setup(u) {
71
+ const l = u, {
72
+ direction: y,
73
+ itemCount: z,
74
+ scaleRatio: w,
75
+ scaleStartPercent: q,
76
+ translateFactor: U,
77
+ spacerEnabled: k,
78
+ occludeLowerItems: j
79
+ } = ae(l), o = $(null), g = $([]), r = le({});
80
+ let v = null;
81
+ const s = I(() => l.direction === "vertical"), X = I(() => s.value ? "translateY" : "translateX"), Y = (e, t) => Math.min(Math.max(e / t, 0), 1), D = (e) => e * e * (3 - 2 * e), E = I(() => Array.from({ length: l.itemCount }, (e, t) => t)), n = () => {
82
+ G(), B();
83
+ }, G = () => {
84
+ if (!o.value) return;
85
+ const e = o.value, t = e[s.value ? "clientHeight" : "clientWidth"], a = e[s.value ? "scrollTop" : "scrollLeft"];
86
+ let c = -1 / 0, f = 0;
87
+ g.value.forEach((i, m) => {
88
+ const N = i.getBoundingClientRect(), J = s.value ? N.top : N.left, F = e.getBoundingClientRect(), K = J - (s.value ? F.top : F.left), Q = Math.min(
89
+ Math.max(0, (t - K) / t),
41
90
  1
42
- ), B = k(1 - N - n.scaleStartPercent, 1 - n.scaleStartPercent), _ = M(B), I = 1 + (n.scaleRatio - 1) * _, x = _ * n.translateFactor;
43
- let p;
44
- const E = Math.min(Math.max(_ || 0, 0), 1);
45
- E > 0.6 ? p = 0 : E < 0.4 ? p = 1 : p = (0.6 - E) / 0.2, r[i] = {
46
- scale: I,
47
- translate: x,
48
- opacity: p
91
+ ), Z = Y(1 - Q - l.scaleStartPercent, 1 - l.scaleStartPercent), C = D(Z), p = 1 + (l.scaleRatio - 1) * C, T = C * l.translateFactor;
92
+ let h;
93
+ const R = Math.min(Math.max(C || 0, 0), 1);
94
+ R > 0.6 ? h = 0 : R < 0.4 ? h = 1 : h = (0.6 - R) / 0.2;
95
+ let _;
96
+ const A = s.value ? i.offsetHeight : i.offsetWidth, H = (s.value ? i.offsetTop : i.offsetLeft) - a + A * (0.5 - T / 100 - p / 2), ee = H + A * p;
97
+ if (l.occludeLowerItems && m > 0 && f > 0.05) {
98
+ const O = c - H;
99
+ if (O > 0.5 && p > 0.01) {
100
+ const V = O / p;
101
+ s.value ? _ = `inset(${V}px 0 0 0)` : _ = `inset(0 0 0 ${V}px)`;
102
+ }
103
+ }
104
+ c = ee, f = h, r[m] = {
105
+ scale: p,
106
+ translate: T,
107
+ opacity: h,
108
+ clipPath: _
49
109
  };
50
110
  });
51
- }, C = () => {
52
- t.value && (u.value = Array.from(t.value.querySelectorAll(".slider-item")), S.value.forEach((e) => {
111
+ }, M = () => {
112
+ o.value && (g.value = Array.from(o.value.querySelectorAll(".slider-item")), E.value.forEach((e) => {
53
113
  r[e] || (r[e] = {
54
114
  scale: 1,
55
115
  translate: 0,
56
116
  opacity: 1
57
117
  });
58
118
  }), Object.keys(r).forEach((e) => {
59
- const a = Number(e);
60
- a >= n.itemCount && delete r[a];
61
- }), s());
119
+ const t = Number(e);
120
+ t >= l.itemCount && delete r[t];
121
+ }), n());
62
122
  };
63
- b(() => n.itemCount, (e, a) => {
123
+ W(() => l.itemCount, (e, t) => {
64
124
  setTimeout(() => {
65
- C();
125
+ M();
66
126
  }, 0);
67
127
  }, { immediate: !1 });
68
- const d = h(() => {
69
- if (!t.value) return 0;
70
- const e = t.value[o.value ? "clientHeight" : "clientWidth"];
71
- let a = 0;
72
- if (u.value.length > 0) {
73
- const l = u.value[0];
74
- if (l) {
75
- const i = l.getBoundingClientRect();
76
- a = o.value ? i.height : i.width;
128
+ const d = $(0), B = () => {
129
+ if (!o.value) return 0;
130
+ const e = o.value[s.value ? "clientHeight" : "clientWidth"];
131
+ let t = 0;
132
+ if (g.value.length > 0) {
133
+ const a = g.value[0];
134
+ if (a) {
135
+ const c = a.getBoundingClientRect();
136
+ t = s.value ? c.height : c.width;
77
137
  }
78
138
  }
79
- return Math.max(0, e - a);
80
- });
81
- return V(() => {
82
- t.value && (t.value.addEventListener("scroll", s), window.addEventListener("resize", s), t.value.addEventListener("touchmove", s, { passive: !0 }), C());
83
- }), W(() => {
84
- t.value && (t.value.removeEventListener("scroll", s), t.value.removeEventListener("touchmove", s)), window.removeEventListener("resize", s);
85
- }), b(v, () => {
86
- s();
87
- }), (e, a) => (g(), y("div", {
88
- class: O(["slider", { horizontal: !o.value }]),
139
+ d.value = Math.max(0, e - t);
140
+ };
141
+ return B(), oe(() => {
142
+ if (!o.value) return;
143
+ const e = o.value;
144
+ v = new ResizeObserver(() => n()), v.observe(e), e.addEventListener("scroll", n), window.addEventListener("resize", n), e.addEventListener("touchmove", n, { passive: !0 }), M(), x(() => requestAnimationFrame(n));
145
+ }), se(() => {
146
+ v == null || v.disconnect(), v = null, o.value && (o.value.removeEventListener("scroll", n), o.value.removeEventListener("touchmove", n)), window.removeEventListener("resize", n);
147
+ }), W([
148
+ y,
149
+ z,
150
+ w,
151
+ q,
152
+ U,
153
+ k,
154
+ j
155
+ ], () => {
156
+ console.log("Props changed, reinitializing items"), x(() => {
157
+ n();
158
+ });
159
+ }), (e, t) => (P(), S("div", {
160
+ class: ne(["slider", { horizontal: !s.value }]),
89
161
  ref_key: "sliderRef",
90
- ref: t
162
+ ref: o
91
163
  }, [
92
- j(v) ? (g(), y("div", {
164
+ ce(k) ? (P(), S("div", {
93
165
  key: 0,
94
166
  class: "slider-spacer",
95
- style: z(o.value ? { height: `${d.value}px`, minHeight: `${d.value}px` } : { width: `${d.value}px`, minWidth: `${d.value}px`, display: "inline-block" })
96
- }, null, 4)) : T("", !0),
97
- (g(!0), y(q, null, U(S.value, (l) => {
98
- var i, m, f;
99
- return g(), y("div", {
100
- key: l,
167
+ style: L(s.value ? { height: `${d.value}px`, minHeight: `${d.value}px` } : { width: `${d.value}px`, minWidth: `${d.value}px`, display: "inline-block" })
168
+ }, [
169
+ b(e.$slots, "spacer", { size: d.value }, void 0, !0)
170
+ ], 4)) : re("", !0),
171
+ (P(!0), S(ie, null, ue(E.value, (a) => {
172
+ var c, f, i, m;
173
+ return P(), S("div", {
174
+ key: a,
101
175
  class: "slider-item",
102
- style: z({
103
- zIndex: S.value.length - l
176
+ style: L({
177
+ zIndex: E.value.length - a
104
178
  })
105
179
  }, [
106
- X("div", {
180
+ ve("div", {
107
181
  class: "slider-slot",
108
- style: z({
109
- transform: `${$.value}(${-((i = r[l]) == null ? void 0 : i.translate) || 0}%) scale(${((m = r[l]) == null ? void 0 : m.scale) || 1})`,
110
- opacity: (f = r[l]) == null ? void 0 : f.opacity
182
+ style: L({
183
+ transform: `${X.value}(${-((c = r[a]) == null ? void 0 : c.translate) || 0}%) scale(${((f = r[a]) == null ? void 0 : f.scale) || 1})`,
184
+ opacity: (i = r[a]) == null ? void 0 : i.opacity,
185
+ clipPath: (m = r[a]) == null ? void 0 : m.clipPath
111
186
  })
112
187
  }, [
113
- P(e.$slots, `item-${l}`, { index: l }, () => [
114
- P(e.$slots, "item", { index: l }, void 0, !0)
188
+ b(e.$slots, `item-${a}`, { index: a }, () => [
189
+ b(e.$slots, "item", { index: a }, void 0, !0)
115
190
  ], !0)
116
191
  ], 4)
117
192
  ], 4);
118
193
  }), 128))
119
194
  ], 2));
120
195
  }
121
- }), D = (c, n) => {
122
- const v = c.__vccOpts || c;
123
- for (const [t, u] of n)
124
- v[t] = u;
125
- return v;
126
- }, J = /* @__PURE__ */ D(Y, [["__scopeId", "data-v-68d7cf0e"]]);
196
+ }), fe = (u, l) => {
197
+ const y = u.__vccOpts || u;
198
+ for (const [z, w] of l)
199
+ y[z] = w;
200
+ return y;
201
+ }, ye = /* @__PURE__ */ fe(de, [["__scopeId", "data-v-30dc45e5"]]);
127
202
  export {
128
- J as ScrollSlide
203
+ ye as ScrollSlide
129
204
  };
@@ -1 +1 @@
1
- (function(s,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(s=typeof globalThis<"u"?globalThis:s||self,e(s.ScrollSlide={},s.Vue))})(this,function(s,e){"use strict";const z=((m,a)=>{const f=m.__vccOpts||m;for(const[l,u]of a)f[l]=u;return f})(e.defineComponent({__name:"ScrollSlide",props:{direction:{type:String,default:"vertical",validator:m=>["vertical","horizontal"].includes(m)},itemCount:{type:Number,default:0},scaleRatio:{type:Number,default:.7},scaleStartPercent:{type:Number,default:.8},translateFactor:{type:Number,default:100},spacerEnabled:{type:Boolean,default:!1}},setup(m){const a=m,{spacerEnabled:f}=e.toRefs(a),l=e.ref(null),u=e.ref([]),r=e.reactive({}),i=e.computed(()=>a.direction==="vertical"),b=e.computed(()=>i.value?"translateY":"translateX"),w=(t,n)=>Math.min(Math.max(t/n,0),1),B=t=>t*t*(3-2*t),S=e.computed(()=>Array.from({length:a.itemCount},(t,n)=>n)),c=()=>{if(!l.value)return;const t=l.value,n=t[i.value?"clientHeight":"clientWidth"];u.value.forEach((o,d)=>{const p=o.getBoundingClientRect(),v=i.value?p.top:p.left,k=t.getBoundingClientRect(),C=v-(i.value?k.top:k.left),P=Math.min(Math.max(0,(n-C)/n),1),R=w(1-P-a.scaleStartPercent,1-a.scaleStartPercent),g=B(R),$=1+(a.scaleRatio-1)*g,M=g*a.translateFactor;let y;const _=Math.min(Math.max(g||0,0),1);_>.6?y=0:_<.4?y=1:y=(.6-_)/.2,r[d]={scale:$,translate:M,opacity:y}})},E=()=>{l.value&&(u.value=Array.from(l.value.querySelectorAll(".slider-item")),S.value.forEach(t=>{r[t]||(r[t]={scale:1,translate:0,opacity:1})}),Object.keys(r).forEach(t=>{const n=Number(t);n>=a.itemCount&&delete r[n]}),c())};e.watch(()=>a.itemCount,(t,n)=>{setTimeout(()=>{E()},0)},{immediate:!1});const h=e.computed(()=>{if(!l.value)return 0;const t=l.value[i.value?"clientHeight":"clientWidth"];let n=0;if(u.value.length>0){const o=u.value[0];if(o){const d=o.getBoundingClientRect();n=i.value?d.height:d.width}}return Math.max(0,t-n)});return e.onMounted(()=>{l.value&&(l.value.addEventListener("scroll",c),window.addEventListener("resize",c),l.value.addEventListener("touchmove",c,{passive:!0}),E())}),e.onUnmounted(()=>{l.value&&(l.value.removeEventListener("scroll",c),l.value.removeEventListener("touchmove",c)),window.removeEventListener("resize",c)}),e.watch(f,()=>{c()}),(t,n)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["slider",{horizontal:!i.value}]),ref_key:"sliderRef",ref:l},[e.unref(f)?(e.openBlock(),e.createElementBlock("div",{key:0,class:"slider-spacer",style:e.normalizeStyle(i.value?{height:`${h.value}px`,minHeight:`${h.value}px`}:{width:`${h.value}px`,minWidth:`${h.value}px`,display:"inline-block"})},null,4)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(S.value,o=>{var d,p,v;return e.openBlock(),e.createElementBlock("div",{key:o,class:"slider-item",style:e.normalizeStyle({zIndex:S.value.length-o})},[e.createElementVNode("div",{class:"slider-slot",style:e.normalizeStyle({transform:`${b.value}(${-((d=r[o])==null?void 0:d.translate)||0}%) scale(${((p=r[o])==null?void 0:p.scale)||1})`,opacity:(v=r[o])==null?void 0:v.opacity})},[e.renderSlot(t.$slots,`item-${o}`,{index:o},()=>[e.renderSlot(t.$slots,"item",{index:o},void 0,!0)],!0)],4)],4)}),128))],2))}}),[["__scopeId","data-v-68d7cf0e"]]);s.ScrollSlide=z,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
1
+ (function(f,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(f=typeof globalThis<"u"?globalThis:f||self,e(f.ScrollSlide={},f.Vue))})(this,(function(f,e){"use strict";const F=((u,n)=>{const g=u.__vccOpts||u;for(const[z,E]of n)g[z]=E;return g})(e.defineComponent({__name:"ScrollSlide",props:{direction:{type:String,default:"vertical",validator:u=>["vertical","horizontal"].includes(u)},itemCount:{type:Number,default:0},scaleRatio:{type:Number,default:.7},scaleStartPercent:{type:Number,default:.8},translateFactor:{type:Number,default:100},spacerEnabled:{type:Boolean,default:!1},occludeLowerItems:{type:Boolean,default:!1}},setup(u){const n=u,{direction:g,itemCount:z,scaleRatio:E,scaleStartPercent:O,translateFactor:V,spacerEnabled:B,occludeLowerItems:A}=e.toRefs(n),a=e.ref(null),P=e.ref([]),c=e.reactive({});let m=null;const s=e.computed(()=>n.direction==="vertical"),H=e.computed(()=>s.value?"translateY":"translateX"),W=(t,l)=>Math.min(Math.max(t/l,0),1),j=t=>t*t*(3-2*t),_=e.computed(()=>Array.from({length:n.itemCount},(t,l)=>l)),r=()=>{q(),R()},q=()=>{if(!a.value)return;const t=a.value,l=t[s.value?"clientHeight":"clientWidth"],o=t[s.value?"scrollTop":"scrollLeft"];let i=-1/0,h=0;P.value.forEach((d,v)=>{const $=d.getBoundingClientRect(),U=s.value?$.top:$.left,I=t.getBoundingClientRect(),X=U-(s.value?I.top:I.left),Y=Math.min(Math.max(0,(l-X)/l),1),D=W(1-Y-n.scaleStartPercent,1-n.scaleStartPercent),k=j(D),y=1+(n.scaleRatio-1)*k,L=k*n.translateFactor;let S;const w=Math.min(Math.max(k||0,0),1);w>.6?S=0:w<.4?S=1:S=(.6-w)/.2;let b;const M=s.value?d.offsetHeight:d.offsetWidth,T=(s.value?d.offsetTop:d.offsetLeft)-o+M*(.5-L/100-y/2),G=T+M*y;if(n.occludeLowerItems&&v>0&&h>.05){const N=i-T;if(N>.5&&y>.01){const x=N/y;s.value?b=`inset(${x}px 0 0 0)`:b=`inset(0 0 0 ${x}px)`}}i=G,h=S,c[v]={scale:y,translate:L,opacity:S,clipPath:b}})},C=()=>{a.value&&(P.value=Array.from(a.value.querySelectorAll(".slider-item")),_.value.forEach(t=>{c[t]||(c[t]={scale:1,translate:0,opacity:1})}),Object.keys(c).forEach(t=>{const l=Number(t);l>=n.itemCount&&delete c[l]}),r())};e.watch(()=>n.itemCount,(t,l)=>{setTimeout(()=>{C()},0)},{immediate:!1});const p=e.ref(0),R=()=>{if(!a.value)return 0;const t=a.value[s.value?"clientHeight":"clientWidth"];let l=0;if(P.value.length>0){const o=P.value[0];if(o){const i=o.getBoundingClientRect();l=s.value?i.height:i.width}}p.value=Math.max(0,t-l)};return R(),e.onMounted(()=>{if(!a.value)return;const t=a.value;m=new ResizeObserver(()=>r()),m.observe(t),t.addEventListener("scroll",r),window.addEventListener("resize",r),t.addEventListener("touchmove",r,{passive:!0}),C(),e.nextTick(()=>requestAnimationFrame(r))}),e.onUnmounted(()=>{m==null||m.disconnect(),m=null,a.value&&(a.value.removeEventListener("scroll",r),a.value.removeEventListener("touchmove",r)),window.removeEventListener("resize",r)}),e.watch([g,z,E,O,V,B,A],()=>{console.log("Props changed, reinitializing items"),e.nextTick(()=>{r()})}),(t,l)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["slider",{horizontal:!s.value}]),ref_key:"sliderRef",ref:a},[e.unref(B)?(e.openBlock(),e.createElementBlock("div",{key:0,class:"slider-spacer",style:e.normalizeStyle(s.value?{height:`${p.value}px`,minHeight:`${p.value}px`}:{width:`${p.value}px`,minWidth:`${p.value}px`,display:"inline-block"})},[e.renderSlot(t.$slots,"spacer",{size:p.value},void 0,!0)],4)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(_.value,o=>{var i,h,d,v;return e.openBlock(),e.createElementBlock("div",{key:o,class:"slider-item",style:e.normalizeStyle({zIndex:_.value.length-o})},[e.createElementVNode("div",{class:"slider-slot",style:e.normalizeStyle({transform:`${H.value}(${-((i=c[o])==null?void 0:i.translate)||0}%) scale(${((h=c[o])==null?void 0:h.scale)||1})`,opacity:(d=c[o])==null?void 0:d.opacity,clipPath:(v=c[o])==null?void 0:v.clipPath})},[e.renderSlot(t.$slots,`item-${o}`,{index:o},()=>[e.renderSlot(t.$slots,"item",{index:o},void 0,!0)],!0)],4)],4)}),128))],2))}}),[["__scopeId","data-v-30dc45e5"]]);f.ScrollSlide=F,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,34 +1,42 @@
1
- {
2
- "name": "scroll-slides",
3
- "version": "0.1.2",
4
- "type": "module",
5
- "types": "./dist/index.d.ts",
6
- "files": [
7
- "dist"
8
- ],
9
- "main": "./dist/scroll-slides.umd.cjs",
10
- "module": "./dist/scroll-slides.js",
11
- "author": {
12
- "name": "agoudbg",
13
- "email": "agoudbg@gmail.com",
14
- "url": "https://github.com/agoudbg"
15
- },
16
- "homepage": "https://github.com/agoudbg/scroll-slides",
17
- "scripts": {
18
- "dev": "vite",
19
- "build": "vite build && vue-tsc --emitDeclarationOnly --project tsconfig.app.json",
20
- "types": "vue-tsc --declaration --emitDeclarationOnly --project tsconfig.app.json",
21
- "preview": "vite preview"
22
- },
23
- "dependencies": {
24
- "vue": "^3.5.13"
25
- },
26
- "devDependencies": {
27
- "@types/node": "^22.14.0",
28
- "@vitejs/plugin-vue": "^5.2.1",
29
- "@vue/tsconfig": "^0.7.0",
30
- "typescript": "~5.7.2",
31
- "vite": "^6.2.0",
32
- "vue-tsc": "^2.2.4"
33
- }
1
+ {
2
+ "name": "scroll-slides",
3
+ "version": "0.3.0",
4
+ "type": "module",
5
+ "types": "./dist/index.d.ts",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "main": "./dist/scroll-slides.umd.cjs",
10
+ "module": "./dist/scroll-slides.js",
11
+ "author": {
12
+ "name": "agoudbg",
13
+ "email": "agoudbg@gmail.com",
14
+ "url": "https://github.com/agoudbg"
15
+ },
16
+ "license": "MIT",
17
+ "homepage": "https://github.com/agoudbg/scroll-slides",
18
+ "scripts": {
19
+ "dev": "vite",
20
+ "build": "vite build && vue-tsc --emitDeclarationOnly --project tsconfig.app.json",
21
+ "build:demo": "vite build --config vite.demo.config.ts",
22
+ "types": "vue-tsc --declaration --emitDeclarationOnly --project tsconfig.app.json",
23
+ "preview": "vite preview"
24
+ },
25
+ "dependencies": {
26
+ "scroll-slides": "link:..\\..\\..\\AppData\\Local\\pnpm\\global\\5\\node_modules\\scroll-slides",
27
+ "vue": "^3.5.26"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^22.19.7",
31
+ "@vitejs/plugin-vue": "^5.2.4",
32
+ "@vue/tsconfig": "^0.7.0",
33
+ "typescript": "~5.7.3",
34
+ "vite": "^6.4.1",
35
+ "vue-tsc": "^2.2.12"
36
+ },
37
+ "pnpm": {
38
+ "overrides": {
39
+ "scroll-slides": "link:../../../AppData/Local/pnpm/global/5/node_modules/scroll-slides"
40
+ }
41
+ }
34
42
  }
package/dist/vite.svg DELETED
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>