@xwadex/fesd 0.0.2 → 0.0.5

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 (43) hide show
  1. package/package.json +5 -11
  2. package/20240328-video4-setting.png +0 -0
  3. package/CHANGELOG.md +0 -41
  4. package/index.html +0 -25
  5. package/prepros.config +0 -883
  6. package/src/fesd/anchor4/anchor4.js +0 -179
  7. package/src/fesd/aost4/_aost4.sass +0 -64
  8. package/src/fesd/aost4/aost4.js +0 -138
  9. package/src/fesd/article4/article4.js +0 -280
  10. package/src/fesd/article4/article4.md +0 -1
  11. package/src/fesd/category-slider/_category-slider.sass +0 -33
  12. package/src/fesd/category-slider/category-slider.js +0 -332
  13. package/src/fesd/collapse4/collapse4.js +0 -159
  14. package/src/fesd/detect4/detect4.js +0 -70
  15. package/src/fesd/dropdown4/_dropdown4.sass +0 -185
  16. package/src/fesd/dropdown4/cityData.js +0 -830
  17. package/src/fesd/dropdown4/dropdown4.js +0 -647
  18. package/src/fesd/image-preview/_image-preview.sass +0 -26
  19. package/src/fesd/image-preview/image-preview.js +0 -209
  20. package/src/fesd/image-validate/_image-validate.sass +0 -21
  21. package/src/fesd/image-validate/image-validate.js +0 -84
  22. package/src/fesd/marquee4/_marquee4.sass +0 -45
  23. package/src/fesd/marquee4/marquee4.js +0 -371
  24. package/src/fesd/modal4/_modal4.sass +0 -134
  25. package/src/fesd/modal4/modal4.js +0 -236
  26. package/src/fesd/modal4/modernModal.js +0 -182
  27. package/src/fesd/multipurpose4/_multipurpose4.sass +0 -282
  28. package/src/fesd/multipurpose4/multipurpose4.js +0 -562
  29. package/src/fesd/ripple4/_ripple4.sass +0 -44
  30. package/src/fesd/ripple4/ripple4.js +0 -138
  31. package/src/fesd/share4/share4.js +0 -191
  32. package/src/fesd/shared/shared.js +0 -59
  33. package/src/fesd/shared/utils.js +0 -98
  34. package/src/fesd/tab4/_tab4.sass +0 -25
  35. package/src/fesd/tab4/tab4.js +0 -473
  36. package/src/fesd/video4/README.md +0 -3
  37. package/src/fesd/video4/_video4.sass +0 -117
  38. package/src/fesd/video4/video4.js +0 -237
  39. package/src/fesd/video4/videoPlayer.js +0 -195
  40. package/src/fesd.js +0 -53
  41. package/src/fesd.sass +0 -29
  42. package/src/fesdDB.js +0 -282
  43. package/vite.config.js +0 -37
