@xwadex/fesd 0.0.1

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.
Files changed (47) hide show
  1. package/20240328-video4-setting.png +0 -0
  2. package/CHANGELOG.md +41 -0
  3. package/README.md +25 -0
  4. package/dist/assets/fesd-bundle.css +9 -0
  5. package/dist/assets/fesd-bundle.js +9800 -0
  6. package/dist/assets/fesd-bundle.js.map +1 -0
  7. package/index.html +25 -0
  8. package/package.json +23 -0
  9. package/prepros.config +883 -0
  10. package/src/fesd/anchor4/anchor4.js +179 -0
  11. package/src/fesd/aost4/_aost4.sass +64 -0
  12. package/src/fesd/aost4/aost4.js +138 -0
  13. package/src/fesd/article4/article4.js +280 -0
  14. package/src/fesd/article4/article4.md +1 -0
  15. package/src/fesd/category-slider/_category-slider.sass +33 -0
  16. package/src/fesd/category-slider/category-slider.js +332 -0
  17. package/src/fesd/collapse4/collapse4.js +159 -0
  18. package/src/fesd/detect4/detect4.js +70 -0
  19. package/src/fesd/dropdown4/_dropdown4.sass +185 -0
  20. package/src/fesd/dropdown4/cityData.js +830 -0
  21. package/src/fesd/dropdown4/dropdown4.js +647 -0
  22. package/src/fesd/image-preview/_image-preview.sass +26 -0
  23. package/src/fesd/image-preview/image-preview.js +209 -0
  24. package/src/fesd/image-validate/_image-validate.sass +21 -0
  25. package/src/fesd/image-validate/image-validate.js +84 -0
  26. package/src/fesd/marquee4/_marquee4.sass +45 -0
  27. package/src/fesd/marquee4/marquee4.js +371 -0
  28. package/src/fesd/modal4/_modal4.sass +134 -0
  29. package/src/fesd/modal4/modal4.js +236 -0
  30. package/src/fesd/modal4/modernModal.js +182 -0
  31. package/src/fesd/multipurpose4/_multipurpose4.sass +282 -0
  32. package/src/fesd/multipurpose4/multipurpose4.js +562 -0
  33. package/src/fesd/ripple4/_ripple4.sass +44 -0
  34. package/src/fesd/ripple4/ripple4.js +138 -0
  35. package/src/fesd/share4/share4.js +191 -0
  36. package/src/fesd/shared/shared.js +59 -0
  37. package/src/fesd/shared/utils.js +98 -0
  38. package/src/fesd/tab4/_tab4.sass +25 -0
  39. package/src/fesd/tab4/tab4.js +473 -0
  40. package/src/fesd/video4/README.md +3 -0
  41. package/src/fesd/video4/_video4.sass +117 -0
  42. package/src/fesd/video4/video4.js +237 -0
  43. package/src/fesd/video4/videoPlayer.js +195 -0
  44. package/src/fesd.js +53 -0
  45. package/src/fesd.sass +29 -0
  46. package/src/fesdDB.js +282 -0
  47. package/vite.config.js +37 -0
