@materializecss/materialize 2.0.3-alpha → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/css/materialize.css +345 -236
- package/dist/css/materialize.min.css +2 -2
- package/dist/js/materialize.js +518 -1979
- package/dist/js/materialize.min.js +2 -2
- package/dist/js/materialize.min.js.map +1 -1
- package/dist/src/buttons.d.ts.map +1 -1
- package/dist/src/cards.d.ts.map +1 -1
- package/dist/src/collapsible.d.ts +1 -0
- package/dist/src/collapsible.d.ts.map +1 -1
- package/dist/src/dropdown.d.ts.map +1 -1
- package/dist/src/global.d.ts.map +1 -1
- package/dist/src/materialbox.d.ts +14 -10
- package/dist/src/materialbox.d.ts.map +1 -1
- package/dist/src/modal.d.ts.map +1 -1
- package/dist/src/range.d.ts.map +1 -1
- package/dist/src/scrollspy.d.ts.map +1 -1
- package/dist/src/sidenav.d.ts +25 -25
- package/dist/src/sidenav.d.ts.map +1 -1
- package/dist/src/slider.d.ts +12 -12
- package/dist/src/slider.d.ts.map +1 -1
- package/dist/src/tabs.d.ts +1 -1
- package/dist/src/tabs.d.ts.map +1 -1
- package/dist/src/toasts.d.ts +7 -2
- package/dist/src/toasts.d.ts.map +1 -1
- package/dist/src/tooltip.d.ts +8 -2
- package/dist/src/tooltip.d.ts.map +1 -1
- package/package.json +14 -13
- package/sass/components/_buttons.scss +158 -73
- package/sass/components/_chips.scss +75 -28
- package/sass/components/_collapsible.scss +14 -2
- package/sass/components/_global.scss +6 -94
- package/sass/components/_materialbox.scss +2 -2
- package/sass/components/_modal.scss +0 -1
- package/sass/components/_preloader.scss +85 -0
- package/sass/components/_tooltip.scss +18 -8
- package/sass/components/_variables.scss +5 -4
- package/sass/components/forms/_range.scss +1 -1
- package/sass/components/forms/_switches.scss +44 -14
- package/Gruntfile.js +0 -480
- package/src/autocomplete.ts +0 -553
- package/src/bounding.ts +0 -6
- package/src/buttons.ts +0 -260
- package/src/cards.ts +0 -53
- package/src/carousel.ts +0 -676
- package/src/characterCounter.ts +0 -117
- package/src/chips.ts +0 -439
- package/src/collapsible.ts +0 -249
- package/src/component.ts +0 -120
- package/src/datepicker.ts +0 -1076
- package/src/dropdown.ts +0 -644
- package/src/edges.ts +0 -6
- package/src/forms.ts +0 -132
- package/src/global.ts +0 -114
- package/src/index.ts +0 -26
- package/src/materialbox.ts +0 -404
- package/src/modal.ts +0 -341
- package/src/parallax.ts +0 -149
- package/src/pushpin.ts +0 -165
- package/src/range.ts +0 -198
- package/src/scrollspy.ts +0 -263
- package/src/select.ts +0 -484
- package/src/sidenav.ts +0 -543
- package/src/slider.ts +0 -474
- package/src/tabs.ts +0 -347
- package/src/tapTarget.ts +0 -273
- package/src/timepicker.ts +0 -832
- package/src/toasts.ts +0 -290
- package/src/tooltip.ts +0 -346
- package/src/utils.ts +0 -271
- package/src/waves.ts +0 -70
package/src/carousel.ts
DELETED
|
@@ -1,676 +0,0 @@
|
|
|
1
|
-
import { Utils } from "./utils";
|
|
2
|
-
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
3
|
-
|
|
4
|
-
export interface CarouselOptions extends BaseOptions{
|
|
5
|
-
/**
|
|
6
|
-
* Transition duration in milliseconds.
|
|
7
|
-
* @default 200
|
|
8
|
-
*/
|
|
9
|
-
duration: number;
|
|
10
|
-
/**
|
|
11
|
-
* Perspective zoom. If 0, all items are the same size.
|
|
12
|
-
* @default -100
|
|
13
|
-
*/
|
|
14
|
-
dist: number;
|
|
15
|
-
/**
|
|
16
|
-
* Set the spacing of the center item.
|
|
17
|
-
* @default 0
|
|
18
|
-
*/
|
|
19
|
-
shift: number;
|
|
20
|
-
/**
|
|
21
|
-
* Set the padding between non center items.
|
|
22
|
-
* @default 0
|
|
23
|
-
*/
|
|
24
|
-
padding: number;
|
|
25
|
-
/**
|
|
26
|
-
* Set the number of visible items.
|
|
27
|
-
* @default 5
|
|
28
|
-
*/
|
|
29
|
-
numVisible: number;
|
|
30
|
-
/**
|
|
31
|
-
* Make the carousel a full width slider like the second example.
|
|
32
|
-
* @default false
|
|
33
|
-
*/
|
|
34
|
-
fullWidth: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Set to true to show indicators.
|
|
37
|
-
* @default false
|
|
38
|
-
*/
|
|
39
|
-
indicators: boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Don't wrap around and cycle through items.
|
|
42
|
-
* @default false
|
|
43
|
-
*/
|
|
44
|
-
noWrap: boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Callback for when a new slide is cycled to.
|
|
47
|
-
* @default null
|
|
48
|
-
*/
|
|
49
|
-
onCycleTo: (current: Element, dragged: boolean) => void;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let _defaults: CarouselOptions = {
|
|
53
|
-
duration: 200, // ms
|
|
54
|
-
dist: -100, // zoom scale TODO: make this more intuitive as an option
|
|
55
|
-
shift: 0, // spacing for center image
|
|
56
|
-
padding: 0, // Padding between non center items
|
|
57
|
-
numVisible: 5, // Number of visible items in carousel
|
|
58
|
-
fullWidth: false, // Change to full width styles
|
|
59
|
-
indicators: false, // Toggle indicators
|
|
60
|
-
noWrap: false, // Don't wrap around and cycle through items.
|
|
61
|
-
onCycleTo: null // Callback for when a new slide is cycled to.
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export class Carousel extends Component<CarouselOptions> {
|
|
65
|
-
hasMultipleSlides: boolean;
|
|
66
|
-
showIndicators: boolean;
|
|
67
|
-
noWrap: boolean;
|
|
68
|
-
/** If the carousel is being clicked or tapped. */
|
|
69
|
-
pressed: boolean;
|
|
70
|
-
/** If the carousel is currently being dragged. */
|
|
71
|
-
dragged: boolean;
|
|
72
|
-
offset: number;
|
|
73
|
-
target: number;
|
|
74
|
-
images: HTMLElement[];
|
|
75
|
-
itemWidth: any;
|
|
76
|
-
itemHeight: any;
|
|
77
|
-
dim: number;
|
|
78
|
-
_indicators: any;
|
|
79
|
-
count: number;
|
|
80
|
-
xform: string;
|
|
81
|
-
verticalDragged: boolean;
|
|
82
|
-
reference: any;
|
|
83
|
-
referenceY: any;
|
|
84
|
-
velocity: number;
|
|
85
|
-
frame: number;
|
|
86
|
-
timestamp: number;
|
|
87
|
-
ticker: string | number | NodeJS.Timeout;
|
|
88
|
-
amplitude: number;
|
|
89
|
-
/** The index of the center carousel item. */
|
|
90
|
-
center: number = 0;
|
|
91
|
-
imageHeight: any;
|
|
92
|
-
scrollingTimeout: any;
|
|
93
|
-
oneTimeCallback: any;
|
|
94
|
-
|
|
95
|
-
constructor(el: HTMLElement, options: Partial<CarouselOptions>) {
|
|
96
|
-
super(el, options, Carousel);
|
|
97
|
-
(this.el as any).M_Carousel = this;
|
|
98
|
-
|
|
99
|
-
this.options = {
|
|
100
|
-
...Carousel.defaults,
|
|
101
|
-
...options
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// Setup
|
|
105
|
-
this.hasMultipleSlides = this.el.querySelectorAll('.carousel-item').length > 1;
|
|
106
|
-
this.showIndicators = this.options.indicators && this.hasMultipleSlides;
|
|
107
|
-
this.noWrap = this.options.noWrap || !this.hasMultipleSlides;
|
|
108
|
-
this.pressed = false;
|
|
109
|
-
this.dragged = false;
|
|
110
|
-
this.offset = this.target = 0;
|
|
111
|
-
this.images = [];
|
|
112
|
-
this.itemWidth = this.el.querySelector('.carousel-item').clientWidth;
|
|
113
|
-
this.itemHeight = this.el.querySelector('.carousel-item').clientHeight;
|
|
114
|
-
this.dim = this.itemWidth * 2 + this.options.padding || 1; // Make sure dim is non zero for divisions.
|
|
115
|
-
|
|
116
|
-
// Full Width carousel setup
|
|
117
|
-
if (this.options.fullWidth) {
|
|
118
|
-
this.options.dist = 0;
|
|
119
|
-
this._setCarouselHeight();
|
|
120
|
-
|
|
121
|
-
// Offset fixed items when indicators.
|
|
122
|
-
if (this.showIndicators) {
|
|
123
|
-
this.el.querySelector('.carousel-fixed-item')?.classList.add('with-indicators');
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Iterate through slides
|
|
128
|
-
this._indicators = document.createElement('ul');
|
|
129
|
-
this._indicators.classList.add('indicators');
|
|
130
|
-
|
|
131
|
-
this.el.querySelectorAll('.carousel-item').forEach((item: HTMLElement, i) => {
|
|
132
|
-
this.images.push(item);
|
|
133
|
-
if (this.showIndicators) {
|
|
134
|
-
const indicator = document.createElement('li');
|
|
135
|
-
indicator.classList.add('indicator-item');
|
|
136
|
-
if (i === 0) {
|
|
137
|
-
indicator.classList.add('active');
|
|
138
|
-
}
|
|
139
|
-
this._indicators.appendChild(indicator);
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
if (this.showIndicators)
|
|
144
|
-
this.el.appendChild(this._indicators);
|
|
145
|
-
|
|
146
|
-
this.count = this.images.length;
|
|
147
|
-
|
|
148
|
-
// Cap numVisible at count
|
|
149
|
-
this.options.numVisible = Math.min(this.count, this.options.numVisible);
|
|
150
|
-
|
|
151
|
-
// Setup cross browser string
|
|
152
|
-
this.xform = 'transform';
|
|
153
|
-
['webkit', 'Moz', 'O', 'ms'].every((prefix) => {
|
|
154
|
-
var e = prefix + 'Transform';
|
|
155
|
-
if (typeof document.body.style[e] !== 'undefined') {
|
|
156
|
-
this.xform = e;
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
return true;
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
this._setupEventHandlers();
|
|
163
|
-
this._scroll(this.offset);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
static get defaults(): CarouselOptions {
|
|
167
|
-
return _defaults;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Initializes instance of Carousel.
|
|
172
|
-
* @param el HTML element.
|
|
173
|
-
* @param options Component options.
|
|
174
|
-
*/
|
|
175
|
-
static init(el: HTMLElement, options?: Partial<CarouselOptions>): Carousel;
|
|
176
|
-
/**
|
|
177
|
-
* Initializes instances of Carousel.
|
|
178
|
-
* @param els HTML elements.
|
|
179
|
-
* @param options Component options.
|
|
180
|
-
*/
|
|
181
|
-
static init(els: InitElements<MElement>, options?: Partial<CarouselOptions>): Carousel[];
|
|
182
|
-
/**
|
|
183
|
-
* Initializes instances of Carousel.
|
|
184
|
-
* @param els HTML elements.
|
|
185
|
-
* @param options Component options.
|
|
186
|
-
*/
|
|
187
|
-
static init(els: HTMLElement | InitElements<MElement>, options: Partial<CarouselOptions> = {}): Carousel | Carousel[] {
|
|
188
|
-
return super.init(els, options, Carousel);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
static getInstance(el: HTMLElement): Carousel {
|
|
192
|
-
return (el as any).M_Carousel;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
destroy() {
|
|
196
|
-
this._removeEventHandlers();
|
|
197
|
-
(this.el as any).M_Carousel = undefined;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
_setupEventHandlers() {
|
|
201
|
-
if (typeof window.ontouchstart !== 'undefined') {
|
|
202
|
-
this.el.addEventListener('touchstart', this._handleCarouselTap);
|
|
203
|
-
this.el.addEventListener('touchmove', this._handleCarouselDrag);
|
|
204
|
-
this.el.addEventListener('touchend', this._handleCarouselRelease);
|
|
205
|
-
}
|
|
206
|
-
this.el.addEventListener('mousedown', this._handleCarouselTap);
|
|
207
|
-
this.el.addEventListener('mousemove', this._handleCarouselDrag);
|
|
208
|
-
this.el.addEventListener('mouseup', this._handleCarouselRelease);
|
|
209
|
-
this.el.addEventListener('mouseleave', this._handleCarouselRelease);
|
|
210
|
-
this.el.addEventListener('click', this._handleCarouselClick);
|
|
211
|
-
if (this.showIndicators && this._indicators) {
|
|
212
|
-
this._indicators.querySelectorAll('.indicator-item').forEach((el) => {
|
|
213
|
-
el.addEventListener('click', this._handleIndicatorClick);
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
// Resize
|
|
217
|
-
window.addEventListener('resize', this._handleThrottledResize);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
_removeEventHandlers() {
|
|
221
|
-
if (typeof window.ontouchstart !== 'undefined') {
|
|
222
|
-
this.el.removeEventListener('touchstart', this._handleCarouselTap);
|
|
223
|
-
this.el.removeEventListener('touchmove', this._handleCarouselDrag);
|
|
224
|
-
this.el.removeEventListener('touchend', this._handleCarouselRelease);
|
|
225
|
-
}
|
|
226
|
-
this.el.removeEventListener('mousedown', this._handleCarouselTap);
|
|
227
|
-
this.el.removeEventListener('mousemove', this._handleCarouselDrag);
|
|
228
|
-
this.el.removeEventListener('mouseup', this._handleCarouselRelease);
|
|
229
|
-
this.el.removeEventListener('mouseleave', this._handleCarouselRelease);
|
|
230
|
-
this.el.removeEventListener('click', this._handleCarouselClick);
|
|
231
|
-
if (this.showIndicators && this._indicators) {
|
|
232
|
-
this._indicators.querySelectorAll('.indicator-item').forEach((el) => {
|
|
233
|
-
el.removeEventListener('click', this._handleIndicatorClick);
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
window.removeEventListener('resize', this._handleThrottledResize);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
_handleThrottledResize: () => void = Utils.throttle(function(){ this._handleResize(); }, 200, null).bind(this);
|
|
240
|
-
|
|
241
|
-
_handleCarouselTap = (e: MouseEvent | TouchEvent) => {
|
|
242
|
-
// Fixes firefox draggable image bug
|
|
243
|
-
if (e.type === 'mousedown' && (<HTMLElement>e.target).tagName === 'IMG') {
|
|
244
|
-
e.preventDefault();
|
|
245
|
-
}
|
|
246
|
-
this.pressed = true;
|
|
247
|
-
this.dragged = false;
|
|
248
|
-
this.verticalDragged = false;
|
|
249
|
-
this.reference = this._xpos(e);
|
|
250
|
-
this.referenceY = this._ypos(e);
|
|
251
|
-
|
|
252
|
-
this.velocity = this.amplitude = 0;
|
|
253
|
-
this.frame = this.offset;
|
|
254
|
-
this.timestamp = Date.now();
|
|
255
|
-
clearInterval(this.ticker);
|
|
256
|
-
this.ticker = setInterval(this._track, 100);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
_handleCarouselDrag = (e: MouseEvent | TouchEvent) => {
|
|
260
|
-
let x: number, y: number, delta: number, deltaY: number;
|
|
261
|
-
if (this.pressed) {
|
|
262
|
-
x = this._xpos(e);
|
|
263
|
-
y = this._ypos(e);
|
|
264
|
-
delta = this.reference - x;
|
|
265
|
-
deltaY = Math.abs(this.referenceY - y);
|
|
266
|
-
if (deltaY < 30 && !this.verticalDragged) {
|
|
267
|
-
// If vertical scrolling don't allow dragging.
|
|
268
|
-
if (delta > 2 || delta < -2) {
|
|
269
|
-
this.dragged = true;
|
|
270
|
-
this.reference = x;
|
|
271
|
-
this._scroll(this.offset + delta);
|
|
272
|
-
}
|
|
273
|
-
} else if (this.dragged) {
|
|
274
|
-
// If dragging don't allow vertical scroll.
|
|
275
|
-
e.preventDefault();
|
|
276
|
-
e.stopPropagation();
|
|
277
|
-
return false;
|
|
278
|
-
} else {
|
|
279
|
-
// Vertical scrolling.
|
|
280
|
-
this.verticalDragged = true;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
if (this.dragged) {
|
|
284
|
-
// If dragging don't allow vertical scroll.
|
|
285
|
-
e.preventDefault();
|
|
286
|
-
e.stopPropagation();
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
_handleCarouselRelease = (e: MouseEvent | TouchEvent) => {
|
|
292
|
-
if (this.pressed) {
|
|
293
|
-
this.pressed = false;
|
|
294
|
-
} else {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
clearInterval(this.ticker);
|
|
298
|
-
this.target = this.offset;
|
|
299
|
-
if (this.velocity > 10 || this.velocity < -10) {
|
|
300
|
-
this.amplitude = 0.9 * this.velocity;
|
|
301
|
-
this.target = this.offset + this.amplitude;
|
|
302
|
-
}
|
|
303
|
-
this.target = Math.round(this.target / this.dim) * this.dim;
|
|
304
|
-
// No wrap of items.
|
|
305
|
-
if (this.noWrap) {
|
|
306
|
-
if (this.target >= this.dim * (this.count - 1)) {
|
|
307
|
-
this.target = this.dim * (this.count - 1);
|
|
308
|
-
} else if (this.target < 0) {
|
|
309
|
-
this.target = 0;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
this.amplitude = this.target - this.offset;
|
|
313
|
-
this.timestamp = Date.now();
|
|
314
|
-
requestAnimationFrame(this._autoScroll);
|
|
315
|
-
if (this.dragged) {
|
|
316
|
-
e.preventDefault();
|
|
317
|
-
e.stopPropagation();
|
|
318
|
-
}
|
|
319
|
-
return false;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
_handleCarouselClick = (e: MouseEvent | TouchEvent) => {
|
|
323
|
-
// Disable clicks if carousel was dragged.
|
|
324
|
-
if (this.dragged) {
|
|
325
|
-
e.preventDefault();
|
|
326
|
-
e.stopPropagation();
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
else if (!this.options.fullWidth) {
|
|
330
|
-
const clickedElem = (<HTMLElement>e.target).closest('.carousel-item');
|
|
331
|
-
if (!clickedElem) return;
|
|
332
|
-
const clickedIndex = [...clickedElem.parentNode.children].indexOf(clickedElem);
|
|
333
|
-
const diff = this._wrap(this.center) - clickedIndex;
|
|
334
|
-
// Disable clicks if carousel was shifted by click
|
|
335
|
-
if (diff !== 0) {
|
|
336
|
-
e.preventDefault();
|
|
337
|
-
e.stopPropagation();
|
|
338
|
-
}
|
|
339
|
-
// fixes https://github.com/materializecss/materialize/issues/180
|
|
340
|
-
if (clickedIndex < 0) {
|
|
341
|
-
// relative X position > center of carousel = clicked at the right part of the carousel
|
|
342
|
-
if ((e as MouseEvent).clientX - (e.target as HTMLElement).getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
343
|
-
this.next();
|
|
344
|
-
} else {
|
|
345
|
-
this.prev();
|
|
346
|
-
}
|
|
347
|
-
} else {
|
|
348
|
-
this._cycleTo(clickedIndex);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
_handleIndicatorClick = (e: Event) => {
|
|
354
|
-
e.stopPropagation();
|
|
355
|
-
const indicator = (<HTMLElement>e.target).closest('.indicator-item');
|
|
356
|
-
if (indicator) {
|
|
357
|
-
const index = [...indicator.parentNode.children].indexOf(indicator);
|
|
358
|
-
this._cycleTo(index);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
_handleResize = () => {
|
|
363
|
-
if (this.options.fullWidth) {
|
|
364
|
-
this.itemWidth = this.el.querySelector('.carousel-item').clientWidth;
|
|
365
|
-
this.imageHeight = this.el.querySelector('.carousel-item.active').clientHeight;
|
|
366
|
-
this.dim = this.itemWidth * 2 + this.options.padding;
|
|
367
|
-
this.offset = this.center * 2 * this.itemWidth;
|
|
368
|
-
this.target = this.offset;
|
|
369
|
-
this._setCarouselHeight(true);
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
this._scroll();
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
_setCarouselHeight(imageOnly: boolean = false) {
|
|
377
|
-
const firstSlide = this.el.querySelector('.carousel-item.active')
|
|
378
|
-
? this.el.querySelector('.carousel-item.active')
|
|
379
|
-
: this.el.querySelector('.carousel-item');
|
|
380
|
-
|
|
381
|
-
const firstImage = firstSlide.querySelector('img');
|
|
382
|
-
if (firstImage) {
|
|
383
|
-
if (firstImage.complete) {
|
|
384
|
-
// If image won't trigger the load event
|
|
385
|
-
const imageHeight = firstImage.clientHeight;
|
|
386
|
-
if (imageHeight > 0) {
|
|
387
|
-
this.el.style.height = imageHeight+'px';
|
|
388
|
-
}
|
|
389
|
-
else {
|
|
390
|
-
// If image still has no height, use the natural dimensions to calculate
|
|
391
|
-
const naturalWidth = firstImage.naturalWidth;
|
|
392
|
-
const naturalHeight = firstImage.naturalHeight;
|
|
393
|
-
const adjustedHeight = (this.el.clientWidth / naturalWidth) * naturalHeight;
|
|
394
|
-
this.el.style.height = adjustedHeight+'px';
|
|
395
|
-
}
|
|
396
|
-
} else {
|
|
397
|
-
// Get height when image is loaded normally
|
|
398
|
-
firstImage.addEventListener('load', () => {
|
|
399
|
-
this.el.style.height = firstImage.offsetHeight+'px';
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
else if (!imageOnly) {
|
|
404
|
-
const slideHeight = firstSlide.clientHeight;
|
|
405
|
-
this.el.style.height = slideHeight+'px';
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
_xpos(e: MouseEvent | TouchEvent) {
|
|
410
|
-
// touch event
|
|
411
|
-
if (e.type.startsWith("touch") && (e as TouchEvent).targetTouches.length >= 1) {
|
|
412
|
-
return (e as TouchEvent).targetTouches[0].clientX;
|
|
413
|
-
}
|
|
414
|
-
// mouse event
|
|
415
|
-
return (e as MouseEvent).clientX;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
_ypos(e: MouseEvent | TouchEvent) {
|
|
419
|
-
// touch event
|
|
420
|
-
if (e.type.startsWith("touch") && (e as TouchEvent).targetTouches.length >= 1) {
|
|
421
|
-
return (e as TouchEvent).targetTouches[0].clientY;
|
|
422
|
-
}
|
|
423
|
-
// mouse event
|
|
424
|
-
return (e as MouseEvent).clientY;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
_wrap(x: number) {
|
|
428
|
-
return x >= this.count
|
|
429
|
-
? x % this.count
|
|
430
|
-
: x < 0
|
|
431
|
-
? this._wrap(this.count + (x % this.count))
|
|
432
|
-
: x;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
_track = () => {
|
|
436
|
-
let now: number, elapsed: number, delta: number, v: number;
|
|
437
|
-
now = Date.now();
|
|
438
|
-
elapsed = now - this.timestamp;
|
|
439
|
-
this.timestamp = now;
|
|
440
|
-
delta = this.offset - this.frame;
|
|
441
|
-
this.frame = this.offset;
|
|
442
|
-
v = (1000 * delta) / (1 + elapsed);
|
|
443
|
-
this.velocity = 0.8 * v + 0.2 * this.velocity;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
_autoScroll = () => {
|
|
447
|
-
let elapsed: number, delta: number;
|
|
448
|
-
if (this.amplitude) {
|
|
449
|
-
elapsed = Date.now() - this.timestamp;
|
|
450
|
-
delta = this.amplitude * Math.exp(-elapsed / this.options.duration);
|
|
451
|
-
if (delta > 2 || delta < -2) {
|
|
452
|
-
this._scroll(this.target - delta);
|
|
453
|
-
requestAnimationFrame(this._autoScroll);
|
|
454
|
-
} else {
|
|
455
|
-
this._scroll(this.target);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
_scroll(x: number = 0) {
|
|
461
|
-
// Track scrolling state
|
|
462
|
-
if (!this.el.classList.contains('scrolling')) {
|
|
463
|
-
this.el.classList.add('scrolling');
|
|
464
|
-
}
|
|
465
|
-
if (this.scrollingTimeout != null) {
|
|
466
|
-
window.clearTimeout(this.scrollingTimeout);
|
|
467
|
-
}
|
|
468
|
-
this.scrollingTimeout = window.setTimeout(() => {
|
|
469
|
-
this.el.classList.remove('scrolling');
|
|
470
|
-
}, this.options.duration);
|
|
471
|
-
|
|
472
|
-
// Start actual scroll
|
|
473
|
-
let i: number,
|
|
474
|
-
half: number,
|
|
475
|
-
delta: number,
|
|
476
|
-
dir: number,
|
|
477
|
-
tween: number,
|
|
478
|
-
el: HTMLElement,
|
|
479
|
-
alignment: string,
|
|
480
|
-
zTranslation: number,
|
|
481
|
-
tweenedOpacity: number,
|
|
482
|
-
centerTweenedOpacity: number;
|
|
483
|
-
let lastCenter = this.center;
|
|
484
|
-
let numVisibleOffset = 1 / this.options.numVisible;
|
|
485
|
-
|
|
486
|
-
this.offset = typeof x === 'number' ? x : this.offset;
|
|
487
|
-
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
|
|
488
|
-
|
|
489
|
-
delta = this.offset - this.center * this.dim;
|
|
490
|
-
dir = delta < 0 ? 1 : -1;
|
|
491
|
-
tween = (-dir * delta * 2) / this.dim;
|
|
492
|
-
half = this.count >> 1;
|
|
493
|
-
|
|
494
|
-
if (this.options.fullWidth) {
|
|
495
|
-
alignment = 'translateX(0)';
|
|
496
|
-
centerTweenedOpacity = 1;
|
|
497
|
-
}
|
|
498
|
-
else {
|
|
499
|
-
alignment = 'translateX(' + (this.el.clientWidth - this.itemWidth) / 2 + 'px) ';
|
|
500
|
-
alignment += 'translateY(' + (this.el.clientHeight - this.itemHeight) / 2 + 'px)';
|
|
501
|
-
centerTweenedOpacity = 1 - numVisibleOffset * tween;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// Set indicator active
|
|
505
|
-
if (this.showIndicators) {
|
|
506
|
-
const diff = this.center % this.count;
|
|
507
|
-
const activeIndicator = this._indicators.querySelector('.indicator-item.active');
|
|
508
|
-
const activeIndicatorIndex = [...activeIndicator.parentNode.children].indexOf(activeIndicator);
|
|
509
|
-
if (activeIndicatorIndex !== diff) {
|
|
510
|
-
activeIndicator.classList.remove('active');
|
|
511
|
-
const pos = diff < 0 ? this.count + diff : diff;
|
|
512
|
-
this._indicators.querySelectorAll('.indicator-item')[pos].classList.add('active');
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// center
|
|
517
|
-
// Don't show wrapped items.
|
|
518
|
-
if (!this.noWrap || (this.center >= 0 && this.center < this.count)) {
|
|
519
|
-
el = this.images[this._wrap(this.center)];
|
|
520
|
-
|
|
521
|
-
// Add active class to center item.
|
|
522
|
-
if (!el.classList.contains('active')) {
|
|
523
|
-
this.el.querySelector('.carousel-item').classList.remove('active');
|
|
524
|
-
el.classList.add('active');
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
let transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir *
|
|
528
|
-
this.options.shift *
|
|
529
|
-
tween *
|
|
530
|
-
i}px) translateZ(${this.options.dist * tween}px)`;
|
|
531
|
-
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
for (i = 1; i <= half; ++i) {
|
|
535
|
-
// right side
|
|
536
|
-
if (this.options.fullWidth) {
|
|
537
|
-
zTranslation = this.options.dist;
|
|
538
|
-
tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
|
|
539
|
-
} else {
|
|
540
|
-
zTranslation = this.options.dist * (i * 2 + tween * dir);
|
|
541
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
|
|
542
|
-
}
|
|
543
|
-
// Don't show wrapped items.
|
|
544
|
-
if (!this.noWrap || this.center + i < this.count) {
|
|
545
|
-
el = this.images[this._wrap(this.center + i)];
|
|
546
|
-
let transformString = `${alignment} translateX(${this.options.shift +
|
|
547
|
-
(this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
548
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
549
|
-
}
|
|
550
|
-
// left side
|
|
551
|
-
if (this.options.fullWidth) {
|
|
552
|
-
zTranslation = this.options.dist;
|
|
553
|
-
tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
|
|
554
|
-
} else {
|
|
555
|
-
zTranslation = this.options.dist * (i * 2 - tween * dir);
|
|
556
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
|
|
557
|
-
}
|
|
558
|
-
// Don't show wrapped items.
|
|
559
|
-
if (!this.noWrap || this.center - i >= 0) {
|
|
560
|
-
el = this.images[this._wrap(this.center - i)];
|
|
561
|
-
let transformString = `${alignment} translateX(${-this.options.shift +
|
|
562
|
-
(-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
563
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
// center
|
|
567
|
-
// Don't show wrapped items.
|
|
568
|
-
if (!this.noWrap || (this.center >= 0 && this.center < this.count)) {
|
|
569
|
-
el = this.images[this._wrap(this.center)];
|
|
570
|
-
let transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir *
|
|
571
|
-
this.options.shift *
|
|
572
|
-
tween}px) translateZ(${this.options.dist * tween}px)`;
|
|
573
|
-
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
574
|
-
}
|
|
575
|
-
// onCycleTo callback
|
|
576
|
-
const _currItem = this.el.querySelectorAll('.carousel-item')[this._wrap(this.center)];
|
|
577
|
-
|
|
578
|
-
if (lastCenter !== this.center && typeof this.options.onCycleTo === 'function') {
|
|
579
|
-
this.options.onCycleTo.call(this, _currItem, this.dragged);
|
|
580
|
-
}
|
|
581
|
-
// One time callback
|
|
582
|
-
if (typeof this.oneTimeCallback === 'function') {
|
|
583
|
-
this.oneTimeCallback.call(this, _currItem, this.dragged);
|
|
584
|
-
this.oneTimeCallback = null;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
_updateItemStyle(el: HTMLElement, opacity: number, zIndex: number, transform: string) {
|
|
589
|
-
el.style[this.xform] = transform;
|
|
590
|
-
el.style.zIndex = zIndex.toString();
|
|
591
|
-
el.style.opacity = opacity.toString();
|
|
592
|
-
el.style.visibility = 'visible';
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
_cycleTo(n: number, callback: CarouselOptions["onCycleTo"] = null) {
|
|
596
|
-
let diff = (this.center % this.count) - n;
|
|
597
|
-
// Account for wraparound.
|
|
598
|
-
if (!this.noWrap) {
|
|
599
|
-
if (diff < 0) {
|
|
600
|
-
if (Math.abs(diff + this.count) < Math.abs(diff)) {
|
|
601
|
-
diff += this.count;
|
|
602
|
-
}
|
|
603
|
-
} else if (diff > 0) {
|
|
604
|
-
if (Math.abs(diff - this.count) < diff) {
|
|
605
|
-
diff -= this.count;
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
this.target = this.dim * Math.round(this.offset / this.dim);
|
|
610
|
-
// Next
|
|
611
|
-
if (diff < 0) {
|
|
612
|
-
this.target += this.dim * Math.abs(diff);
|
|
613
|
-
} // Prev
|
|
614
|
-
else if (diff > 0) {
|
|
615
|
-
this.target -= this.dim * diff;
|
|
616
|
-
}
|
|
617
|
-
// Set one time callback
|
|
618
|
-
if (typeof callback === 'function') {
|
|
619
|
-
this.oneTimeCallback = callback;
|
|
620
|
-
}
|
|
621
|
-
// Scroll
|
|
622
|
-
if (this.offset !== this.target) {
|
|
623
|
-
this.amplitude = this.target - this.offset;
|
|
624
|
-
this.timestamp = Date.now();
|
|
625
|
-
requestAnimationFrame(this._autoScroll);
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
/**
|
|
630
|
-
* Move carousel to next slide or go forward a given amount of slides.
|
|
631
|
-
* @param n How many times the carousel slides.
|
|
632
|
-
*/
|
|
633
|
-
next(n: number = 1) {
|
|
634
|
-
if (n === undefined || isNaN(n)) {
|
|
635
|
-
n = 1;
|
|
636
|
-
}
|
|
637
|
-
let index = this.center + n;
|
|
638
|
-
if (index >= this.count || index < 0) {
|
|
639
|
-
if (this.noWrap) return;
|
|
640
|
-
index = this._wrap(index);
|
|
641
|
-
}
|
|
642
|
-
this._cycleTo(index);
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
/**
|
|
646
|
-
* Move carousel to previous slide or go back a given amount of slides.
|
|
647
|
-
* @param n How many times the carousel slides.
|
|
648
|
-
*/
|
|
649
|
-
prev(n: number = 1) {
|
|
650
|
-
if (n === undefined || isNaN(n)) {
|
|
651
|
-
n = 1;
|
|
652
|
-
}
|
|
653
|
-
let index = this.center - n;
|
|
654
|
-
if (index >= this.count || index < 0) {
|
|
655
|
-
if (this.noWrap) return;
|
|
656
|
-
index = this._wrap(index);
|
|
657
|
-
}
|
|
658
|
-
this._cycleTo(index);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
/**
|
|
662
|
-
* Move carousel to nth slide.
|
|
663
|
-
* @param n Index of slide.
|
|
664
|
-
* @param callback "onCycleTo" optional callback.
|
|
665
|
-
*/
|
|
666
|
-
set(n: number, callback?: CarouselOptions["onCycleTo"]) {
|
|
667
|
-
if (n === undefined || isNaN(n)) {
|
|
668
|
-
n = 0;
|
|
669
|
-
}
|
|
670
|
-
if (n > this.count || n < 0) {
|
|
671
|
-
if (this.noWrap) return;
|
|
672
|
-
n = this._wrap(n);
|
|
673
|
-
}
|
|
674
|
-
this._cycleTo(n, callback);
|
|
675
|
-
}
|
|
676
|
-
}
|