@@ -1,179 +0,0 @@
1
- import SHARED from './../shared/shared';
2
- import { isString, isElementExist, isFunction, getElement, getAllElements } from './../shared/utils';
3
-
4
- const ease = {
5
- easeInOutCirc(t, b, c, d) {
6
- if ((t /= d / 2) < 1) return (-c / 2) * (Math.sqrt(1 - t * t) - 1) + b;
7
- return (c / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
8
- },
9
- easeInQuart(t, b, c, d) {
10
- return c * (t /= d) * t * t * t + b;
11
- },
12
- easeOutQuart(t, b, c, d) {
13
- return -c * ((t = t / d - 1) * t * t * t - 1) + b;
14
- },
15
- };
16
-
17
- // scroll handler
18
- const scrollTo = (options, instance) => {
19
- const { target, container, spacer, speed, gap, easing, direction } = options;
20
-
21
- const isHorizontal = direction === 'horizontal';
22
- const scrollDirection = isHorizontal ? 'scrollLeft' : 'scrollTop';
23
- const rectPosition = isHorizontal ? 'left' : 'top';
24
- const rectSpace = isHorizontal ? 'width' : 'height';
25
-
26
- const containerEle = isElementExist(container) ? getElement(container) : document.scrollingElement;
27
- const start = containerEle[scrollDirection];
28
- const targetPoint = isElementExist(target) ? getElement(target).getBoundingClientRect()[rectPosition] : 0 - start;
29
- const spacerGap = isElementExist(spacer) ? getElement(spacer).getBoundingClientRect()[rectSpace] : 0;
30
- const change = targetPoint - gap - spacerGap;
31
- const increment = 15;
32
- let currentTime = 0;
33
-
34
- if (change === 0) return;
35
-
36
- const emitEvent = eventName => {
37
- const targetEle = getElement(target);
38
- if (instance) instance.emit(eventName, targetEle);
39
- if (!instance && options.on) {
40
- if (isFunction(options.on[eventName])) options.on[eventName](targetEle);
41
- }
42
- };
43
-
44
- emitEvent('beforeScroll');
45
-
46
- const animateScroll = () => {
47
- currentTime += increment;
48
- const val = ease[easing](currentTime, start, change, speed);
49
- containerEle[scrollDirection] = val;
50
- if (currentTime < speed) requestAnimationFrame(animateScroll);
51
- if (currentTime >= speed) emitEvent('afterScroll');
52
- };
53
-
54
- requestAnimationFrame(animateScroll);
55
- };
56
-
57
- // class Anchor4
58
- class Anchor4 {
59
- constructor(el, options = {}) {
60
- this.__storage__ = {
61
- el,
62
- options,
63
- };
64
-
65
- this.#create();
66
- }
67
-
68
- #create() {
69
- const { el, options } = this.__storage__;
70
- if (!isString(el) || !isElementExist(el)) return;
71
-
72
- const { SETTINGS, EVENTS } = fesdDB.anchor4;
73
-
74
- this.elements = getAllElements(el);
75
- this.options = Object.assign({}, SETTINGS, options);
76
- this.__events__ = Object.assign({}, EVENTS);
77
-
78
- if (this.options.on) {
79
- for (const [k, v] of Object.entries(this.options.on)) {
80
- this.__events__[k] = [v];
81
- }
82
- }
83
-
84
- this.#init();
85
- }
86
-
87
- #init() {
88
- const { elements, options } = this;
89
-
90
- elements.forEach(el => {
91
- el.anchor = {};
92
- el.anchor.instance = this;
93
- el.anchor.eventHandler = this.#trigger;
94
- el.anchor.defaultOptions = options;
95
- el.addEventListener('click', el.anchor.eventHandler);
96
- });
97
-
98
- this.emit('afterInit');
99
- }
100
-
101
- #trigger() {
102
- /** the keyword `this` in this method is pointed to the click target */
103
- const { defaultOptions, eventHandler, instance } = this.anchor;
104
-
105
- const options = {
106
- target: this.getAttribute('data-anchor-target') || defaultOptions.target,
107
- container: this.getAttribute('data-anchor-container') || defaultOptions.container,
108
- spacer: this.getAttribute('data-anchor-spacer') || defaultOptions.spacer,
109
- gap: parseInt(this.getAttribute('data-anchor-gap') || defaultOptions.gap),
110
- speed: parseInt(this.getAttribute('data-anchor-speed')) || defaultOptions.speed,
111
- delay: parseInt(this.getAttribute('data-anchor-delay')) || defaultOptions.delay,
112
- easing: this.getAttribute('data-anchor-easing') || defaultOptions.easing,
113
- direction: this.getAttribute('data-anchor-direction') || defaultOptions.direction,
114
- };
115
-
116
- // prevent multiple click
117
- this.removeEventListener('click', eventHandler);
118
- setTimeout(() => {
119
- this.addEventListener('click', eventHandler);
120
- }, options.speed);
121
-
122
- // do scroll
123
- setTimeout(() => {
124
- scrollTo(options, instance);
125
- }, options.delay);
126
- }
127
-
128
- destroy() {
129
- const { elements } = this;
130
-
131
- this.emit('beforeDestroy');
132
-
133
- elements.forEach(el => {
134
- if (!el.anchor) return;
135
-
136
- el.removeEventListener('click', el.anchor.eventHandler);
137
- delete el.anchor;
138
- });
139
-
140
- return this;
141
- }
142
-
143
- update() {
144
- this.destroy().#create();
145
-
146
- this.emit('afterUpdate');
147
-
148
- return this;
149
- }
150
-
151
- static run(options) {
152
- const { SETTINGS } = fesdDB.anchor4;
153
- const newOptions = Object.assign({}, SETTINGS, options);
154
-
155
- setTimeout(() => {
156
- scrollTo(newOptions);
157
- }, newOptions.delay);
158
- }
159
-
160
- static url(options) {
161
- const { SETTINGS } = fesdDB.anchor4;
162
-
163
- const targetStr = window.location.search || window.location.hash;
164
- const targetName = targetStr.split('?').pop();
165
- const target = document.querySelector(`[data-anchor-id="${targetName}"]`);
166
-
167
- if (!target) return;
168
-
169
- const newOptions = Object.assign({}, SETTINGS, options, { target });
170
-
171
- setTimeout(() => {
172
- scrollTo(newOptions);
173
- }, newOptions.delay);
174
- }
175
- }
176
-
177
- Object.assign(Anchor4.prototype, SHARED);
178
-
179
- export default Anchor4;
@@ -1,64 +0,0 @@
1
- // aost
2
- [data-aost]
3
- // animations
4
- &[data-aost-fade]
5
- opacity: 0
6
- &.aost-show
7
- opacity: 1
8
- transition: opacity var(--aost-trans, .8s)
9
- &[data-aost-fade-up]
10
- opacity: 0
11
- transform: translateY(50px)
12
- &.aost-show
13
- opacity: 1
14
- transform: translateY(0)
15
- transition: opacity var(--aost-trans, .8s), transform var(--aost-trans, .8s)
16
- &[data-aost-fade-down]
17
- opacity: 0
18
- transform: translateY(-50px)
19
- &.aost-show
20
- opacity: 1
21
- transform: translateY(0)
22
- transition: opacity var(--aost-trans, .8s), transform var(--aost-trans, .8s)
23
- &[data-aost-fade-right]
24
- opacity: 0
25
- transform: translateX(50px)
26
- &.aost-show
27
- opacity: 1
28
- transform: translateY(0)
29
- transition: opacity var(--aost-trans, .8s), transform var(--aost-trans, .8s)
30
- &[data-aost-fade-left]
31
- opacity: 0
32
- transform: translateX(-50px)
33
- &.aost-show
34
- opacity: 1
35
- transform: translateY(0)
36
- transition: opacity var(--aost-trans, .8s), transform var(--aost-trans, .8s)
37
- &[data-aost-clip-down]
38
- opacity: 0
39
- clip-path: polygon(0 0, 100% 0, 100% 0, 0 0)
40
- &.aost-show
41
- opacity: 1
42
- clip-path: polygon(0 0, 100% 0, 100% 115%, 0 100%)
43
- transition: opacity var(--aost-trans, .8s), clip-path var(--aost-trans, .8s)
44
- &[data-aost-clip-left]
45
- opacity: 0
46
- clip-path: polygon(0 0, 0 0, 0 100%, 0 100%)
47
- &.aost-show
48
- opacity: 1
49
- clip-path: polygon(0 0, 110% 0, 100% 100%, 0 100%)
50
- transition: opacity var(--aost-trans, .8s), clip-path var(--aost-trans, .8s)
51
- &[data-aost-clip-right]
52
- opacity: 0
53
- clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%)
54
- &.aost-show
55
- opacity: 1
56
- clip-path: polygon(-10% 0, 100% 0, 100% 100%, 0% 100%)
57
- transition: opacity var(--aost-trans, .8s), clip-path var(--aost-trans, .8s)
58
- &[data-aost-scale]
59
- opacity: 0
60
- transform: scale(.5)
61
- &.aost-show
62
- opacity: 1
63
- transform: scale(1)
64
- transition: opacity var(--aost-trans, .8s), clip-path var(--aost-trans, .8s)
@@ -1,138 +0,0 @@
1
- import SHARED from './../shared/shared';
2
- import { isString, isElementExist, getElement, getAllElements } from './../shared/utils';
3
-
4
- const interaction = (scrollElement, elements) => {
5
- const viewHeight = scrollElement === window ? scrollElement.innerHeight : scrollElement.getBoundingClientRect().height;
6
- const viewTop = scrollElement === window ? 0 : scrollElement.getBoundingClientRect().top;
7
-
8
- elements.forEach(el => {
9
- const { class: className, delay, start, end, repeat, instance } = el.aost;
10
-
11
- const { top, bottom } = el.getBoundingClientRect();
12
- const startTrigger = viewHeight * (start / 100);
13
- const endTrigger = viewHeight * (end / 100);
14
- const isEntered = top - viewTop <= startTrigger && bottom - viewTop >= endTrigger;
15
-
16
- // in view
17
- if (isEntered && el.offsetParent) {
18
- setTimeout(() => {
19
- // instance.emit('enter', el);
20
- el.classList.add(className);
21
- }, delay);
22
- }
23
- // out of view
24
- else {
25
- const shouldRemove = (el.classList.contains(className) && repeat === 'down' && top - viewTop >= startTrigger) || (repeat === 'up' && bottom - viewTop <= endTrigger) || repeat === true;
26
- setTimeout(() => {
27
- // instance.emit('leave', el);
28
- if (shouldRemove) el.classList.remove(className);
29
- }, delay);
30
- }
31
- });
32
- };
33
-
34
- const detectRepeat = (repeatType, options) => {
35
- if (repeatType === 'up' || repeatType === 'down') {
36
- return repeatType;
37
- }
38
-
39
- if (repeatType !== null) {
40
- if (repeatType === 'true') {
41
- return true;
42
- } else if (repeatType === 'false') {
43
- return false;
44
- } else {
45
- return options.repeat;
46
- }
47
- }
48
-
49
- return options.repeat;
50
- };
51
-
52
- class Aost4 {
53
- constructor(el, options = {}) {
54
- this.__storage__ = {
55
- el,
56
- options,
57
- };
58
-
59
- this.#create();
60
- }
61
-
62
- #create() {
63
- const { el, options } = this.__storage__;
64
- if (!isString(el) || !isElementExist(el)) return;
65
-
66
- const { SETTINGS, EVENTS } = fesdDB.aost4;
67
-
68
- this.elements = getAllElements(el);
69
- this.options = Object.assign({}, SETTINGS, options);
70
- this.__events__ = Object.assign({}, EVENTS);
71
-
72
- if (this.options.on) {
73
- for (const [k, v] of Object.entries(this.options.on)) {
74
- this.__events__[k] = [v];
75
- }
76
- }
77
-
78
- this.#init();
79
- }
80
-
81
- #init() {
82
- const { elements, options } = this;
83
- const { scroller } = options;
84
- const scrollElement = scroller === window || !isElementExist(scroller) ? window : getElement(scroller);
85
-
86
- this.eventHandler = () => {
87
- interaction(scrollElement, elements);
88
- };
89
-
90
- elements.forEach(el => {
91
- el.aost = {};
92
- el.aost.class = el.getAttribute('data-aost-class') || options.class;
93
- el.aost.delay = parseInt(el.getAttribute('data-aost-delay')) || options.delay;
94
- el.aost.start = parseInt(el.getAttribute('data-aost-start')) || options.start;
95
- el.aost.end = parseInt(el.getAttribute('data-aost-end')) || options.end;
96
- el.aost.repeat = detectRepeat(el.getAttribute('data-aost-repeat'), options);
97
- el.aost.instance = this;
98
- });
99
-
100
- const { eventHandler } = this;
101
- eventHandler();
102
- scrollElement.aost = {};
103
- scrollElement.aost.eventHandler = eventHandler;
104
- scrollElement.addEventListener('scroll', scrollElement.aost.eventHandler, false);
105
- }
106
-
107
- destroy(removeShow) {
108
- const { elements, options } = this;
109
- if (!elements) return this;
110
-
111
- const { scroller } = options;
112
- const scrollElement = scroller === window || !isElementExist(scroller) ? window : getElement(scroller);
113
-
114
- if (scrollElement.aost) {
115
- scrollElement.removeEventListener('scroll', scrollElement.aost.eventHandler);
116
- delete scrollElement.aost;
117
- }
118
-
119
- elements.forEach(el => {
120
- if (!el.aost) return;
121
- const { class: className } = el.aost;
122
- if (removeShow) {
123
- el.classList.remove(className);
124
- }
125
- delete el.aost;
126
- });
127
-
128
- return this;
129
- }
130
-
131
- update(removeShow) {
132
- this.destroy(removeShow).#create();
133
- }
134
- }
135
-
136
- Object.assign(Aost4.prototype, SHARED);
137
-
138
- export default Aost4;
@@ -1,280 +0,0 @@
1
- // import Swiper bundle with all modules installed
2
- import { Swiper as SwiperV8 } from 'swiper/bundle';
3
- import { isString, isNodeList, isElementExist, getAllElements, createUid } from './../shared/utils';
4
-
5
- ('use strict');
6
-
7
- // 設置 CSS 樣式
8
- const setCss = (target, style, css) => {
9
- if (!target) return;
10
-
11
- // 若是 NodeList 則需使用 foreach set css
12
- if (isNodeList(target)) target.forEach(el => (el.style[style] = css));
13
- else target.style[style] = css;
14
- };
15
-
16
- class Article4 {
17
- constructor(el, options = {}) {
18
- if (!isString(el) || !isElementExist(el)) return;
19
-
20
- this.__storage__ = {
21
- el,
22
- options,
23
- };
24
-
25
- this.#create();
26
- }
27
-
28
- #create() {
29
- const { el, options } = this.__storage__;
30
- const { SETTINGS } = fesdDB.article4;
31
-
32
- this.elements = getAllElements(el);
33
- this.options = Object.assign({}, SETTINGS, options);
34
-
35
- this.#init();
36
- }
37
-
38
- #init() {
39
- const { elements } = this;
40
-
41
- elements.forEach(parent => {
42
- parent.querySelectorAll('._article').forEach(el => {
43
- el.article = {};
44
- el.article.parent = parent;
45
- el.article.params = this.#getArticleData(el);
46
-
47
- this.#setStyle(el).#createVideo4(el).#createSwiper(el);
48
- });
49
- });
50
- }
51
-
52
- // 取得元件上的設定值
53
- #getArticleData(element) {
54
- return {
55
- // 元件本身
56
- $selector: element,
57
-
58
- // 父層元件
59
- $backgroundWrap: element.querySelector('._backgroundWrap'),
60
- $contentWrap: element.querySelector('._contentWrap'),
61
- $wordCover: element.querySelector('._wordCover'),
62
- $buttonCover: element.querySelector('._buttonCover'),
63
- $imgCover: element.querySelector('._imgCover'),
64
- $cover: element.querySelectorAll('._cover'),
65
- $swiper: element.querySelector('.swiper'),
66
- $swiperButtonCover: element.querySelector('.swiper-button-cover'),
67
-
68
- // 子層元件
69
- $h: element.querySelector('._H'),
70
- $subH: element.querySelector('._subH'),
71
- $p: element.querySelector('._P'),
72
- $button: element.querySelector('._button'),
73
- $description: element.querySelectorAll('._description'),
74
- $video: element.querySelectorAll('[video-id]'),
75
-
76
- // 父層設定
77
- typeFullColor: element.getAttribute('typeFull-color'),
78
- typeFullBoxColor: element.getAttribute('typeFull-boxcolor'),
79
-
80
- // 子層設定
81
- hColor: element.getAttribute('h-color'),
82
- subHColor: element.getAttribute('subh-color'),
83
- pColor: element.getAttribute('p-color'),
84
- buttonColor: element.getAttribute('button-color'),
85
- buttonColorHover: element.getAttribute('button-color-hover'),
86
- buttonTextColor: element.getAttribute('button-textcolor'),
87
- descriptionColor: element.getAttribute('description-color'),
88
- };
89
- }
90
-
91
- // 設置設定值的 CSS 樣式
92
- #setStyle(element) {
93
- const { params } = element.article;
94
-
95
- // article ._H
96
- setCss(params.$h, 'color', params.hColor);
97
-
98
- // article ._subH
99
- setCss(params.$subH, 'color', params.subHColor);
100
-
101
- // article ._P
102
- setCss(params.$p, 'color', params.pColor);
103
-
104
- // imgCover ._description
105
- setCss(params.$description, 'color', params.descriptionColor);
106
-
107
- // button background-color && text color
108
- setCss(params.$button, 'backgroundColor', params.buttonColor);
109
- setCss(params.$button, 'color', params.buttonTextColor);
110
-
111
- // button hover color
112
- if (params.buttonColorHover) {
113
- params.$button.appendChild(document.createElement('span'));
114
- setCss(params.$button.querySelector('span'), 'backgroundColor', params.buttonColorHover);
115
- }
116
-
117
- // typeFull background-color
118
- setCss(params.$backgroundWrap, 'backgroundColor', params.typeFullColor);
119
-
120
- // typeFull box background-color
121
- setCss(params.$contentWrap, 'backgroundColor', params.typeFullBoxColor);
122
-
123
- return this;
124
- }
125
-
126
- #createVideo4(element) {
127
- const { params } = element.article;
128
-
129
- if (params.$video.length) {
130
- const video = new Video4(params.$video);
131
- }
132
-
133
- return this;
134
- }
135
-
136
- #createSwiper(element) {
137
- const { basic_rwd } = this.options;
138
-
139
- const { params } = element.article;
140
-
141
- // 判斷是否擁有 swiper4 結構
142
- if (!params.$swiper) return;
143
-
144
- // set id
145
- const $id = createUid();
146
-
147
- const $this = this;
148
-
149
- // set swiper
150
- let $swiperSet = {
151
- on: {
152
- init(swiper) {
153
- const container = swiper.$el[0];
154
- // video4 重複綁定修正
155
- if (params.$video.length) {
156
- // 應該抓 DB 設定的 classname
157
- const allVideo4 = container.querySelectorAll('[video4-active]');
158
- [...allVideo4].forEach(element => {
159
- element.querySelector(fesdDB.video4.SETTINGS.videoButton)?.remove();
160
- element.querySelector('.overlay')?.remove();
161
- element.removeAttribute('video4-active');
162
- });
163
- $this.update();
164
- }
165
- },
166
- observerUpdate(swiper) {
167
- if (swiper.params.autoplay.enabled) {
168
- swiper.autoplay.start();
169
- swiper.update();
170
- }
171
- },
172
- },
173
- observer: true,
174
- breakpoints: {},
175
- };
176
-
177
- params.$selector.setAttribute('img-swiper', 'on');
178
- params.$selector.classList.add(`swiper-${$id}`);
179
-
180
- // swiper navigation (預設為 off)
181
- if (params.$selector.getAttribute('swiper-arrow') !== 'off' && params.$selector.getAttribute('swiper-arrow')) {
182
- const next = document.createElement('div');
183
- next.className = `swiper-button-next swiper-${$id}`;
184
- params.$swiperButtonCover.appendChild(next);
185
-
186
- const prev = document.createElement('div');
187
- prev.className = `swiper-button-prev swiper-${$id}`;
188
- params.$swiperButtonCover.appendChild(prev);
189
-
190
- $swiperSet.navigation = {
191
- nextEl: `.swiper-button-next.swiper-${$id}`,
192
- prevEl: `.swiper-button-prev.swiper-${$id}`,
193
- };
194
- }
195
-
196
- // swiper pagination (預設為 on)
197
- if (params.$selector.getAttribute('swiper-nav') !== 'off' || !params.$selector.getAttribute('swiper-nav')) {
198
- const pagination = document.createElement('div');
199
- pagination.className = `swiper-pagination swiper-${$id}`;
200
- params.$swiper.appendChild(pagination);
201
-
202
- $swiperSet.pagination = {
203
- el: `.swiper-pagination.swiper-${$id}`,
204
- clickable: true,
205
- };
206
- }
207
-
208
- // slidesPerView
209
- if (Number.parseInt(params.$selector.getAttribute('swiper-num'))) {
210
- $swiperSet.breakpoints[basic_rwd] = {
211
- slidesPerView: params.$selector.getAttribute('swiper-num') ? (Number.parseInt(params.$selector.getAttribute('swiper-num')) > 5 ? 5 : Number.parseInt(params.$selector.getAttribute('swiper-num'))) : 1,
212
- };
213
- }
214
-
215
- // autoplay (預設為 on)
216
- if (params.$selector.getAttribute('swiper-autoplay') !== 'off' || !params.$selector.getAttribute('swiper-autoplay')) {
217
- $swiperSet.autoplay = {
218
- delay: 3000,
219
- disableOnInteraction: false,
220
- };
221
- }
222
-
223
- // loop (預設為 on)
224
- if (params.$selector.getAttribute('swiper-loop') !== 'off' || !params.$selector.getAttribute('swiper-loop')) {
225
- $swiperSet.loop = true;
226
- }
227
-
228
- // speed
229
- if (params.$selector.getAttribute('swiper-speed')) {
230
- $swiperSet.speed = parseInt(params.$selector.getAttribute('swiper-speed'));
231
- }
232
-
233
- // parallax (預設為 off)
234
- if (params.$selector.getAttribute('swiper-parallax') !== 'off' && !params.$selector.getAttribute('swiper-loop')) {
235
- $swiperSet.parallax = true;
236
- }
237
-
238
- // pagination dynamicBullets (預設為 off)
239
- if (params.$selector.getAttribute('swiper-pagination-dynamic') === 'on') {
240
- $swiperSet.pagination.dynamicBullets = true;
241
- }
242
-
243
- // 若 swiper 只有一筆輪播則隱藏 navigation 及 pagination
244
- let gate = () => (window.innerWidth > this.basic_rwd ? Number(params.$selector.getAttribute('swiper-num')) || 1 : 1);
245
-
246
- if (params.$swiper.querySelectorAll('.swiper-slide').length <= gate()) {
247
- $swiperSet.navigation = false;
248
- $swiperSet.pagination = false;
249
- $swiperSet.autoplay = false;
250
- $swiperSet.loop = false;
251
-
252
- params.$selector.querySelector('.swiper-button-cover').style.display = 'none';
253
- params.$selector.querySelector('.swiper-pagination').style.display = 'none';
254
-
255
- params.$swiper.classList.add('swiper-no-swiping');
256
- }
257
-
258
- const $swiper = new SwiperV8(params.$swiper, $swiperSet);
259
-
260
- element.article.swiperList = [];
261
- element.article.swiperList.push($swiper);
262
-
263
- return this;
264
- }
265
- update() {
266
- const { elements } = this;
267
-
268
- elements.forEach(parent => {
269
- parent.querySelectorAll('._article').forEach(el => {
270
- el.article = {};
271
- el.article.parent = parent;
272
- el.article.params = this.#getArticleData(el);
273
-
274
- this.#createVideo4(el);
275
- });
276
- });
277
- }
278
- }
279
-
280
- export default Article4;
@@ -1 +0,0 @@
1
- 段落編輯器的 sass 檔案已移動至 WDD_Template
@@ -1,33 +0,0 @@
1
- .category-slider
2
- position: relative
3
- display: inline-block
4
- max-width: 100%
5
- overflow: hidden
6
- &.slidable
7
- mask-image: linear-gradient(270deg, rgba(#fff, 0), #fff 20%, #fff 80%,rgba(#fff, 0))
8
- .wrapper
9
- cursor: grab
10
- &.dragging
11
- cursor: grabbing
12
- &.moving
13
- .category
14
- pointer-events: none
15
- &.is-start
16
- mask-image: linear-gradient(270deg, rgba(#fff, 0), #fff 20%, #fff)
17
- &.is-end
18
- mask-image: linear-gradient(90deg, rgba(#fff, 0), #fff 20%, #fff)
19
- .wrapper
20
- position: relative
21
- display: flex
22
- flex-wrap: nowrap
23
- justify-content: flex-start
24
- width: 100%
25
- height: 100%
26
- transform: translate3d(0px, 0, 0)
27
- transition-property: transform
28
- user-select: none
29
- .item
30
- flex-shrink: 0
31
- &.active
32
- a
33
- color: red