@@ -0,0 +1,371 @@
1
+ 'use strict';
2
+
3
+ // 獲取標籤上斷點設定
4
+ function getBreakpoints(m4) {
5
+ const breakpoints = {};
6
+ [...m4.attributes].forEach(attr => {
7
+ if (attr.name.includes('duration-')) {
8
+ const key = attr.name.replace('duration-', '');
9
+ const value = attr.nodeValue;
10
+ breakpoints[key] = Number(value);
11
+ }
12
+ });
13
+ return Object.keys(breakpoints).length === 0 ? null : breakpoints;
14
+ }
15
+
16
+ // 透過標籤上設定的斷點判斷持續時間
17
+ function getDuration(m4) {
18
+ if (getBreakpoints(m4)) {
19
+ let breakpoint;
20
+ const points = Object.keys(getBreakpoints(m4)).map(point => {
21
+ return {
22
+ value: point,
23
+ point,
24
+ };
25
+ });
26
+ points.sort((a, b) => parseInt(b.value, 10) - parseInt(a.value, 10));
27
+ for (let i = 0; i < points.length; i += 1) {
28
+ const { point, value } = points[i];
29
+ if (window.matchMedia(`(max-width: ${value}px)`).matches) {
30
+ breakpoint = point;
31
+ }
32
+ }
33
+ return breakpoint ? Number(getBreakpoints(m4)[breakpoint]) : m4.s.options.duration;
34
+ } else {
35
+ return m4.s.options.duration;
36
+ }
37
+ }
38
+
39
+ // 產生動畫結構
40
+ function createAnimateWrap(m4) {
41
+ const { behavior, continual, gap } = m4.s.options;
42
+ const childDOM = m4.childNodes;
43
+ const container = document.createElement('div');
44
+ const animateItem = document.createElement('div');
45
+ container.className = 'animate-container';
46
+ animateItem.className = 'animate-item';
47
+ [...childDOM].forEach(element => {
48
+ animateItem.append(element);
49
+ });
50
+ function cloneElement() {
51
+ const cloneAnimateWrap = animateItem.cloneNode(true);
52
+ cloneAnimateWrap.classList.add('clone');
53
+ m4.s.cloneAnimation = null;
54
+ m4.s.cloneAnimateEl = cloneAnimateWrap;
55
+ return cloneAnimateWrap;
56
+ }
57
+ m4.s.animation = null;
58
+ m4.s.animateEl = animateItem;
59
+ m4.textContent = '';
60
+ container.append(animateItem);
61
+ m4.append(container);
62
+ if (animateItem.clientWidth * 2 + gap >= m4.clientWidth) {
63
+ if (behavior === 'normal' && continual) {
64
+ container.append(cloneElement());
65
+ }
66
+ } else {
67
+ m4.s.options.continual = false;
68
+ }
69
+ }
70
+
71
+ // 設定動畫影格
72
+ function keyframes(m4) {
73
+ const { behavior, direction, continual } = m4.s.options;
74
+ let framesObj = {};
75
+ // 判斷模式
76
+ switch (behavior) {
77
+ case 'normal':
78
+ // 判斷方向
79
+ // normal 模式會判斷是否開啟 continual
80
+ let animateFrom, animateTo;
81
+ switch (direction) {
82
+ case 'top':
83
+ animateFrom = continual ? 'translate3d(0,100%,0)' : `translate3d(0,${m4.clientHeight}px,0)`;
84
+ animateTo = continual ? 'translate3d(0,-100%,0)' : 'translate3d(0,-100%,0)';
85
+ framesObj.animate1 = [{ transform: animateFrom }, { transform: animateTo }];
86
+ if (continual) {
87
+ framesObj.animate2 = [{ transform: 'translate3d(0,0,0)' }, { transform: 'translate3d(0,-200%,0)' }];
88
+ }
89
+ break;
90
+ case 'right':
91
+ animateFrom = continual ? 'translate3d(0,0,0)' : 'translate3d(-100%,0,0)';
92
+ animateTo = continual ? 'translate3d(200%,0,0)' : `translate3d(${m4.clientWidth}px,0,0)`;
93
+ framesObj.animate1 = [{ transform: animateFrom }, { transform: animateTo }];
94
+ if (continual) {
95
+ framesObj.animate2 = [{ transform: 'translate3d(-100%,0,0)' }, { transform: 'translate3d(100%,0,0)' }];
96
+ }
97
+ break;
98
+ case 'bottom':
99
+ animateFrom = continual ? 'translate3d(0,-100%,0)' : 'translate3d(0,-100%,0)';
100
+ animateTo = continual ? 'translate3d(0,100%,0)' : `translate3d(0,${m4.clientHeight}px,0)`;
101
+ framesObj.animate1 = [{ transform: animateFrom }, { transform: animateTo }];
102
+ if (continual) {
103
+ framesObj.animate2 = [{ transform: 'translate3d(0,-200%,0)' }, { transform: 'translate3d(0,0,0)' }];
104
+ }
105
+ break;
106
+ case 'left':
107
+ animateFrom = continual ? 'translate3d(100%,0,0)' : `translate3d(${m4.clientWidth}px,0,0)`;
108
+ animateTo = continual ? 'translate3d(-100%,0,0)' : 'translate3d(-100%,0,0)';
109
+ framesObj.animate1 = [{ transform: animateFrom }, { transform: animateTo }];
110
+ if (continual) {
111
+ framesObj.animate2 = [{ transform: 'translate3d(0,0,0)' }, { transform: 'translate3d(-200%,0,0)' }];
112
+ }
113
+ break;
114
+ }
115
+ break;
116
+ // 來回模式
117
+ case 'alternate':
118
+ // 判斷方向
119
+ switch (direction) {
120
+ case 'top':
121
+ framesObj.animate1 = [{ transform: `translate3d(0,calc(${m4.clientHeight}px - 100%),0)` }, { transform: `translate3d(0,0,0)` }, { transform: `translate3d(0,calc(${m4.clientHeight}px - 100%),0)` }];
122
+ break;
123
+ case 'right':
124
+ framesObj.animate1 = [{ transform: `translate3d(0,0,0)` }, { transform: `translate3d(calc(-100% + ${m4.clientWidth}px),0,0)` }, { transform: `translate3d(0,0,0)` }];
125
+ break;
126
+ case 'bottom':
127
+ framesObj.animate1 = [{ transform: `translate3d(0,0,0)` }, { transform: `translate3d(0,calc(${m4.clientHeight}px - 100%),0)` }, { transform: `translate3d(0,0,0)` }];
128
+ break;
129
+ case 'left':
130
+ framesObj.animate1 = [{ transform: `translate3d(calc(-100% + ${m4.clientWidth}px),0,0)` }, { transform: `translate3d(0,0,0)` }, { transform: `translate3d(calc(-100% + ${m4.clientWidth}px),0,0)` }];
131
+ break;
132
+ }
133
+ break;
134
+ case 'endStop':
135
+ // 判斷方向
136
+ switch (direction) {
137
+ case 'top':
138
+ framesObj.animate1 = [{ transform: `translate3d(0,${m4.clientHeight}px,0)` }, { transform: `translate3d(0,0,0)` }];
139
+ break;
140
+ case 'right':
141
+ framesObj.animate1 = [{ transform: `translate3d(-100%,0,0)` }, { transform: `translate3d(0,0,0)` }];
142
+ break;
143
+ case 'bottom':
144
+ framesObj.animate1 = [{ transform: `translate3d(0,-100%,0)` }, { transform: `translate3d(0,calc(${m4.clientHeight}px - 100%),0)` }];
145
+ break;
146
+ case 'left':
147
+ framesObj.animate1 = [{ transform: `translate3d(${m4.clientWidth}px,0,0)` }, { transform: `translate3d(calc(${m4.clientWidth}px - 100%),0,0)` }];
148
+ break;
149
+ }
150
+ break;
151
+ }
152
+ return framesObj;
153
+ }
154
+
155
+ function debounce(func) {
156
+ let timer;
157
+ return function (event) {
158
+ if (timer) clearTimeout(timer);
159
+ timer = setTimeout(func, 200, event);
160
+ };
161
+ }
162
+
163
+ class Marquee4 extends HTMLElement {
164
+ constructor() {
165
+ super();
166
+ this.initialize = false;
167
+ }
168
+ static get observedAttributes() {
169
+ return [];
170
+ }
171
+ attributeChangedCallback(attr, oldVal, newVal) { }
172
+ connectedCallback() {
173
+ if (this.initialize) return;
174
+ this.initialize = true;
175
+ this.#create();
176
+ }
177
+ #create() {
178
+ const options = {
179
+ direction: this.getAttribute('direction') || fesdDB.marquee4.SETTINGS.direction, // up / down / left / right
180
+ behavior: this.getAttribute('behavior') || fesdDB.marquee4.SETTINGS.behavior, // normal / alternate / endStop
181
+ duration: Number(this.getAttribute('duration')) || fesdDB.marquee4.SETTINGS.duration, // ms
182
+ durationBreakpoints: getBreakpoints(this) || fesdDB.marquee4.SETTINGS.durationBreakpoints,
183
+ autoplay: this.getAttribute('autoplay') || fesdDB.marquee4.SETTINGS.autoplay, // normal / alternate / endStop
184
+ pauseOnMouseenter: this.getAttribute('pauseOnMouseEnter') ? (this.getAttribute('pauseOnMouseEnter') === 'true' ? true : false) : fesdDB.marquee4.SETTINGS.pauseOnMouseenter, // true / false
185
+ continual: this.getAttribute('continual') ? (this.getAttribute('continual') === 'true' ? true : false) : fesdDB.marquee4.SETTINGS.continual, // true / false
186
+ gap: Number(this.getAttribute('gap')) || fesdDB.marquee4.SETTINGS.gap,
187
+ };
188
+ this.s = {};
189
+ this.s.options = options;
190
+ this.s.nowDuration = getDuration(this);
191
+ createAnimateWrap(this);
192
+ this.#init();
193
+ }
194
+ #init() {
195
+ const { direction, continual, gap } = this.s.options;
196
+ // 方向為左/右
197
+ switch (direction) {
198
+ case 'left':
199
+ case 'right':
200
+ this.style.cssText = `--continual-gap: ${gap}px;`;
201
+ break;
202
+ case 'top':
203
+ case 'bottom':
204
+ if (continual) {
205
+ this.style.cssText = `height: ${this.s.animateEl.clientHeight}px;--continual-gap: ${gap}px;`;
206
+ } else {
207
+ this.style.cssText = `min-height: ${this.s.animateEl.clientHeight}px;--continual-gap: ${gap}px;`;
208
+ }
209
+ break;
210
+ }
211
+ this.#animation();
212
+ this.#event();
213
+ if (continual) {
214
+ this.classList.add(`continual`);
215
+ }
216
+ this.classList.add('m4-initialize');
217
+ }
218
+ #animation() {
219
+ const m4 = this;
220
+ const { direction, behavior, duration, autoplay, pauseOnMouseenter, continual } = m4.s.options;
221
+ let playDelay; //跑馬燈自動撥放開始前的延遲時間
222
+ function animateInit() {
223
+ // 判斷模式
224
+ switch (behavior) {
225
+ case 'normal':
226
+ m4.s.animateEl.style.transform = `${keyframes(m4).animate1[0].transform}`;
227
+ m4.s.animation = m4.s.animateEl.animate(keyframes(m4).animate1, {
228
+ duration: m4.s.nowDuration,
229
+ iterations: Infinity,
230
+ });
231
+ if (continual) {
232
+ m4.s.cloneAnimateEl.style.transform = `${keyframes(m4).animate2[0].transform}`;
233
+ m4.s.cloneAnimation = m4.s.cloneAnimateEl.animate(keyframes(m4).animate2, {
234
+ duration: m4.s.nowDuration,
235
+ delay: -m4.s.nowDuration / 2,
236
+ iterations: Infinity,
237
+ });
238
+ }
239
+ break;
240
+ case 'alternate':
241
+ let moveDistance; //移動的距離
242
+ let averageDuration; //平均速率
243
+ // 進場的keyframe
244
+ function enterKeyframes() {
245
+ let framesArr = [];
246
+ switch (direction) {
247
+ case 'top':
248
+ moveDistance = Math.abs(m4.s.animateEl.scrollHeight - m4.clientHeight);
249
+ averageDuration = parseInt(m4.s.nowDuration / (moveDistance * 2)) * m4.s.animateEl.scrollHeight;
250
+ framesArr = [{ transform: `translate3d(0,${m4.clientHeight}px,0)` }, { transform: `translate3d(0,calc(${m4.clientHeight}px - 100%),0)` }];
251
+ break;
252
+ case 'right':
253
+ moveDistance = Math.abs(m4.s.animateEl.scrollWidth - m4.clientWidth);
254
+ averageDuration = parseInt(m4.s.nowDuration / (moveDistance * 2)) * m4.s.animateEl.scrollWidth;
255
+ framesArr = [{ transform: `translate3d(-100%,0,0)` }, { transform: `translate3d(0,0,0)` }];
256
+ break;
257
+ case 'bottom':
258
+ moveDistance = Math.abs(m4.s.animateEl.scrollHeight - m4.clientHeight);
259
+ averageDuration = parseInt(duration / (moveDistance * 2)) * m4.s.animateEl.scrollHeight;
260
+ framesArr = [{ transform: `translate3d(0,-100%,0)` }, { transform: `translate3d(0,0,0)` }];
261
+ break;
262
+ case 'left':
263
+ moveDistance = Math.abs(m4.s.animateEl.scrollWidth - m4.clientWidth);
264
+ averageDuration = parseInt(duration / (moveDistance * 2)) * m4.s.animateEl.scrollWidth;
265
+ framesArr = [{ transform: `translate3d(${m4.clientWidth}px,0,0)` }, { transform: `translate3d(calc(-100% + ${m4.clientWidth}px),0,0)` }];
266
+ break;
267
+ }
268
+ return framesArr;
269
+ }
270
+ // 跑馬燈範圍高度大於內容高度或是方向為左/右時
271
+ if (m4.clientHeight > m4.s.animateEl.scrollHeight || direction === 'left' || direction === 'right') {
272
+ m4.s.animateEl.style.transform = `${enterKeyframes()[0].transform}`;
273
+ const enterAnimate = m4.s.animateEl.animate(enterKeyframes(), {
274
+ duration: averageDuration,
275
+ fill: 'forwards',
276
+ });
277
+ enterAnimate.finished.then(() => {
278
+ m4.s.animation = m4.s.animateEl.animate(keyframes(m4).animate1, {
279
+ duration: m4.s.nowDuration,
280
+ iterations: Infinity,
281
+ });
282
+ });
283
+ }
284
+ if (m4.s.animation) {
285
+ m4.s.animation.ready.then(() => {
286
+ m4.s.animateEl.classList.add('ready');
287
+ });
288
+ }
289
+ break;
290
+ case 'endStop':
291
+ m4.s.animateEl.style.transform = `${keyframes(m4).animate1[0].transform}`;
292
+ m4.s.animation = m4.s.animateEl.animate(keyframes(m4).animate1, {
293
+ duration: m4.s.nowDuration,
294
+ fill: 'forwards',
295
+ });
296
+ break;
297
+ }
298
+ m4.s.animateEl.classList.add('start');
299
+ if (autoplay === false) {
300
+ m4.s.animateEl.classList.remove('start');
301
+ m4.s.animation.cancel();
302
+ }
303
+ }
304
+ clearTimeout(playDelay);
305
+ playDelay = setTimeout(
306
+ () => {
307
+ animateInit();
308
+ },
309
+ autoplay ? autoplay : 0,
310
+ );
311
+
312
+ // mouseenter/leave Event
313
+ m4.addEventListener('mouseenter', function () {
314
+ if (m4.s.animation && pauseOnMouseenter && m4.s.animation.playState === 'running') {
315
+ m4.pause();
316
+ }
317
+ });
318
+ m4.addEventListener('mouseleave', function () {
319
+ if (m4.s.animation && pauseOnMouseenter && m4.s.animation.playState === 'paused') {
320
+ m4.play();
321
+ }
322
+ });
323
+ }
324
+ #event() {
325
+ const m4 = this;
326
+ function updateDuration() {
327
+ const startTime = m4.s.animation.startTime;
328
+ const cloneStartTime = m4.s.cloneAnimation ? m4.s.cloneAnimation.startTime : null;
329
+ m4.s.nowDuration = getDuration(m4);
330
+ m4.s.animation.cancel();
331
+ if (m4.s.cloneAnimation) {
332
+ m4.s.cloneAnimation.cancel();
333
+ }
334
+ m4.s.animation = m4.s.animateEl.animate(keyframes(m4).animate1, {
335
+ duration: m4.s.nowDuration,
336
+ iterations: Infinity,
337
+ });
338
+ m4.s.animation.startTime = startTime;
339
+ if (m4.s.cloneAnimation) {
340
+ m4.s.cloneAnimation = m4.s.cloneAnimateEl.animate(keyframes(m4).animate2, {
341
+ duration: m4.s.nowDuration,
342
+ delay: -m4.s.nowDuration / 2,
343
+ iterations: Infinity,
344
+ });
345
+ m4.s.cloneAnimation.startTime = cloneStartTime;
346
+ }
347
+ }
348
+ window.addEventListener('resize', debounce(updateDuration));
349
+ }
350
+ play() {
351
+ this.s.animation.play();
352
+ this.s.animateEl.classList.add('start');
353
+ if (this.s.options.continual) {
354
+ this.s.cloneAnimation.play();
355
+ this.s.cloneAnimateEl.classList.add('start');
356
+ }
357
+ }
358
+ pause() {
359
+ this.s.animation.pause();
360
+ if (this.s.options.continual) {
361
+ this.s.cloneAnimation.pause();
362
+ }
363
+ }
364
+ }
365
+
366
+ // define custom element
367
+ // if (!customElements.get('marquee-el')) {
368
+ // customElements.define('marquee-el', Marquee4);
369
+ // }
370
+
371
+ export default Marquee4;
@@ -0,0 +1,134 @@
1
+ modern-modal
2
+ position: fixed
3
+ z-index: 10
4
+ top: 0
5
+ bottom: 0
6
+ left: 0
7
+ right: 0
8
+ background-color: rgba(0, 0, 0, .6)
9
+ backdrop-filter: blur(10px)
10
+ opacity: 0
11
+ pointer-events: none
12
+ transition: .5s .3s
13
+ display: none
14
+ &.show
15
+ opacity: 1
16
+ pointer-events: auto
17
+ transition: .5s
18
+ .modal-scroller
19
+ position: relative
20
+ width: 100%
21
+ height: 100%
22
+ .modal-wrapper
23
+ display: flex
24
+ flex-direction: column
25
+ min-height: 100%
26
+ .modal-content
27
+ position: relative
28
+ width: 100%
29
+ max-width: 800px
30
+ background-color: #fff
31
+ margin: auto
32
+
33
+ // animation
34
+ modern-modal
35
+ &[data-modal-animate="fade-up"]
36
+ &.show
37
+ .modal-content
38
+ opacity: 1
39
+ transform: translate(0)
40
+ transition: .6s .2s
41
+ .modal-content
42
+ opacity: 0
43
+ transform: translateY(50px)
44
+ transition: .6s
45
+ &[data-modal-animate="fade-down"]
46
+ &.show
47
+ .modal-content
48
+ opacity: 1
49
+ transform: translate(0)
50
+ transition: .6s .2s
51
+ .modal-content
52
+ opacity: 0
53
+ transform: translateY(-50px)
54
+ transition: .6s
55
+ &[data-modal-animate="fade-right"]
56
+ &.show
57
+ .modal-content
58
+ opacity: 1
59
+ transform: translate(0)
60
+ transition: .6s .2s
61
+ .modal-content
62
+ opacity: 0
63
+ transform: translateX(-50px)
64
+ transition: .6s
65
+ &[data-modal-animate="fade-left"]
66
+ &.show
67
+ .modal-content
68
+ opacity: 1
69
+ transform: translate(0)
70
+ transition: .6s .2s
71
+ .modal-content
72
+ opacity: 0
73
+ transform: translateX(50px)
74
+ transition: .6s
75
+ &[data-modal-animate="zoom-in"]
76
+ &.show
77
+ .modal-content
78
+ opacity: 1
79
+ transform: scale(1)
80
+ transition: .6s .2s
81
+ .modal-content
82
+ opacity: 0
83
+ transform: scale(.8)
84
+ transition: .6s
85
+ &[data-modal-animate="zoom-out"]
86
+ &.show
87
+ .modal-content
88
+ opacity: 1
89
+ transform: scale(1)
90
+ transition: .6s .2s
91
+ .modal-content
92
+ opacity: 0
93
+ transform: scale(1.2)
94
+ transition: .6s
95
+ &[data-modal-animate="clip-up"]
96
+ &.show
97
+ .modal-content
98
+ opacity: 1
99
+ clip-path: polygon(0 -15%, 100% 0, 100% 100%, 0 100%)
100
+ transition: .6s .2s
101
+ .modal-content
102
+ opacity: 0
103
+ clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%)
104
+ transition: .6s
105
+ &[data-modal-animate="clip-down"]
106
+ &.show
107
+ .modal-content
108
+ opacity: 1
109
+ clip-path: polygon(0 0, 100% 0, 100% 115%, 0 100%)
110
+ transition: .6s .2s
111
+ .modal-content
112
+ opacity: 0
113
+ clip-path: polygon(0 0, 100% 0, 100% 0, 0 0)
114
+ transition: .6s
115
+ &[data-modal-animate="clip-right"]
116
+ &.show
117
+ .modal-content
118
+ opacity: 1
119
+ clip-path: polygon(0 0, 115% 0, 100% 100%, 0 100%)
120
+ transition: .6s .2s
121
+ .modal-content
122
+ opacity: 0
123
+ clip-path: polygon(0 0, 0 0, 0 100%, 0 100%)
124
+ transition: .6s
125
+ &[data-modal-animate="clip-left"]
126
+ &.show
127
+ .modal-content
128
+ opacity: 1
129
+ clip-path: polygon(-15% 0, 100% 0, 100% 100%, 0 100%)
130
+ transition: .6s .2s
131
+ .modal-content
132
+ opacity: 0
133
+ clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%)
134
+ transition: .6s