PageSourceSearch

https://i3simulations.com/wp-content/plugins/exclusive-addons-elem…/assets/js/vendor/granim.min.js?ver=1.5.6

js i3simulations.com collected 2026-10-05 19:21:50 UTC 33,183 bytes, 1,053 lines download raw bytes

vendor: 33,183 bytes, lines 1-1053
1/*! Granim v2.0.0 - https://sarcadass.github.io/granim.js */
2(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
3'use strict';
4
5function Granim(options) {
6	this.getElement(options.element);
7	this.x1 = 0;
8	this.y1 = 0;
9	this.name = options.name || false;
10	this.elToSetClassOn = options.elToSetClassOn || 'body';
11	this.direction = options.direction || 'diagonal';
12	this.customDirection = options.customDirection || {};
13	this.validateInput('direction');
14	this.isPausedWhenNotInView = options.isPausedWhenNotInView || false;
15	this.states = options.states;
16	this.stateTransitionSpeed = options.stateTransitionSpeed || 1000;
17	this.previousTimeStamp = null;
18	this.progress = 0;
19	this.isPaused = false;
20	this.isCleared = false;
21	this.isPausedBecauseNotInView = false;
22	this.context = this.canvas.getContext('2d');
23	this.channels = {};
24	this.channelsIndex = 0;
25	this.activeState = options.defaultStateName || 'default-state';
26	this.isChangingState = false;
27	this.currentColors = [];
28	this.currentColorsPos = [];
29	this.activetransitionSpeed = null;
30	this.eventPolyfill();
31	this.scrollDebounceThreshold = options.scrollDebounceThreshold || 300;
32	this.scrollDebounceTimeout = null;
33	this.isImgLoaded = false;
34	this.isCanvasInWindowView = false;
35	this.firstScrollInit = true;
36	this.animating = false;
37	this.gradientLength = this.states[this.activeState].gradients[0].length;
38	if (options.image && options.image.source) {
39		this.image = {
40			source: options.image.source,
41			position: options.image.position || ['center', 'center'],
42			stretchMode: options.image.stretchMode || false,
43			blendingMode: options.image.blendingMode || false
44		};
45	}
46	this.events = {
47		start: new CustomEvent('granim:start'),
48		end: new CustomEvent('granim:end'),
49		gradientChange: function(details) {
50			return new CustomEvent('granim:gradientChange', {
51				detail: {
52					isLooping: details.isLooping,
53					colorsFrom: details.colorsFrom,
54					colorsTo: details.colorsTo,
55					activeState: details.activeState
56				},
57				bubbles: false,
58				cancelable: false
59			});
60		}
61	};
62	this.callbacks = {
63		onStart: typeof options.onStart === 'function' ? options.onStart : false,
64		onGradientChange: typeof options.onGradientChange === 'function' ?
65			options.onGradientChange :
66			false,
67		onEnd: typeof options.onEnd === 'function' ? options.onEnd : false
68	};
69	this.getDimensions();
70	this.canvas.setAttribute('width', this.x1);
71	this.canvas.setAttribute('height', this.y1);
72	this.setColors();
73
74	if (this.image) {
75		this.validateInput('image');
76		this.prepareImage();
77	}
78
79	this.pauseWhenNotInViewNameSpace = this.pauseWhenNotInView.bind(this);
80	this.setSizeAttributesNameSpace = this.setSizeAttributes.bind(this);
81	this.onResize();
82
83	if (this.isPausedWhenNotInView) {
84		this.onScroll();
85		
86	} else {
87		if (!this.image) {
88			this.refreshColorsAndPos();
89			this.animation = requestAnimationFrame(this.animateColors.bind(this));
90			this.animating = true;
91		}
92	}
93
94	// Callback and Event
95	if (this.callbacks.onStart) this.callbacks.onStart();
96	this.canvas.dispatchEvent(this.events.start);
97}
98
99Granim.prototype.animateColors = require('./animateColors.js');
100Granim.prototype.changeBlendingMode = require('./changeBlendingMode.js');
101Granim.prototype.changeDirection = require('./changeDirection.js');
102Granim.prototype.changeState = require('./changeState.js');
103Granim.prototype.clear = require('./clear.js');
104Granim.prototype.convertColorToRgba = require('./convertColorToRgba.js');
105Granim.prototype.destroy = require('./destroy.js');
106Granim.prototype.eventPolyfill = require('./eventPolyfill.js');
107Granim.prototype.getColor = require('./getColor.js');
108Granim.prototype.getColorDiff = require('./getColorDiff.js');
109Granim.prototype.getColorPos = require('./getColorPos.js');
110Granim.prototype.getColorPosDiff = require('./getColorPosDiff.js');
111Granim.prototype.getCurrentColors = require('./getCurrentColors.js');
112Granim.prototype.getCurrentColorsPos = require('./getCurrentColorsPos.js');
113Granim.prototype.getDimensions = require('./getDimensions.js');
114Granim.prototype.getElement = require('./getElement.js');
115Granim.prototype.getLightness = require('./getLightness.js');
116Granim.prototype.makeGradient = require('./makeGradient.js');
117Granim.prototype.onResize = require('./onResize.js');
118Granim.prototype.onScroll = require('./onScroll.js');
119Granim.prototype.pause = require('./pause.js');
120Granim.prototype.pauseWhenNotInView = require('./pauseWhenNotInView.js');
121Granim.prototype.play = require('./play.js');
122Granim.prototype.prepareImage = require('./prepareImage.js');
123Granim.prototype.refreshColorsAndPos = require('./refreshColorsAndPos.js');
124Granim.prototype.setColors = require('./setColors.js');
125Granim.prototype.setDirection = require('./setDirection.js');
126Granim.prototype.setSizeAttributes = require('./setSizeAttributes.js');
127Granim.prototype.triggerError = require('./triggerError.js');
128Granim.prototype.validateInput = require('./validateInput.js');
129
130module.exports = Granim;
131
132},{"./animateColors.js":2,"./changeBlendingMode.js":3,"./changeDirection.js":4,"./changeState.js":5,"./clear.js":6,"./convertColorToRgba.js":7,"./destroy.js":8,"./eventPolyfill.js":9,"./getColor.js":10,"./getColorDiff.js":11,"./getColorPos.js":12,"./getColorPosDiff.js":13,"./getCurrentColors.js":14,"./getCurrentColorsPos.js":15,"./getDimensions.js":16,"./getElement.js":17,"./getLightness.js":18,"./makeGradient.js":19,"./onResize.js":20,"./onScroll.js":21,"./pause.js":22,"./pauseWhenNotInView.js":23,"./play.js":24,"./prepareImage.js":25,"./refreshColorsAndPos.js":26,"./setColors.js":27,"./setDirection.js":28,"./setSizeAttributes.js":29,"./triggerError.js":30,"./validateInput.js":31}],2:[function(require,module,exports){
133'use strict';
134
135module.exports = function(timestamp) {
136	var wasWindowIdled = timestamp - this.previousTimeStamp > 100;
137	var isLoop = this.states[this.activeState].loop !== undefined ? this.states[this.activeState].loop : true;
138	var progressPercent, isLooping, nextGradient;
139
140	// If tab was inactive then resumed, reset the previous timestamp
141	if (this.previousTimeStamp === null || wasWindowIdled) {
142		this.previousTimeStamp = timestamp;
143	}
144
145	// Compute progress and save the timestamp
146	this.progress = this.progress + (timestamp - this.previousTimeStamp);
147	progressPercent = (this.progress / this.activetransitionSpeed * 100).toFixed(2);
148	this.previousTimeStamp = timestamp;
149
150	// Set the new gradient colors in a property
151	this.refreshColorsAndPos(progressPercent);
152
153	// Continue the animation or prepare for the next one
154	if (progressPercent < 100) {
155		this.animation = requestAnimationFrame(this.animateColors.bind(this));
156
157	} else {
158		// if the current animation index is inferior to the penultimate gradient
159		// or to the last gradient with the loop mode activated
160		if (this.channelsIndex < this.states[this.activeState].gradients.length - 2 || isLoop) {
161
162			// Set the active transition speed to the active state one after changing state
163			if (this.isChangingState) {
164				this.activetransitionSpeed = this.states[this.activeState].transitionSpeed || 5000;
165				this.isChangingState = false;
166			}
167
168			// Resetting properties
169			this.previousTimeStamp = null;
170			this.progress = 0;
171			this.channelsIndex++;
172			isLooping = false;
173
174			// If it's going to loop or if it's the transition after the loop
175			if (this.channelsIndex === this.states[this.activeState].gradients.length - 1) {
176				isLooping = true;
177				
178			} else if (this.channelsIndex === this.states[this.activeState].gradients.length) {
179				this.channelsIndex = 0;
180			}
181
182			// Checking the next gradient to send in args of an event and a callback
183			nextGradient = this.states[this.activeState].gradients[this.channelsIndex + 1] === undefined ?
184				this.states[this.activeState].gradients[0] :
185				this.states[this.activeState].gradients[this.channelsIndex + 1];
186
187			// Compute the colors for the transition and render a new frame
188			this.setColors();
189			this.animation = requestAnimationFrame(this.animateColors.bind(this));
190			
191			// Callback and Event
192			if (this.callbacks.onGradientChange) {
193				this.callbacks.onGradientChange({
194					isLooping: isLooping,
195					colorsFrom: this.states[this.activeState].gradients[this.channelsIndex],
196					colorsTo: nextGradient,
197					activeState: this.activeState
198				});
199			}
200
201			this.canvas.dispatchEvent(this.events.gradientChange({
202				isLooping: isLooping,
203				colorsFrom: this.states[this.activeState].gradients[this.channelsIndex],
204				colorsTo: nextGradient,
205				activeState: this.activeState
206			}));
207
208		// Else if it was the last gradient on the list and the loop mode is off
209		} else {
210			cancelAnimationFrame(this.animation);
211
212			// Callback and Event
213			if (this.callbacks.onEnd) this.callbacks.onEnd();
214			this.canvas.dispatchEvent(new CustomEvent('granim:end'));
215		}
216	}
217};
218
219},{}],3:[function(require,module,exports){
220'use strict';
221
222module.exports = function(newBlendingMode) {
223	this.context.clearRect(0, 0, this.x1, this.y1);
224	this.context.globalCompositeOperation =
225		this.image.blendingMode = newBlendingMode;
226	this.validateInput('blendingMode');
227	if (this.isPaused) this.refreshColorsAndPos();
228};
229
230},{}],4:[function(require,module,exports){
231'use strict';
232
233module.exports = function(newDirection) {
234	this.context.clearRect(0, 0, this.x1, this.y1);
235	this.direction = newDirection;
236	this.validateInput('direction');
237	if (this.isPaused) this.refreshColorsAndPos();
238};
239
240},{}],5:[function(require,module,exports){
241'use strict';
242
243module.exports = function(newState) {
244	var _this = this;
245
246	// Prevent transitioning to the same state
247	if (this.activeState === newState) {
248		return;
249	}
250
251	// Setting the good properties for the transition
252	if (!this.isPaused) {
253		this.isPaused = true;
254		this.pause();
255	}
256
257	this.channelsIndex = -1;
258	this.activetransitionSpeed = this.stateTransitionSpeed;
259	this.activeColorsDiff = [];
260	this.activeColorsPosDiff = [];
261	this.activeColors = this.getCurrentColors();
262	this.activeColorsPos = this.getCurrentColorsPos();
263	this.progress = 0;
264	this.previousTimeStamp = null;
265	this.isChangingState = true;
266
267	// Compute the gradient color and pos diff between the last frame gradient
268	// and the first one of the new state
269	this.states[newState].gradients[0].forEach(function(gradientColor, i, arr) {
270		var nextColors = _this.convertColorToRgba(_this.getColor(gradientColor));
271		var nextColorsPos = _this.getColorPos(gradientColor, i);
272		var colorDiff = _this.getColorDiff(_this.activeColors[i], nextColors);
273		var colorPosDiff = _this.getColorPosDiff(_this.activeColorsPos[i], nextColorsPos);
274		_this.activeColorsDiff.push(colorDiff);
275		_this.activeColorsPosDiff.push(colorPosDiff);
276	});
277
278	// Start the animation
279	this.activeState = newState;
280	this.play();
281};
282
283},{}],6:[function(require,module,exports){
284'use strict';
285
286module.exports = function() {
287	if (!this.isPaused) {
288		cancelAnimationFrame(this.animation);
289
290	} else {
291		this.isPaused = false;
292	}
293	this.isCleared = true;
294	this.context.clearRect(0, 0, this.x1, this.y1);
295};
296
297},{}],7:[function(require,module,exports){
298'use strict';
299
300var regex = {
301	hexa: /^#(?:[0-9a-fA-F]{3}){1,2}$/,
302	rgba: /^rgba\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3}), ?(.?\d{1,3})\)$/,
303	rgb: /^rgb\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)$/,
304	hsla: /^hsla\((\d{1,3}), ?(\d{1,3})%, ?(\d{1,3})%, ?(.?\d{1,3})\)$/,
305	hsl: /^hsl\((\d{1,3}), ?(\d{1,3})%, ?(\d{1,3})%\)$/
306}, match;
307
308module.exports = function(color) {
309	switch(identifyColorType(color)) {
310		default:
311			this.triggerError('colorType');
312
313		case 'hexa':
314			return hexToRgba(color);
315
316		case 'rgba':
317			return [
318				parseInt(match[1], 10),
319				parseInt(match[2], 10),
320				parseInt(match[3], 10),
321				parseFloat(match[4])
322			];
323
324		case 'rgb':
325			return [
326				parseInt(match[1], 10),
327				parseInt(match[2], 10),
328				parseInt(match[3], 10),
329				1
330			];
331
332		case 'hsla':
333			return hslaToRgb(
334				parseInt(match[1], 10) / 360,
335				parseInt(match[2], 10) / 100,
336				parseInt(match[3], 10) / 100,
337				parseFloat(match[4])
338			);
339
340		case 'hsl':
341			return hslaToRgb(
342				parseInt(match[1], 10) / 360,
343				parseInt(match[2], 10) / 100,
344				parseInt(match[3], 10) / 100,
345				1
346			);
347	}
348};
349
350function identifyColorType(color) {
351	var colorTypes = Object.keys(regex);
352	var i = 0;
353	for (i; i < colorTypes.length; i++) {
354		match = regex[colorTypes[i]].exec(color);
355		if (match) return colorTypes[i];
356	}
357	return false;
358}
359
360function hexToRgba(hex) {
361	// Expand shorthand form (e.g. '03F') to full form (e.g. '0033FF')
362	var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
363	hex = hex.replace(shorthandRegex, function(m, r, g, b) {
364		return r + r + g + g + b + b;
365	});
366	var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
367	return result ? [
368		parseInt(result[1], 16),
369		parseInt(result[2], 16),
370		parseInt(result[3], 16),
371		1
372	] : null;
373}
374
375function hue2rgb(p, q, t) {
376	if (t < 0) t += 1;
377	if (t > 1) t -= 1;
378	if (t < 1 / 6) return p + (q - p) * 6 * t;
379	if (t < 1 / 2) return q;
380	if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
381	return p;
382}
383
384function hslaToRgb(h, s, l, a) {
385	var r, g, b, q, p;
386	if (s === 0) {
387		r = g = b = l; // achromatic
388	} else {
389		q = l < 0.5 ? l * (1 + s) : l + s - l * s;
390		p = 2 * l - q;
391		r = hue2rgb(p, q, h + 1/3);
392		g = hue2rgb(p, q, h);
393		b = hue2rgb(p, q, h - 1/3);
394	}
395	return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a];
396}
397
398},{}],8:[function(require,module,exports){
399'use strict';
400
401module.exports = function() {
402	this.onResize('removeListeners');
403	this.onScroll('removeListeners');
404	this.clear();
405};
406
407},{}],9:[function(require,module,exports){
408'use strict';
409
410module.exports = function() {
411	if ( typeof window.CustomEvent === 'function' ) return;
412
413	function CustomEvent(event, params) {
414		params = params || { bubbles: false, cancelable: false, detail: undefined };
415		var evt = document.createEvent('CustomEvent');
416		evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
417		return evt;
418	}
419
420	CustomEvent.prototype = window.Event.prototype;
421
422	window.CustomEvent = CustomEvent;
423};
424
425},{}],10:[function(require,module,exports){
426'use strict';
427
428module.exports = function(gradientColor) {
429	if (typeof gradientColor === 'string') {
430		return gradientColor;
431
432	} else if (typeof gradientColor === 'object' && gradientColor.color) {
433		return gradientColor.color;
434
435	} else {
436		this.triggerError('gradient.color');
437	}
438};
439
440},{}],11:[function(require,module,exports){
441'use strict';
442
443module.exports = function(colorA, colorB) {
444	var i = 0;
445	var colorDiff = [];
446
447	for (i; i < 4; i++) {
448		colorDiff.push(colorB[i] - colorA[i]);
449	}
450
451	return colorDiff;
452};
453
454},{}],12:[function(require,module,exports){
455'use strict';
456
457module.exports = function(gradientColor, i) {
458	if (typeof gradientColor === 'object' && gradientColor.pos) {
459		return gradientColor.pos;
460
461	} else {
462		// Ensure first and last position to be 0 and 100
463		return parseFloat(!i ? 0 : ((1 / (this.gradientLength - 1)) * i).toFixed(2));
464	}
465};
466
467},{}],13:[function(require,module,exports){
468'use strict';
469
470module.exports = function(posA, posB) {
471	return posB - posA;
472};
473
474},{}],14:[function(require,module,exports){
475'use strict';
476
477module.exports = function() {
478	var i, j;
479	var currentColors = [];
480
481	for (i = 0; i < this.currentColors.length; i++) {
482		currentColors.push([]);
483
484		for (j = 0; j < 4; j++) {
485			currentColors[i].push(this.currentColors[i][j]);
486		}
487	}
488
489	// Return a deep copy of the current colors
490	return currentColors;
491};
492
493},{}],15:[function(require,module,exports){
494'use strict';
495
496module.exports = function() {
497	var currentColorsPos = [], i;
498
499	for (i = 0; i < this.currentColorsPos.length; i++) {
500		currentColorsPos.push(this.currentColorsPos[i]);
501	}
502
503	// Return a deep copy of the current colors
504	return currentColorsPos;
505};
506
507},{}],16:[function(require,module,exports){
508'use strict';
509
510module.exports = function() {
511	this.x1 = this.canvas.offsetWidth;
512	this.y1 = this.canvas.offsetHeight;
513};
514
515},{}],17:[function(require,module,exports){
516'use strict';
517
518module.exports = function(element) {
519	if (element instanceof HTMLCanvasElement) {
520		this.canvas = element;
521
522	} else if (typeof element === 'string') {
523		this.canvas = document.querySelector(element);
524
525	} else {
526		throw new Error('The element you used is neither a String, nor a HTMLCanvasElement');
527	}
528
529	if (!this.canvas) {
530		throw new Error('`' + element + '` could not be found in the DOM');
531	}
532};
533
534},{}],18:[function(require,module,exports){
535'use strict';
536
537module.exports = function() {
538	var currentColors = this.getCurrentColors();
539	var gradientAverage = null;
540	var lightnessAverage, i;
541	var colorsAverage = currentColors.map(function(el) {
542		// Compute the average lightness of each color
543		// in the current gradient
544		return Math.max(el[0], el[1], el[2]);
545	});
546
547	for (i = 0; i < colorsAverage.length; i++) {
548		// Add all the average lightness of each color
549		gradientAverage = gradientAverage === null ?
550			colorsAverage[i] : gradientAverage + colorsAverage[i];
551
552		if (i === colorsAverage.length - 1) {
553			// if it's the last lightness average
554			// divide it by the total length to
555			// have the global average lightness
556			lightnessAverage = Math.round(gradientAverage / (i + 1));
557		}
558	}
559
560	return lightnessAverage >= 128 ? 'light' : 'dark';
561};
562
563},{}],19:[function(require,module,exports){
564'use strict';
565
566module.exports = function() {
567	var gradient = this.setDirection();
568	var elToSetClassOnClass = document.querySelector(this.elToSetClassOn).classList;
569	var i = 0;
570	this.context.clearRect(0, 0, this.x1, this.y1);
571
572	if (this.image) {
573		this.context.drawImage(
574			this.imageNode,
575			this.imagePosition.x,
576			this.imagePosition.y,
577			this.imagePosition.width,
578			this.imagePosition.height
579		);
580	}
581
582	for (i; i < this.currentColors.length; i++) {
583		gradient.addColorStop(this.currentColorsPos[i], 'rgba(' +
584			this.currentColors[i][0] + ', ' +
585			this.currentColors[i][1] + ', ' +
586			this.currentColors[i][2] + ', ' +
587			this.currentColors[i][3] + ')'
588		);
589	}
590
591	if (this.name) {
592		if (this.getLightness() === 'light') {
593			elToSetClassOnClass.remove(this.name + '-dark');
594			elToSetClassOnClass.add(this.name + '-light');
595
596		} else {
597			elToSetClassOnClass.remove(this.name + '-light');
598			elToSetClassOnClass.add(this.name + '-dark');
599		}
600	}
601
602	this.context.fillStyle = gradient;
603	this.context.fillRect(0, 0, this.x1, this.y1);
604};
605
606},{}],20:[function(require,module,exports){
607'use strict';
608
609module.exports = function(type) {
610	if (type === 'removeListeners') {
611		window.removeEventListener('resize', this.setSizeAttributesNameSpace);
612		return;
613	}
614
615	window.addEventListener('resize', this.setSizeAttributesNameSpace);
616};
617
618},{}],21:[function(require,module,exports){
619'use strict';
620
621module.exports = function(type) {
622	if (type === 'removeListeners') {
623		window.removeEventListener('scroll', this.pauseWhenNotInViewNameSpace);
624		return;
625	}
626
627	window.addEventListener('scroll', this.pauseWhenNotInViewNameSpace);
628	this.pauseWhenNotInViewNameSpace();
629};
630
631},{}],22:[function(require,module,exports){
632'use strict';
633
634module.exports = function(state) {
635	var isPausedBecauseNotInView = state === 'isPausedBecauseNotInView';
636	if (this.isCleared) return;
637	if (!isPausedBecauseNotInView) this.isPaused = true;
638	cancelAnimationFrame(this.animation);
639	this.animating = false;
640};
641
642},{}],23:[function(require,module,exports){
643'use strict';
644
645module.exports = function() {
646	var _this = this;
647	if (this.scrollDebounceTimeout) clearTimeout(this.scrollDebounceTimeout);
648
649	this.scrollDebounceTimeout = setTimeout(function() {
650		var elPos = _this.canvas.getBoundingClientRect();
651		_this.isCanvasInWindowView = !(elPos.bottom < 0 || elPos.right < 0 ||
652			elPos.left > window.innerWidth || elPos.top > window.innerHeight);
653
654		if (_this.isCanvasInWindowView) {
655			if (!_this.isPaused || _this.firstScrollInit) {
656				if (_this.image && !_this.isImgLoaded) {return;}
657				_this.isPausedBecauseNotInView = false;
658				_this.play('isPlayedBecauseInView');
659				_this.firstScrollInit = false;
660			}
661
662		} else {
663			if (!_this.image && _this.firstScrollInit) {
664				_this.refreshColorsAndPos();
665				_this.firstScrollInit = false;
666			}
667
668			if (!_this.isPaused && !_this.isPausedBecauseNotInView) {
669				_this.isPausedBecauseNotInView = true;
670				_this.pause('isPausedBecauseNotInView');
671			}
672		}
673	}, this.scrollDebounceThreshold);
674};
675
676},{}],24:[function(require,module,exports){
677'use strict';
678
679module.exports = function(state) {
680	var isPlayedBecauseInView = state === 'isPlayedBecauseInView';
681	if (!isPlayedBecauseInView) this.isPaused = false;
682	this.isCleared = false;
683	if (!this.animating) {
684		this.animation = requestAnimationFrame(this.animateColors.bind(this));
685		this.animating = true;
686	}
687};
688
689},{}],25:[function(require,module,exports){
690'use strict';
691
692module.exports = function() {
693	var _this = this;
694
695	if (!this.imagePosition) {
696		this.imagePosition = { x: 0, y: 0, width: 0, height: 0 };
697	}
698
699	if (this.image.blendingMode) {
700		this.context.globalCompositeOperation = this.image.blendingMode;
701	}
702
703	if (this.imageNode) {
704		setImagePosition();
705		return;
706	}
707
708	this.imageNode = new Image();
709	this.imageNode.onerror = function() {
710		throw new Error('Granim: The image source is invalid.');
711	};
712	this.imageNode.onload = function() {
713		_this.imgOriginalWidth = _this.imageNode.width;
714		_this.imgOriginalHeight = _this.imageNode.height;
715		setImagePosition();
716		_this.refreshColorsAndPos();
717		if (!_this.isPausedWhenNotInView || _this.isCanvasInWindowView) {
718			_this.animation = requestAnimationFrame(_this.animateColors.bind(_this));
719		}
720		_this.isImgLoaded = true;
721	};
722	this.imageNode.src = this.image.source;
723
724	function setImagePosition() {
725		var i, currentAxis;
726
727		for (i = 0; i < 2; i++) {
728			currentAxis = !i ? 'x' : 'y';
729			setImageAxisPosition(currentAxis);
730		}
731
732		function setImageAxisPosition(axis) {
733			var canvasWidthOrHeight = _this[axis + '1'];
734			var imgOriginalWidthOrHeight = _this[axis === 'x' ? 'imgOriginalWidth' : 'imgOriginalHeight'];
735			var imageAlignIndex = axis === 'x' ? _this.image.position[0] : _this.image.position[1];
736			var imageAxisPosition;
737			switch(imageAlignIndex) {
738				case 'center':
739					imageAxisPosition = imgOriginalWidthOrHeight > canvasWidthOrHeight
740						? -(imgOriginalWidthOrHeight - canvasWidthOrHeight) / 2
741						: (canvasWidthOrHeight - imgOriginalWidthOrHeight) / 2;
742					_this.imagePosition[axis] = imageAxisPosition;
743					_this.imagePosition[axis === 'x' ? 'width' : 'height'] = imgOriginalWidthOrHeight;
744					break;
745
746				case 'top':
747					_this.imagePosition['y'] = 0;
748					_this.imagePosition['height'] = imgOriginalWidthOrHeight;
749					break;
750
751				case 'bottom':
752					_this.imagePosition['y'] = canvasWidthOrHeight - imgOriginalWidthOrHeight;
753					_this.imagePosition['height'] = imgOriginalWidthOrHeight;
754					break;
755
756				case 'right':
757					_this.imagePosition['x'] = canvasWidthOrHeight - imgOriginalWidthOrHeight;
758					_this.imagePosition['width'] = imgOriginalWidthOrHeight;
759					break;
760
761				case 'left':
762					_this.imagePosition['x'] = 0;
763					_this.imagePosition['width'] = imgOriginalWidthOrHeight;
764					break;
765			}
766
767			if (_this.image.stretchMode) {
768				imageAlignIndex = axis === 'x' ? _this.image.stretchMode[0] : _this.image.stretchMode[1];
769				switch(imageAlignIndex) {
770					case 'none':
771						break;
772					case 'stretch':
773						_this.imagePosition[axis] = 0;
774						_this.imagePosition[axis === 'x' ? 'width' : 'height'] = canvasWidthOrHeight;
775						break;
776
777					case 'stretch-if-bigger':
778						if (imgOriginalWidthOrHeight < canvasWidthOrHeight) break;
779						_this.imagePosition[axis] = 0;
780						_this.imagePosition[axis === 'x' ? 'width' : 'height'] = canvasWidthOrHeight;
781						break;
782
783					case 'stretch-if-smaller':
784						if (imgOriginalWidthOrHeight > canvasWidthOrHeight) break;
785						_this.imagePosition[axis] = 0;
786						_this.imagePosition[axis === 'x' ? 'width' : 'height'] = canvasWidthOrHeight;
787						break;
788				}
789			}
790		}
791	}
792};
793
794},{}],26:[function(require,module,exports){
795'use strict';
796
797module.exports = function(progressPercent) {
798	var _this = this, activeChannel, activeChannelPos, i, j;
799
800	// Loop through each colors of the active gradient
801	for (i = 0; i < this.activeColors.length; i++) {
802
803		// Generate RGBA colors
804		for (j = 0; j < 4; j++) {
805			// If color value [0-255] round to the integer,
806			// Else if opacity [0-1] round to 2 decimals
807			activeChannel = _this.activeColors[i][j] +
808				(j !== 3
809					? Math.ceil(_this.activeColorsDiff[i][j] / 100 * progressPercent)
810					: Math.round((_this.activeColorsDiff[i][j] / 100 * progressPercent) * 100) / 100
811				);
812
813			// Prevent colors values from going < 0 & > 255
814			if (activeChannel <= 255 && activeChannel >= 0) {
815				_this.currentColors[i][j] = activeChannel;
816			}
817		}
818
819		// Generate gradient color position
820		activeChannelPos = parseFloat((_this.activeColorsPos[i] +
821			(_this.activeColorsPosDiff[i] / 100 * progressPercent)
822		).toFixed(4));
823
824		if (activeChannelPos <= 1 && activeChannelPos >= 0) {
825			_this.currentColorsPos[i] = activeChannelPos;
826		}
827	}
828
829	this.makeGradient();
830};
831
832},{}],27:[function(require,module,exports){
833'use strict';
834
835module.exports = function() {
836	var _this = this, colorDiff, colorPosDiff, nextColors, nextColorsPos;
837
838	if (!this.channels[this.activeState]) this.channels[this.activeState] = [];
839
840	// If the actual channel exist, reassign properties and exit
841	// (each channel is saved to prevent recomputing it each time)
842	if (this.channels[this.activeState][this.channelsIndex] !== undefined) {
843		this.activeColors = this.channels[this.activeState][this.channelsIndex].colors;
844		this.activeColorsDiff = this.channels[this.activeState][this.channelsIndex].colorsDiff;
845		this.activeColorsPos = this.channels[this.activeState][this.channelsIndex].colorsPos;
846		this.activeColorsPosDiff = this.channels[this.activeState][this.channelsIndex].colorsPosDiff;
847		return;
848	}
849
850	// Set blank properties
851	this.channels[this.activeState].push([{}]);
852	this.channels[this.activeState][this.channelsIndex].colors = [];
853	this.channels[this.activeState][this.channelsIndex].colorsDiff = [];
854	this.channels[this.activeState][this.channelsIndex].colorsPos = [];
855	this.channels[this.activeState][this.channelsIndex].colorsPosDiff = [];
856	this.activeColors = [];
857	this.activeColorsDiff = [];
858	this.activeColorsPos = [];
859	this.activeColorsPosDiff = [];
860
861	// Go on each gradient of the current state
862	this.states[this.activeState].gradients[this.channelsIndex].forEach(function(color, i) {
863		// Push the hex color converted to rgba on the channel and the active color properties
864		var colorPos = _this.getColorPos(color, i);
865		var color = _this.getColor(color);
866		var rgbaColor = _this.convertColorToRgba(color);
867		var activeChannel = _this.channels[_this.activeState];
868
869		activeChannel[_this.channelsIndex].colors.push(rgbaColor);
870		_this.activeColors.push(rgbaColor);
871		activeChannel[_this.channelsIndex].colorsPos.push(colorPos);
872		_this.activeColorsPos.push(colorPos);
873
874		// If it's the first channel to be set, set the currentColors
875		if (!_this.isCurrentColorsSet) {
876			_this.currentColors.push(_this.convertColorToRgba(color));
877			_this.currentColorsPos.push(colorPos);
878		}
879
880		// If it's the last gradient, compute the color diff between the last gradient and the first one,
881		// else between the penultimate one and the last one
882		if (_this.channelsIndex === _this.states[_this.activeState].gradients.length - 1) {
883			colorDiff = _this.getColorDiff(
884				activeChannel[_this.channelsIndex].colors[i],
885				activeChannel[0].colors[i]
886			);
887			colorPosDiff = _this.getColorPosDiff(
888				activeChannel[_this.channelsIndex].colorsPos[i],
889				activeChannel[0].colorsPos[i]
890			);
891
892		} else {
893			nextColors = _this.convertColorToRgba(_this.getColor(_this.states[_this.activeState].gradients[_this.channelsIndex + 1][i]));
894			nextColorsPos = _this.getColorPos(_this.states[_this.activeState].gradients[_this.channelsIndex + 1][i], i);
895			colorDiff = _this.getColorDiff(activeChannel[_this.channelsIndex].colors[i], nextColors);
896			colorPosDiff = _this.getColorPosDiff(activeChannel[_this.channelsIndex].colorsPos[i], nextColorsPos);
897		}
898
899		activeChannel[_this.channelsIndex].colorsDiff.push(colorDiff);
900		_this.activeColorsDiff.push(colorDiff);
901		activeChannel[_this.channelsIndex].colorsPosDiff.push(colorPosDiff);
902		_this.activeColorsPosDiff.push(colorPosDiff);
903	});
904
905	this.activetransitionSpeed = this.states[this.activeState].transitionSpeed || 5000;
906	this.isCurrentColorsSet = true;
907};
908
909},{}],28:[function(require,module,exports){
910'use strict';
911
912module.exports = function() {
913	var ctx = this.context;
914
915	switch(this.direction) {
916		case 'diagonal':
917			return ctx.createLinearGradient(0, 0, this.x1, this.y1);
918
919		case 'left-right':
920			return ctx.createLinearGradient(0, 0, this.x1, 0);
921
922		case 'top-bottom':
923			return ctx.createLinearGradient(this.x1 / 2, 0, this.x1 / 2, this.y1);
924
925		case 'radial':
926			return ctx.createRadialGradient(this.x1 / 2, this.y1 / 2, this.x1 / 2, this.x1 / 2, this.y1 / 2, 0);
927
928		case 'custom':
929			return ctx.createLinearGradient(
930				getCustomCoordinateInPixels(this.customDirection.x0, this.x1),
931				getCustomCoordinateInPixels(this.customDirection.y0, this.y1),
932				getCustomCoordinateInPixels(this.customDirection.x1, this.x1),
933				getCustomCoordinateInPixels(this.customDirection.y1, this.y1)
934			);
935	}
936};
937
938function getCustomCoordinateInPixels(coordinate, size) {
939	return coordinate.indexOf('%') > -1
940		? size / 100 * parseInt(coordinate.split('%')[0], 10)
941		: parseInt(coordinate.split('px')[0], 10);
942}
943
944},{}],29:[function(require,module,exports){
945'use strict';
946
947module.exports = function() {
948	this.getDimensions();
949	this.canvas.setAttribute('width', this.x1);
950	this.canvas.setAttribute('height', this.y1);
951	if (this.image) this.prepareImage();
952	this.refreshColorsAndPos();
953};
954
955},{}],30:[function(require,module,exports){
956'use strict';
957
958module.exports = function(element) {
959	var siteURL = 'https://sarcadass.github.io/granim.js/api.html';
960	throw new Error('Granim: Input error on "' + element + '" option.\nCheck the API ' + siteURL + '.');
961};
962
963},{}],31:[function(require,module,exports){
964'use strict';
965
966module.exports = function(inputType) {
967	var xPositionValues = ['left', 'center', 'right'];
968	var yPositionValues = ['top', 'center', 'bottom'];
969	var stretchModeValues = ['none', 'stretch', 'stretch-if-smaller', 'stretch-if-bigger'];
970	var blendingModeValues = ['multiply', 'screen', 'normal', 'overlay', 'darken',
971		'lighten', 'lighter', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
972		'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'];
973	var directionValues = ['diagonal', 'left-right', 'top-bottom', 'radial', 'custom'];
974
975	switch(inputType) {
976		case 'image':
977			// Validate image.position
978			if ((!Array.isArray(this.image.position) || this.image.position.length !== 2) ||
979				xPositionValues.indexOf(this.image.position[0]) === -1 ||
980				yPositionValues.indexOf(this.image.position[1]) === -1
981			) { this.triggerError('image.position'); }
982			// Validate image.stretchMode
983			if (this.image.stretchMode) {
984				if ((!Array.isArray(this.image.stretchMode) || this.image.stretchMode.length !== 2) ||
985					stretchModeValues.indexOf(this.image.stretchMode[0]) === -1 ||
986					stretchModeValues.indexOf(this.image.stretchMode[1]) === -1
987				) { this.triggerError('image.stretchMode'); }
988			}
989			break;
990
991		case 'blendingMode':
992			if (blendingModeValues.indexOf(this.image.blendingMode) === -1) {
993				this.clear();
994				this.triggerError('blendingMode');
995			}
996			break;
997
998		case 'direction':
999			if (directionValues.indexOf(this.direction) === -1) {
1000				this.triggerError('direction');
1001			} else {
1002				if (this.direction === 'custom') {
1003					if (!areDefinedInPixelsOrPercentage([
1004						this.customDirection.x0,
1005						this.customDirection.x1,
1006						this.customDirection.y0,
1007						this.customDirection.y1
1008					])) {
1009						this.triggerError('customDirection');
1010					}
1011				}
1012			}
1013			break;
1014	}
1015};
1016
1017function areDefinedInPixelsOrPercentage(array) {
1018	var definedInPixelsOrPercentage = true, i = 0, value;
1019	while (definedInPixelsOrPercentage && i < array.length) {
1020		value = array[i];
1021		if (typeof value !== 'string') {
1022			definedInPixelsOrPercentage = false;
1023		} else {
1024			var splittedValue = null;
1025			var unit = null;
1026			if (value.indexOf('px') !== -1) unit = 'px';
1027			if (value.indexOf('%') !== -1) unit = '%';
1028			splittedValue = value.split(unit).filter(function(value) {
1029				return value.length > 0;
1030			});
1031			// Check if there is a unit ('px' or '%'),
1032			// a char before the unit,
1033			// no char after the unit,
1034			// the string without the unit is only composed of digits
1035			if (
1036				!unit
1037				|| splittedValue.length > 2
1038				|| !splittedValue[0]
1039				|| splittedValue[1]
1040				|| !/^-?\d+\.?\d*$/.test(splittedValue[0])
1041			) {
1042				definedInPixelsOrPercentage = false;
1043			}
1044		}
1045		i++;
1046	}
1047	return definedInPixelsOrPercentage;
1048}
1049
1050},{}],32:[function(require,module,exports){
1051window.Granim = require('./lib/Granim.js');
1052
1053},{"./lib/Granim.js":1}]},{},[32]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.