administrate-materialize-theme 0.1.0
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +49 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/administrate-materialize-theme/anime.min.js +34 -0
- data/app/assets/javascripts/administrate-materialize-theme/autocomplete.js +450 -0
- data/app/assets/javascripts/administrate-materialize-theme/bin/materialize.js +12374 -0
- data/app/assets/javascripts/administrate-materialize-theme/bin/materialize.min.js +6 -0
- data/app/assets/javascripts/administrate-materialize-theme/buttons.js +354 -0
- data/app/assets/javascripts/administrate-materialize-theme/cards.js +40 -0
- data/app/assets/javascripts/administrate-materialize-theme/carousel.js +717 -0
- data/app/assets/javascripts/administrate-materialize-theme/cash.js +960 -0
- data/app/assets/javascripts/administrate-materialize-theme/characterCounter.js +136 -0
- data/app/assets/javascripts/administrate-materialize-theme/chips.js +481 -0
- data/app/assets/javascripts/administrate-materialize-theme/collapsible.js +275 -0
- data/app/assets/javascripts/administrate-materialize-theme/component.js +44 -0
- data/app/assets/javascripts/administrate-materialize-theme/datepicker.js +975 -0
- data/app/assets/javascripts/administrate-materialize-theme/dropdown.js +617 -0
- data/app/assets/javascripts/administrate-materialize-theme/forms.js +275 -0
- data/app/assets/javascripts/administrate-materialize-theme/global.js +427 -0
- data/app/assets/javascripts/administrate-materialize-theme/materialbox.js +453 -0
- data/app/assets/javascripts/administrate-materialize-theme/modal.js +382 -0
- data/app/assets/javascripts/administrate-materialize-theme/parallax.js +138 -0
- data/app/assets/javascripts/administrate-materialize-theme/pushpin.js +145 -0
- data/app/assets/javascripts/administrate-materialize-theme/range.js +263 -0
- data/app/assets/javascripts/administrate-materialize-theme/scrollspy.js +295 -0
- data/app/assets/javascripts/administrate-materialize-theme/select.js +432 -0
- data/app/assets/javascripts/administrate-materialize-theme/sidenav.js +580 -0
- data/app/assets/javascripts/administrate-materialize-theme/slider.js +359 -0
- data/app/assets/javascripts/administrate-materialize-theme/tabs.js +402 -0
- data/app/assets/javascripts/administrate-materialize-theme/tapTarget.js +314 -0
- data/app/assets/javascripts/administrate-materialize-theme/theme.js +6 -0
- data/app/assets/javascripts/administrate-materialize-theme/timepicker.js +647 -0
- data/app/assets/javascripts/administrate-materialize-theme/toasts.js +310 -0
- data/app/assets/javascripts/administrate-materialize-theme/tooltip.js +303 -0
- data/app/assets/javascripts/administrate-materialize-theme/waves.js +335 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_badges.scss +55 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_buttons.scss +322 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_cards.scss +195 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_carousel.scss +90 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_chips.scss +90 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_collapsible.scss +91 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_color-classes.scss +32 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_color-variables.scss +370 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_datepicker.scss +191 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_dropdown.scss +85 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_global.scss +769 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_grid.scss +156 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_icons-material-design.scss +5 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_materialbox.scss +43 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_modal.scss +94 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_navbar.scss +208 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_normalize.scss +447 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_preloader.scss +334 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_pulse.scss +34 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_sidenav.scss +216 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_slider.scss +92 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_table_of_contents.scss +33 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_tabs.scss +99 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_tapTarget.scss +103 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_timepicker.scss +183 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_toast.scss +58 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_tooltip.scss +32 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_transitions.scss +13 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_typography.scss +60 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_variables.scss +349 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/_waves.scss +114 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/forms/_checkboxes.scss +200 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/forms/_file-input.scss +44 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/forms/_forms.scss +22 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/forms/_input-fields.scss +354 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/forms/_radio-buttons.scss +115 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/forms/_range.scss +161 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/forms/_select.scss +180 -0
- data/app/assets/stylesheets/administrate-materialize-theme/components/forms/_switches.scss +89 -0
- data/app/assets/stylesheets/administrate-materialize-theme/materialize.scss +41 -0
- data/app/assets/stylesheets/administrate-materialize-theme/theme.scss +200 -0
- data/lib/administrate-materialize-theme.rb +6 -0
- data/lib/administrate-materialize-theme/engine.rb +7 -0
- data/lib/administrate-materialize-theme/version.rb +5 -0
- metadata +150 -0
@@ -0,0 +1,382 @@
|
|
1
|
+
(function($, anim) {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
let _defaults = {
|
5
|
+
opacity: 0.5,
|
6
|
+
inDuration: 250,
|
7
|
+
outDuration: 250,
|
8
|
+
onOpenStart: null,
|
9
|
+
onOpenEnd: null,
|
10
|
+
onCloseStart: null,
|
11
|
+
onCloseEnd: null,
|
12
|
+
preventScrolling: true,
|
13
|
+
dismissible: true,
|
14
|
+
startingTop: '4%',
|
15
|
+
endingTop: '10%'
|
16
|
+
};
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @class
|
20
|
+
*
|
21
|
+
*/
|
22
|
+
class Modal extends Component {
|
23
|
+
/**
|
24
|
+
* Construct Modal instance and set up overlay
|
25
|
+
* @constructor
|
26
|
+
* @param {Element} el
|
27
|
+
* @param {Object} options
|
28
|
+
*/
|
29
|
+
constructor(el, options) {
|
30
|
+
super(Modal, el, options);
|
31
|
+
|
32
|
+
this.el.M_Modal = this;
|
33
|
+
|
34
|
+
/**
|
35
|
+
* Options for the modal
|
36
|
+
* @member Modal#options
|
37
|
+
* @prop {Number} [opacity=0.5] - Opacity of the modal overlay
|
38
|
+
* @prop {Number} [inDuration=250] - Length in ms of enter transition
|
39
|
+
* @prop {Number} [outDuration=250] - Length in ms of exit transition
|
40
|
+
* @prop {Function} onOpenStart - Callback function called before modal is opened
|
41
|
+
* @prop {Function} onOpenEnd - Callback function called after modal is opened
|
42
|
+
* @prop {Function} onCloseStart - Callback function called before modal is closed
|
43
|
+
* @prop {Function} onCloseEnd - Callback function called after modal is closed
|
44
|
+
* @prop {Boolean} [dismissible=true] - Allow modal to be dismissed by keyboard or overlay click
|
45
|
+
* @prop {String} [startingTop='4%'] - startingTop
|
46
|
+
* @prop {String} [endingTop='10%'] - endingTop
|
47
|
+
*/
|
48
|
+
this.options = $.extend({}, Modal.defaults, options);
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Describes open/close state of modal
|
52
|
+
* @type {Boolean}
|
53
|
+
*/
|
54
|
+
this.isOpen = false;
|
55
|
+
|
56
|
+
this.id = this.$el.attr('id');
|
57
|
+
this._openingTrigger = undefined;
|
58
|
+
this.$overlay = $('<div class="modal-overlay"></div>');
|
59
|
+
this.el.tabIndex = 0;
|
60
|
+
this._nthModalOpened = 0;
|
61
|
+
|
62
|
+
Modal._count++;
|
63
|
+
this._setupEventHandlers();
|
64
|
+
}
|
65
|
+
|
66
|
+
static get defaults() {
|
67
|
+
return _defaults;
|
68
|
+
}
|
69
|
+
|
70
|
+
static init(els, options) {
|
71
|
+
return super.init(this, els, options);
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Get Instance
|
76
|
+
*/
|
77
|
+
static getInstance(el) {
|
78
|
+
let domElem = !!el.jquery ? el[0] : el;
|
79
|
+
return domElem.M_Modal;
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* Teardown component
|
84
|
+
*/
|
85
|
+
destroy() {
|
86
|
+
Modal._count--;
|
87
|
+
this._removeEventHandlers();
|
88
|
+
this.el.removeAttribute('style');
|
89
|
+
this.$overlay.remove();
|
90
|
+
this.el.M_Modal = undefined;
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
* Setup Event Handlers
|
95
|
+
*/
|
96
|
+
_setupEventHandlers() {
|
97
|
+
this._handleOverlayClickBound = this._handleOverlayClick.bind(this);
|
98
|
+
this._handleModalCloseClickBound = this._handleModalCloseClick.bind(this);
|
99
|
+
|
100
|
+
if (Modal._count === 1) {
|
101
|
+
document.body.addEventListener('click', this._handleTriggerClick);
|
102
|
+
}
|
103
|
+
this.$overlay[0].addEventListener('click', this._handleOverlayClickBound);
|
104
|
+
this.el.addEventListener('click', this._handleModalCloseClickBound);
|
105
|
+
}
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Remove Event Handlers
|
109
|
+
*/
|
110
|
+
_removeEventHandlers() {
|
111
|
+
if (Modal._count === 0) {
|
112
|
+
document.body.removeEventListener('click', this._handleTriggerClick);
|
113
|
+
}
|
114
|
+
this.$overlay[0].removeEventListener('click', this._handleOverlayClickBound);
|
115
|
+
this.el.removeEventListener('click', this._handleModalCloseClickBound);
|
116
|
+
}
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Handle Trigger Click
|
120
|
+
* @param {Event} e
|
121
|
+
*/
|
122
|
+
_handleTriggerClick(e) {
|
123
|
+
let $trigger = $(e.target).closest('.modal-trigger');
|
124
|
+
if ($trigger.length) {
|
125
|
+
let modalId = M.getIdFromTrigger($trigger[0]);
|
126
|
+
let modalInstance = document.getElementById(modalId).M_Modal;
|
127
|
+
if (modalInstance) {
|
128
|
+
modalInstance.open($trigger);
|
129
|
+
}
|
130
|
+
e.preventDefault();
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Handle Overlay Click
|
136
|
+
*/
|
137
|
+
_handleOverlayClick() {
|
138
|
+
if (this.options.dismissible) {
|
139
|
+
this.close();
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Handle Modal Close Click
|
145
|
+
* @param {Event} e
|
146
|
+
*/
|
147
|
+
_handleModalCloseClick(e) {
|
148
|
+
let $closeTrigger = $(e.target).closest('.modal-close');
|
149
|
+
if ($closeTrigger.length) {
|
150
|
+
this.close();
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
/**
|
155
|
+
* Handle Keydown
|
156
|
+
* @param {Event} e
|
157
|
+
*/
|
158
|
+
_handleKeydown(e) {
|
159
|
+
// ESC key
|
160
|
+
if (e.keyCode === 27 && this.options.dismissible) {
|
161
|
+
this.close();
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
/**
|
166
|
+
* Handle Focus
|
167
|
+
* @param {Event} e
|
168
|
+
*/
|
169
|
+
_handleFocus(e) {
|
170
|
+
// Only trap focus if this modal is the last model opened (prevents loops in nested modals).
|
171
|
+
if (!this.el.contains(e.target) && this._nthModalOpened === Modal._modalsOpen) {
|
172
|
+
this.el.focus();
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
/**
|
177
|
+
* Animate in modal
|
178
|
+
*/
|
179
|
+
_animateIn() {
|
180
|
+
// Set initial styles
|
181
|
+
$.extend(this.el.style, {
|
182
|
+
display: 'block',
|
183
|
+
opacity: 0
|
184
|
+
});
|
185
|
+
$.extend(this.$overlay[0].style, {
|
186
|
+
display: 'block',
|
187
|
+
opacity: 0
|
188
|
+
});
|
189
|
+
|
190
|
+
// Animate overlay
|
191
|
+
anim({
|
192
|
+
targets: this.$overlay[0],
|
193
|
+
opacity: this.options.opacity,
|
194
|
+
duration: this.options.inDuration,
|
195
|
+
easing: 'easeOutQuad'
|
196
|
+
});
|
197
|
+
|
198
|
+
// Define modal animation options
|
199
|
+
let enterAnimOptions = {
|
200
|
+
targets: this.el,
|
201
|
+
duration: this.options.inDuration,
|
202
|
+
easing: 'easeOutCubic',
|
203
|
+
// Handle modal onOpenEnd callback
|
204
|
+
complete: () => {
|
205
|
+
if (typeof this.options.onOpenEnd === 'function') {
|
206
|
+
this.options.onOpenEnd.call(this, this.el, this._openingTrigger);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
};
|
210
|
+
|
211
|
+
// Bottom sheet animation
|
212
|
+
if (this.el.classList.contains('bottom-sheet')) {
|
213
|
+
$.extend(enterAnimOptions, {
|
214
|
+
bottom: 0,
|
215
|
+
opacity: 1
|
216
|
+
});
|
217
|
+
anim(enterAnimOptions);
|
218
|
+
|
219
|
+
// Normal modal animation
|
220
|
+
} else {
|
221
|
+
$.extend(enterAnimOptions, {
|
222
|
+
top: [this.options.startingTop, this.options.endingTop],
|
223
|
+
opacity: 1,
|
224
|
+
scaleX: [0.8, 1],
|
225
|
+
scaleY: [0.8, 1]
|
226
|
+
});
|
227
|
+
anim(enterAnimOptions);
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
/**
|
232
|
+
* Animate out modal
|
233
|
+
*/
|
234
|
+
_animateOut() {
|
235
|
+
// Animate overlay
|
236
|
+
anim({
|
237
|
+
targets: this.$overlay[0],
|
238
|
+
opacity: 0,
|
239
|
+
duration: this.options.outDuration,
|
240
|
+
easing: 'easeOutQuart'
|
241
|
+
});
|
242
|
+
|
243
|
+
// Define modal animation options
|
244
|
+
let exitAnimOptions = {
|
245
|
+
targets: this.el,
|
246
|
+
duration: this.options.outDuration,
|
247
|
+
easing: 'easeOutCubic',
|
248
|
+
// Handle modal ready callback
|
249
|
+
complete: () => {
|
250
|
+
this.el.style.display = 'none';
|
251
|
+
this.$overlay.remove();
|
252
|
+
|
253
|
+
// Call onCloseEnd callback
|
254
|
+
if (typeof this.options.onCloseEnd === 'function') {
|
255
|
+
this.options.onCloseEnd.call(this, this.el);
|
256
|
+
}
|
257
|
+
}
|
258
|
+
};
|
259
|
+
|
260
|
+
// Bottom sheet animation
|
261
|
+
if (this.el.classList.contains('bottom-sheet')) {
|
262
|
+
$.extend(exitAnimOptions, {
|
263
|
+
bottom: '-100%',
|
264
|
+
opacity: 0
|
265
|
+
});
|
266
|
+
anim(exitAnimOptions);
|
267
|
+
|
268
|
+
// Normal modal animation
|
269
|
+
} else {
|
270
|
+
$.extend(exitAnimOptions, {
|
271
|
+
top: [this.options.endingTop, this.options.startingTop],
|
272
|
+
opacity: 0,
|
273
|
+
scaleX: 0.8,
|
274
|
+
scaleY: 0.8
|
275
|
+
});
|
276
|
+
anim(exitAnimOptions);
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
/**
|
281
|
+
* Open Modal
|
282
|
+
* @param {cash} [$trigger]
|
283
|
+
*/
|
284
|
+
open($trigger) {
|
285
|
+
if (this.isOpen) {
|
286
|
+
return;
|
287
|
+
}
|
288
|
+
|
289
|
+
this.isOpen = true;
|
290
|
+
Modal._modalsOpen++;
|
291
|
+
this._nthModalOpened = Modal._modalsOpen;
|
292
|
+
|
293
|
+
// Set Z-Index based on number of currently open modals
|
294
|
+
this.$overlay[0].style.zIndex = 1000 + Modal._modalsOpen * 2;
|
295
|
+
this.el.style.zIndex = 1000 + Modal._modalsOpen * 2 + 1;
|
296
|
+
|
297
|
+
// Set opening trigger, undefined indicates modal was opened by javascript
|
298
|
+
this._openingTrigger = !!$trigger ? $trigger[0] : undefined;
|
299
|
+
|
300
|
+
// onOpenStart callback
|
301
|
+
if (typeof this.options.onOpenStart === 'function') {
|
302
|
+
this.options.onOpenStart.call(this, this.el, this._openingTrigger);
|
303
|
+
}
|
304
|
+
|
305
|
+
if (this.options.preventScrolling) {
|
306
|
+
document.body.style.overflow = 'hidden';
|
307
|
+
}
|
308
|
+
|
309
|
+
this.el.classList.add('open');
|
310
|
+
this.el.insertAdjacentElement('afterend', this.$overlay[0]);
|
311
|
+
|
312
|
+
if (this.options.dismissible) {
|
313
|
+
this._handleKeydownBound = this._handleKeydown.bind(this);
|
314
|
+
this._handleFocusBound = this._handleFocus.bind(this);
|
315
|
+
document.addEventListener('keydown', this._handleKeydownBound);
|
316
|
+
document.addEventListener('focus', this._handleFocusBound, true);
|
317
|
+
}
|
318
|
+
|
319
|
+
anim.remove(this.el);
|
320
|
+
anim.remove(this.$overlay[0]);
|
321
|
+
this._animateIn();
|
322
|
+
|
323
|
+
// Focus modal
|
324
|
+
this.el.focus();
|
325
|
+
|
326
|
+
return this;
|
327
|
+
}
|
328
|
+
|
329
|
+
/**
|
330
|
+
* Close Modal
|
331
|
+
*/
|
332
|
+
close() {
|
333
|
+
if (!this.isOpen) {
|
334
|
+
return;
|
335
|
+
}
|
336
|
+
|
337
|
+
this.isOpen = false;
|
338
|
+
Modal._modalsOpen--;
|
339
|
+
this._nthModalOpened = 0;
|
340
|
+
|
341
|
+
// Call onCloseStart callback
|
342
|
+
if (typeof this.options.onCloseStart === 'function') {
|
343
|
+
this.options.onCloseStart.call(this, this.el);
|
344
|
+
}
|
345
|
+
|
346
|
+
this.el.classList.remove('open');
|
347
|
+
|
348
|
+
// Enable body scrolling only if there are no more modals open.
|
349
|
+
if (Modal._modalsOpen === 0) {
|
350
|
+
document.body.style.overflow = '';
|
351
|
+
}
|
352
|
+
|
353
|
+
if (this.options.dismissible) {
|
354
|
+
document.removeEventListener('keydown', this._handleKeydownBound);
|
355
|
+
document.removeEventListener('focus', this._handleFocusBound, true);
|
356
|
+
}
|
357
|
+
|
358
|
+
anim.remove(this.el);
|
359
|
+
anim.remove(this.$overlay[0]);
|
360
|
+
this._animateOut();
|
361
|
+
return this;
|
362
|
+
}
|
363
|
+
}
|
364
|
+
|
365
|
+
/**
|
366
|
+
* @static
|
367
|
+
* @memberof Modal
|
368
|
+
*/
|
369
|
+
Modal._modalsOpen = 0;
|
370
|
+
|
371
|
+
/**
|
372
|
+
* @static
|
373
|
+
* @memberof Modal
|
374
|
+
*/
|
375
|
+
Modal._count = 0;
|
376
|
+
|
377
|
+
M.Modal = Modal;
|
378
|
+
|
379
|
+
if (M.jQueryLoaded) {
|
380
|
+
M.initializeJqueryWrapper(Modal, 'modal', 'M_Modal');
|
381
|
+
}
|
382
|
+
})(cash, M.anime);
|
@@ -0,0 +1,138 @@
|
|
1
|
+
(function($) {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
let _defaults = {
|
5
|
+
responsiveThreshold: 0 // breakpoint for swipeable
|
6
|
+
};
|
7
|
+
|
8
|
+
class Parallax extends Component {
|
9
|
+
constructor(el, options) {
|
10
|
+
super(Parallax, el, options);
|
11
|
+
|
12
|
+
this.el.M_Parallax = this;
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Options for the Parallax
|
16
|
+
* @member Parallax#options
|
17
|
+
* @prop {Number} responsiveThreshold
|
18
|
+
*/
|
19
|
+
this.options = $.extend({}, Parallax.defaults, options);
|
20
|
+
this._enabled = window.innerWidth > this.options.responsiveThreshold;
|
21
|
+
|
22
|
+
this.$img = this.$el.find('img').first();
|
23
|
+
this.$img.each(function() {
|
24
|
+
let el = this;
|
25
|
+
if (el.complete) $(el).trigger('load');
|
26
|
+
});
|
27
|
+
|
28
|
+
this._updateParallax();
|
29
|
+
this._setupEventHandlers();
|
30
|
+
this._setupStyles();
|
31
|
+
|
32
|
+
Parallax._parallaxes.push(this);
|
33
|
+
}
|
34
|
+
|
35
|
+
static get defaults() {
|
36
|
+
return _defaults;
|
37
|
+
}
|
38
|
+
|
39
|
+
static init(els, options) {
|
40
|
+
return super.init(this, els, options);
|
41
|
+
}
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Get Instance
|
45
|
+
*/
|
46
|
+
static getInstance(el) {
|
47
|
+
let domElem = !!el.jquery ? el[0] : el;
|
48
|
+
return domElem.M_Parallax;
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Teardown component
|
53
|
+
*/
|
54
|
+
destroy() {
|
55
|
+
Parallax._parallaxes.splice(Parallax._parallaxes.indexOf(this), 1);
|
56
|
+
this.$img[0].style.transform = '';
|
57
|
+
this._removeEventHandlers();
|
58
|
+
|
59
|
+
this.$el[0].M_Parallax = undefined;
|
60
|
+
}
|
61
|
+
|
62
|
+
static _handleScroll() {
|
63
|
+
for (let i = 0; i < Parallax._parallaxes.length; i++) {
|
64
|
+
let parallaxInstance = Parallax._parallaxes[i];
|
65
|
+
parallaxInstance._updateParallax.call(parallaxInstance);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
static _handleWindowResize() {
|
70
|
+
for (let i = 0; i < Parallax._parallaxes.length; i++) {
|
71
|
+
let parallaxInstance = Parallax._parallaxes[i];
|
72
|
+
parallaxInstance._enabled =
|
73
|
+
window.innerWidth > parallaxInstance.options.responsiveThreshold;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
_setupEventHandlers() {
|
78
|
+
this._handleImageLoadBound = this._handleImageLoad.bind(this);
|
79
|
+
this.$img[0].addEventListener('load', this._handleImageLoadBound);
|
80
|
+
|
81
|
+
if (Parallax._parallaxes.length === 0) {
|
82
|
+
Parallax._handleScrollThrottled = M.throttle(Parallax._handleScroll, 5);
|
83
|
+
window.addEventListener('scroll', Parallax._handleScrollThrottled);
|
84
|
+
|
85
|
+
Parallax._handleWindowResizeThrottled = M.throttle(Parallax._handleWindowResize, 5);
|
86
|
+
window.addEventListener('resize', Parallax._handleWindowResizeThrottled);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
_removeEventHandlers() {
|
91
|
+
this.$img[0].removeEventListener('load', this._handleImageLoadBound);
|
92
|
+
|
93
|
+
if (Parallax._parallaxes.length === 0) {
|
94
|
+
window.removeEventListener('scroll', Parallax._handleScrollThrottled);
|
95
|
+
window.removeEventListener('resize', Parallax._handleWindowResizeThrottled);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
_setupStyles() {
|
100
|
+
this.$img[0].style.opacity = 1;
|
101
|
+
}
|
102
|
+
|
103
|
+
_handleImageLoad() {
|
104
|
+
this._updateParallax();
|
105
|
+
}
|
106
|
+
|
107
|
+
_updateParallax() {
|
108
|
+
let containerHeight = this.$el.height() > 0 ? this.el.parentNode.offsetHeight : 500;
|
109
|
+
let imgHeight = this.$img[0].offsetHeight;
|
110
|
+
let parallaxDist = imgHeight - containerHeight;
|
111
|
+
let bottom = this.$el.offset().top + containerHeight;
|
112
|
+
let top = this.$el.offset().top;
|
113
|
+
let scrollTop = M.getDocumentScrollTop();
|
114
|
+
let windowHeight = window.innerHeight;
|
115
|
+
let windowBottom = scrollTop + windowHeight;
|
116
|
+
let percentScrolled = (windowBottom - top) / (containerHeight + windowHeight);
|
117
|
+
let parallax = parallaxDist * percentScrolled;
|
118
|
+
|
119
|
+
if (!this._enabled) {
|
120
|
+
this.$img[0].style.transform = '';
|
121
|
+
} else if (bottom > scrollTop && top < scrollTop + windowHeight) {
|
122
|
+
this.$img[0].style.transform = `translate3D(-50%, ${parallax}px, 0)`;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* @static
|
129
|
+
* @memberof Parallax
|
130
|
+
*/
|
131
|
+
Parallax._parallaxes = [];
|
132
|
+
|
133
|
+
M.Parallax = Parallax;
|
134
|
+
|
135
|
+
if (M.jQueryLoaded) {
|
136
|
+
M.initializeJqueryWrapper(Parallax, 'parallax', 'M_Parallax');
|
137
|
+
}
|
138
|
+
})(cash);
|