@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.
- package/package.json +5 -11
- package/20240328-video4-setting.png +0 -0
- package/CHANGELOG.md +0 -41
- package/index.html +0 -25
- package/prepros.config +0 -883
- package/src/fesd/anchor4/anchor4.js +0 -179
- package/src/fesd/aost4/_aost4.sass +0 -64
- package/src/fesd/aost4/aost4.js +0 -138
- package/src/fesd/article4/article4.js +0 -280
- package/src/fesd/article4/article4.md +0 -1
- package/src/fesd/category-slider/_category-slider.sass +0 -33
- package/src/fesd/category-slider/category-slider.js +0 -332
- package/src/fesd/collapse4/collapse4.js +0 -159
- package/src/fesd/detect4/detect4.js +0 -70
- package/src/fesd/dropdown4/_dropdown4.sass +0 -185
- package/src/fesd/dropdown4/cityData.js +0 -830
- package/src/fesd/dropdown4/dropdown4.js +0 -647
- package/src/fesd/image-preview/_image-preview.sass +0 -26
- package/src/fesd/image-preview/image-preview.js +0 -209
- package/src/fesd/image-validate/_image-validate.sass +0 -21
- package/src/fesd/image-validate/image-validate.js +0 -84
- package/src/fesd/marquee4/_marquee4.sass +0 -45
- package/src/fesd/marquee4/marquee4.js +0 -371
- package/src/fesd/modal4/_modal4.sass +0 -134
- package/src/fesd/modal4/modal4.js +0 -236
- package/src/fesd/modal4/modernModal.js +0 -182
- package/src/fesd/multipurpose4/_multipurpose4.sass +0 -282
- package/src/fesd/multipurpose4/multipurpose4.js +0 -562
- package/src/fesd/ripple4/_ripple4.sass +0 -44
- package/src/fesd/ripple4/ripple4.js +0 -138
- package/src/fesd/share4/share4.js +0 -191
- package/src/fesd/shared/shared.js +0 -59
- package/src/fesd/shared/utils.js +0 -98
- package/src/fesd/tab4/_tab4.sass +0 -25
- package/src/fesd/tab4/tab4.js +0 -473
- package/src/fesd/video4/README.md +0 -3
- package/src/fesd/video4/_video4.sass +0 -117
- package/src/fesd/video4/video4.js +0 -237
- package/src/fesd/video4/videoPlayer.js +0 -195
- package/src/fesd.js +0 -53
- package/src/fesd.sass +0 -29
- package/src/fesdDB.js +0 -282
- 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)
|
package/src/fesd/aost4/aost4.js
DELETED
@@ -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
|