@materializecss/materialize 2.0.1-alpha → 2.0.2-alpha
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/Gruntfile.js +5 -2
- package/dist/css/materialize.css +90 -86
- package/dist/css/materialize.min.css +2 -2
- package/dist/js/materialize.js +2797 -2705
- package/dist/js/materialize.min.js +2 -8967
- package/dist/js/materialize.min.js.map +1 -1
- package/package.json +1 -1
- package/sass/components/_collapsible.scss +0 -41
- package/sass/components/_global.scss +3 -2
- package/sass/components/_icons-material-design.scss +2 -1
- package/sass/components/_navbar.scss +6 -3
- package/sass/components/_sidenav.scss +66 -37
- package/sass/components/_theme_variables.scss +2 -2
- package/sass/components/_typography.scss +2 -2
- package/sass/components/forms/_input-fields.scss +4 -10
- package/sass/materialize.scss +0 -4
- package/src/autocomplete.ts +188 -94
- package/src/buttons.ts +225 -260
- package/src/cards.ts +5 -6
- package/src/carousel.ts +611 -542
- package/src/characterCounter.ts +50 -21
- package/src/chips.ts +152 -63
- package/src/collapsible.ts +97 -32
- package/src/component.ts +99 -10
- package/src/datepicker.ts +905 -726
- package/src/dropdown.ts +576 -484
- package/src/edges.ts +4 -4
- package/src/forms.ts +17 -14
- package/src/global.ts +55 -324
- package/src/materialbox.ts +354 -298
- package/src/modal.ts +296 -211
- package/src/parallax.ts +129 -105
- package/src/pushpin.ts +148 -103
- package/src/range.ts +166 -150
- package/src/scrollspy.ts +214 -174
- package/src/select.ts +434 -398
- package/src/sidenav.ts +447 -381
- package/src/slider.ts +421 -362
- package/src/tabs.ts +276 -222
- package/src/tapTarget.ts +246 -213
- package/src/timepicker.ts +738 -614
- package/src/toasts.ts +254 -230
- package/src/tooltip.ts +315 -252
- package/src/utils.ts +271 -0
- package/src/waves.ts +10 -10
package/src/carousel.ts
CHANGED
|
@@ -1,607 +1,676 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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: NodeJS.Timer;
|
|
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
|
+
}
|
|
71
126
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this._setCarouselHeight();
|
|
127
|
+
// Iterate through slides
|
|
128
|
+
this._indicators = document.createElement('ul');
|
|
129
|
+
this._indicators.classList.add('indicators');
|
|
76
130
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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');
|
|
80
138
|
}
|
|
139
|
+
this._indicators.appendChild(indicator);
|
|
81
140
|
}
|
|
141
|
+
});
|
|
82
142
|
|
|
83
|
-
|
|
84
|
-
this.
|
|
85
|
-
this._indicators.classList.add('indicators');
|
|
86
|
-
|
|
87
|
-
this.el.querySelectorAll('.carousel-item').forEach((item: HTMLElement, i) => {
|
|
88
|
-
this.images.push(item);
|
|
89
|
-
if (this.showIndicators) {
|
|
90
|
-
const indicator = document.createElement('li');
|
|
91
|
-
indicator.classList.add('indicator-item');
|
|
92
|
-
if (i === 0) {
|
|
93
|
-
indicator.classList.add('active');
|
|
94
|
-
}
|
|
95
|
-
this._indicators.appendChild(indicator);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
if (this.showIndicators)
|
|
100
|
-
this.el.appendChild(this._indicators);
|
|
143
|
+
if (this.showIndicators)
|
|
144
|
+
this.el.appendChild(this._indicators);
|
|
101
145
|
|
|
102
|
-
|
|
146
|
+
this.count = this.images.length;
|
|
103
147
|
|
|
104
|
-
|
|
105
|
-
|
|
148
|
+
// Cap numVisible at count
|
|
149
|
+
this.options.numVisible = Math.min(this.count, this.options.numVisible);
|
|
106
150
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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);
|
|
124
205
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
+
});
|
|
128
215
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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);
|
|
133
225
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
+
});
|
|
138
235
|
}
|
|
236
|
+
window.removeEventListener('resize', this._handleThrottledResize);
|
|
237
|
+
}
|
|
139
238
|
|
|
140
|
-
|
|
141
|
-
this._handleCarouselTapBound = this._handleCarouselTap.bind(this);
|
|
142
|
-
this._handleCarouselDragBound = this._handleCarouselDrag.bind(this);
|
|
143
|
-
this._handleCarouselReleaseBound = this._handleCarouselRelease.bind(this);
|
|
144
|
-
this._handleCarouselClickBound = this._handleCarouselClick.bind(this);
|
|
145
|
-
if (typeof window.ontouchstart !== 'undefined') {
|
|
146
|
-
this.el.addEventListener('touchstart', this._handleCarouselTapBound);
|
|
147
|
-
this.el.addEventListener('touchmove', this._handleCarouselDragBound);
|
|
148
|
-
this.el.addEventListener('touchend', this._handleCarouselReleaseBound);
|
|
149
|
-
}
|
|
150
|
-
this.el.addEventListener('mousedown', this._handleCarouselTapBound);
|
|
151
|
-
this.el.addEventListener('mousemove', this._handleCarouselDragBound);
|
|
152
|
-
this.el.addEventListener('mouseup', this._handleCarouselReleaseBound);
|
|
153
|
-
this.el.addEventListener('mouseleave', this._handleCarouselReleaseBound);
|
|
154
|
-
this.el.addEventListener('click', this._handleCarouselClickBound);
|
|
155
|
-
if (this.showIndicators && this._indicators) {
|
|
156
|
-
this._handleIndicatorClickBound = this._handleIndicatorClick.bind(this);
|
|
157
|
-
this._indicators.querySelectorAll('.indicator-item').forEach((el) => {
|
|
158
|
-
el.addEventListener('click', this._handleIndicatorClickBound);
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
// Resize
|
|
162
|
-
let throttledResize = M.throttle(this._handleResize, 200, null);
|
|
163
|
-
this._handleThrottledResizeBound = throttledResize.bind(this);
|
|
164
|
-
window.addEventListener('resize', this._handleThrottledResizeBound);
|
|
165
|
-
}
|
|
239
|
+
_handleThrottledResize: () => void = Utils.throttle(function(){ this._handleResize(); }, 200, null).bind(this);
|
|
166
240
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
this.el.removeEventListener('touchend', this._handleCarouselReleaseBound);
|
|
172
|
-
}
|
|
173
|
-
this.el.removeEventListener('mousedown', this._handleCarouselTapBound);
|
|
174
|
-
this.el.removeEventListener('mousemove', this._handleCarouselDragBound);
|
|
175
|
-
this.el.removeEventListener('mouseup', this._handleCarouselReleaseBound);
|
|
176
|
-
this.el.removeEventListener('mouseleave', this._handleCarouselReleaseBound);
|
|
177
|
-
this.el.removeEventListener('click', this._handleCarouselClickBound);
|
|
178
|
-
if (this.showIndicators && this._indicators) {
|
|
179
|
-
this._indicators.querySelectorAll('.indicator-item').forEach((el) => {
|
|
180
|
-
el.removeEventListener('click', this._handleIndicatorClickBound);
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
window.removeEventListener('resize', this._handleThrottledResizeBound);
|
|
241
|
+
_handleCarouselTap = (e: MouseEvent | TouchEvent) => {
|
|
242
|
+
// Fixes firefox draggable image bug
|
|
243
|
+
if (e.type === 'mousedown' && (<HTMLElement>e.target).tagName === 'IMG') {
|
|
244
|
+
e.preventDefault();
|
|
184
245
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (deltaY < 30 && !this.verticalDragged) {
|
|
212
|
-
// If vertical scrolling don't allow dragging.
|
|
213
|
-
if (delta > 2 || delta < -2) {
|
|
214
|
-
this.dragged = true;
|
|
215
|
-
this.reference = x;
|
|
216
|
-
this._scroll(this.offset + delta);
|
|
217
|
-
}
|
|
218
|
-
} else if (this.dragged) {
|
|
219
|
-
// If dragging don't allow vertical scroll.
|
|
220
|
-
e.preventDefault();
|
|
221
|
-
e.stopPropagation();
|
|
222
|
-
return false;
|
|
223
|
-
} else {
|
|
224
|
-
// Vertical scrolling.
|
|
225
|
-
this.verticalDragged = true;
|
|
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);
|
|
226
272
|
}
|
|
227
|
-
}
|
|
228
|
-
if (this.dragged) {
|
|
273
|
+
} else if (this.dragged) {
|
|
229
274
|
// If dragging don't allow vertical scroll.
|
|
230
275
|
e.preventDefault();
|
|
231
276
|
e.stopPropagation();
|
|
232
277
|
return false;
|
|
278
|
+
} else {
|
|
279
|
+
// Vertical scrolling.
|
|
280
|
+
this.verticalDragged = true;
|
|
233
281
|
}
|
|
234
282
|
}
|
|
283
|
+
if (this.dragged) {
|
|
284
|
+
// If dragging don't allow vertical scroll.
|
|
285
|
+
e.preventDefault();
|
|
286
|
+
e.stopPropagation();
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
235
290
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
this.amplitude = this.target - this.offset;
|
|
258
|
-
this.timestamp = Date.now();
|
|
259
|
-
requestAnimationFrame(this._autoScrollBound);
|
|
260
|
-
if (this.dragged) {
|
|
261
|
-
e.preventDefault();
|
|
262
|
-
e.stopPropagation();
|
|
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;
|
|
263
310
|
}
|
|
264
|
-
return false;
|
|
265
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
|
+
}
|
|
266
321
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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) {
|
|
270
336
|
e.preventDefault();
|
|
271
337
|
e.stopPropagation();
|
|
272
|
-
return false;
|
|
273
338
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (diff !== 0) {
|
|
280
|
-
e.preventDefault();
|
|
281
|
-
e.stopPropagation();
|
|
282
|
-
}
|
|
283
|
-
// fixes https://github.com/materializecss/materialize/issues/180
|
|
284
|
-
if (clickedIndex < 0) {
|
|
285
|
-
// relative X position > center of carousel = clicked at the right part of the carousel
|
|
286
|
-
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
287
|
-
this.next();
|
|
288
|
-
} else {
|
|
289
|
-
this.prev();
|
|
290
|
-
}
|
|
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();
|
|
291
344
|
} else {
|
|
292
|
-
this.
|
|
345
|
+
this.prev();
|
|
293
346
|
}
|
|
347
|
+
} else {
|
|
348
|
+
this._cycleTo(clickedIndex);
|
|
294
349
|
}
|
|
295
350
|
}
|
|
351
|
+
}
|
|
296
352
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
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);
|
|
304
359
|
}
|
|
360
|
+
}
|
|
305
361
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
this._scroll();
|
|
317
|
-
}
|
|
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);
|
|
318
370
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const naturalHeight = firstImage.naturalHeight;
|
|
337
|
-
const adjustedHeight = (this.el.clientWidth / naturalWidth) * naturalHeight;
|
|
338
|
-
this.el.style.height = adjustedHeight+'px';
|
|
339
|
-
}
|
|
340
|
-
} else {
|
|
341
|
-
// Get height when image is loaded normally
|
|
342
|
-
firstImage.addEventListener('load', () => {
|
|
343
|
-
this.el.style.height = firstImage.offsetHeight+'px';
|
|
344
|
-
});
|
|
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';
|
|
345
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
|
+
});
|
|
346
401
|
}
|
|
347
|
-
else if (!imageOnly) {
|
|
348
|
-
const slideHeight = firstSlide.clientHeight;
|
|
349
|
-
this.el.style.height = slideHeight+'px';
|
|
350
|
-
}
|
|
351
402
|
}
|
|
403
|
+
else if (!imageOnly) {
|
|
404
|
+
const slideHeight = firstSlide.clientHeight;
|
|
405
|
+
this.el.style.height = slideHeight+'px';
|
|
406
|
+
}
|
|
407
|
+
}
|
|
352
408
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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);
|
|
357
456
|
}
|
|
358
|
-
// mouse event
|
|
359
|
-
return e.clientX;
|
|
360
457
|
}
|
|
458
|
+
}
|
|
361
459
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
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;
|
|
402
502
|
}
|
|
403
503
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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');
|
|
408
513
|
}
|
|
409
|
-
|
|
410
|
-
window.clearTimeout(this.scrollingTimeout);
|
|
411
|
-
}
|
|
412
|
-
this.scrollingTimeout = window.setTimeout(() => {
|
|
413
|
-
this.el.classList.remove('scrolling');
|
|
414
|
-
}, this.options.duration);
|
|
415
|
-
|
|
416
|
-
// Start actual scroll
|
|
417
|
-
let i,
|
|
418
|
-
half,
|
|
419
|
-
delta,
|
|
420
|
-
dir,
|
|
421
|
-
tween,
|
|
422
|
-
el,
|
|
423
|
-
alignment,
|
|
424
|
-
zTranslation,
|
|
425
|
-
tweenedOpacity,
|
|
426
|
-
centerTweenedOpacity;
|
|
427
|
-
let lastCenter = this.center;
|
|
428
|
-
let numVisibleOffset = 1 / this.options.numVisible;
|
|
429
|
-
|
|
430
|
-
this.offset = typeof x === 'number' ? x : this.offset;
|
|
431
|
-
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
|
|
432
|
-
|
|
433
|
-
delta = this.offset - this.center * this.dim;
|
|
434
|
-
dir = delta < 0 ? 1 : -1;
|
|
435
|
-
tween = (-dir * delta * 2) / this.dim;
|
|
436
|
-
half = this.count >> 1;
|
|
514
|
+
}
|
|
437
515
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
else {
|
|
443
|
-
alignment = 'translateX(' + (this.el.clientWidth - this.itemWidth) / 2 + 'px) ';
|
|
444
|
-
alignment += 'translateY(' + (this.el.clientHeight - this.itemHeight) / 2 + 'px)';
|
|
445
|
-
centerTweenedOpacity = 1 - numVisibleOffset * tween;
|
|
446
|
-
}
|
|
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)];
|
|
447
520
|
|
|
448
|
-
//
|
|
449
|
-
if (
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
const activeIndicatorIndex = [...activeIndicator.parentNode.children].indexOf(activeIndicator);
|
|
453
|
-
if (activeIndicatorIndex !== diff) {
|
|
454
|
-
activeIndicator.classList.remove('active');
|
|
455
|
-
const pos = diff < 0 ? this.count + diff : diff;
|
|
456
|
-
this._indicators.querySelectorAll('.indicator-item')[pos].classList.add('active');
|
|
457
|
-
}
|
|
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');
|
|
458
525
|
}
|
|
459
526
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if (!el.classList.contains('active')) {
|
|
467
|
-
this.el.querySelector('.carousel-item').classList.remove('active');
|
|
468
|
-
el.classList.add('active');
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
let transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir *
|
|
472
|
-
this.options.shift *
|
|
473
|
-
tween *
|
|
474
|
-
i}px) translateZ(${this.options.dist * tween}px)`;
|
|
475
|
-
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
476
|
-
}
|
|
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
|
+
}
|
|
477
533
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
// Don't show wrapped items.
|
|
488
|
-
if (!this.noWrap || this.center + i < this.count) {
|
|
489
|
-
el = this.images[this._wrap(this.center + i)];
|
|
490
|
-
let transformString = `${alignment} translateX(${this.options.shift +
|
|
491
|
-
(this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
492
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
493
|
-
}
|
|
494
|
-
// left side
|
|
495
|
-
if (this.options.fullWidth) {
|
|
496
|
-
zTranslation = this.options.dist;
|
|
497
|
-
tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
|
|
498
|
-
} else {
|
|
499
|
-
zTranslation = this.options.dist * (i * 2 - tween * dir);
|
|
500
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
|
|
501
|
-
}
|
|
502
|
-
// Don't show wrapped items.
|
|
503
|
-
if (!this.noWrap || this.center - i >= 0) {
|
|
504
|
-
el = this.images[this._wrap(this.center - i)];
|
|
505
|
-
let transformString = `${alignment} translateX(${-this.options.shift +
|
|
506
|
-
(-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
507
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
508
|
-
}
|
|
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);
|
|
509
542
|
}
|
|
510
|
-
// center
|
|
511
543
|
// Don't show wrapped items.
|
|
512
|
-
if (!this.noWrap ||
|
|
513
|
-
el = this.images[this._wrap(this.center)];
|
|
514
|
-
let transformString = `${alignment} translateX(${
|
|
515
|
-
this.
|
|
516
|
-
|
|
517
|
-
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
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);
|
|
518
549
|
}
|
|
519
|
-
//
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
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);
|
|
524
557
|
}
|
|
525
|
-
//
|
|
526
|
-
if (
|
|
527
|
-
this.
|
|
528
|
-
this.
|
|
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);
|
|
529
564
|
}
|
|
530
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)];
|
|
531
577
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
this.target = this.dim * Math.round(this.offset / this.dim);
|
|
554
|
-
// Next
|
|
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) {
|
|
555
599
|
if (diff < 0) {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
this.oneTimeCallback = callback;
|
|
564
|
-
}
|
|
565
|
-
// Scroll
|
|
566
|
-
if (this.offset !== this.target) {
|
|
567
|
-
this.amplitude = this.target - this.offset;
|
|
568
|
-
this.timestamp = Date.now();
|
|
569
|
-
requestAnimationFrame(this._autoScrollBound);
|
|
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
|
+
}
|
|
570
607
|
}
|
|
571
608
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
if (this.noWrap) return;
|
|
580
|
-
index = this._wrap(index);
|
|
581
|
-
}
|
|
582
|
-
this._cycleTo(index);
|
|
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;
|
|
583
616
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
n = 1;
|
|
588
|
-
}
|
|
589
|
-
let index = this.center - n;
|
|
590
|
-
if (index >= this.count || index < 0) {
|
|
591
|
-
if (this.noWrap) return;
|
|
592
|
-
index = this._wrap(index);
|
|
593
|
-
}
|
|
594
|
-
this._cycleTo(index);
|
|
617
|
+
// Set one time callback
|
|
618
|
+
if (typeof callback === 'function') {
|
|
619
|
+
this.oneTimeCallback = callback;
|
|
595
620
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
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);
|
|
606
673
|
}
|
|
607
|
-
|
|
674
|
+
this._cycleTo(n, callback);
|
|
675
|
+
}
|
|
676
|
+
}
|