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.