| | var Sakura = function Sakura(selector, options) { |
| | var _this = this; |
| |
|
| | if (typeof selector === 'undefined') { |
| | throw new Error('No selector present. Define an element.'); |
| | } |
| |
|
| | this.el = document.querySelector(selector); |
| |
|
| | var defaults = { |
| | className: 'sakura', |
| | |
| | fallSpeed: 1, |
| | |
| | maxSize: 14, |
| | |
| | minSize: 10, |
| | |
| | delay: 300, |
| | |
| | gradientColorStart: 'rgba(255, 183, 197, 0.9)', |
| | |
| | gradientColorEnd: 'rgba(255, 197, 208, 0.9)', |
| | |
| | gradientColorDegree: 120 |
| |
|
| | }; |
| |
|
| | var extend = function extend(originalObj, newObj) { |
| | Object.keys(originalObj).forEach(function (key) { |
| | if (newObj && Object.prototype.hasOwnProperty.call(newObj, key)) { |
| | var origin = originalObj; |
| | origin[key] = newObj[key]; |
| | } |
| | }); |
| | return originalObj; |
| | }; |
| |
|
| | this.settings = extend(defaults, options); |
| |
|
| | this.el.style.overflowX = 'hidden'; |
| |
|
| | function randomArrayElem(arr) { |
| | return arr[Math.floor(Math.random() * arr.length)]; |
| | } |
| |
|
| |
|
| | function randomInt(min, max) { |
| | return Math.floor(Math.random() * (max - min + 1)) + min; |
| | } |
| |
|
| |
|
| | var prefixes = ['webkit', 'moz', 'MS', 'o', '']; |
| |
|
| | function PrefixedEvent(element, type, callback) { |
| | for (var p = 0; p < prefixes.length; p += 1) { |
| | var animType = type; |
| |
|
| | if (!prefixes[p]) { |
| | animType = type.toLowerCase(); |
| | } |
| |
|
| | element.addEventListener(prefixes[p] + animType, callback, false); |
| | } |
| | } |
| |
|
| |
|
| | function elementInViewport(el) { |
| | var rect = el.getBoundingClientRect(); |
| | return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth); |
| | } |
| |
|
| | this.createPetal = function () { |
| | if (_this.el.dataset.sakuraAnimId) { |
| | setTimeout(function () { |
| | window.requestAnimationFrame(_this.createPetal); |
| | }, _this.settings.delay); |
| | } |
| |
|
| |
|
| | var animationNames = { |
| | blowAnimations: ['blow-soft-left', 'blow-medium-left', 'blow-soft-right', 'blow-medium-right'], |
| | swayAnimations: ['sway-0', 'sway-1', 'sway-2', 'sway-3', 'sway-4', 'sway-5', 'sway-6', 'sway-7', 'sway-8'] |
| | }; |
| |
|
| | var blowAnimation = randomArrayElem(animationNames.blowAnimations); |
| | var swayAnimation = randomArrayElem(animationNames.swayAnimations); |
| |
|
| | var fallTime = (document.documentElement.clientHeight * 0.007 + Math.round(Math.random() * 5)) * _this.settings.fallSpeed; |
| |
|
| |
|
| | var animationsArr = ["fall ".concat(fallTime, "s linear 0s 1"), "".concat(blowAnimation, " ").concat((fallTime > 30 ? fallTime : 30) - 20 + randomInt(0, 20), "s linear 0s infinite"), "".concat(swayAnimation, " ").concat(randomInt(2, 4), "s linear 0s infinite")]; |
| | var animations = animationsArr.join(', '); |
| |
|
| | var petal = document.createElement('div'); |
| | petal.classList.add(_this.settings.className); |
| | var height = randomInt(_this.settings.minSize, _this.settings.maxSize); |
| | var width = height - Math.floor(randomInt(0, _this.settings.minSize) / 3); |
| | petal.style.background = "linear-gradient(".concat(_this.settings.gradientColorDegree, "deg, ").concat(_this.settings.gradientColorStart, ", ").concat(_this.settings.gradientColorEnd, ")"); |
| | petal.style.webkitAnimation = animations; |
| | petal.style.animation = animations; |
| | petal.style.borderRadius = "".concat(randomInt(_this.settings.maxSize, _this.settings.maxSize + Math.floor(Math.random() * 10)), "px ").concat(randomInt(1, Math.floor(width / 4)), "px"); |
| | petal.style.height = "".concat(height, "px"); |
| | petal.style.left = "".concat(Math.random() * document.documentElement.clientWidth - 100, "px"); |
| | petal.style.marginTop = "".concat(-(Math.floor(Math.random() * 20) + 15), "px"); |
| | petal.style.width = "".concat(width, "px"); |
| |
|
| | PrefixedEvent(petal, 'AnimationEnd', function () { |
| | if (!elementInViewport(petal)) { |
| | petal.remove(); |
| | } |
| | }); |
| |
|
| | PrefixedEvent(petal, 'AnimationIteration', function () { |
| | if (!elementInViewport(petal)) { |
| | petal.remove(); |
| | } |
| | }); |
| |
|
| | _this.el.appendChild(petal); |
| | }; |
| |
|
| | this.el.setAttribute('data-sakura-anim-id', window.requestAnimationFrame(this.createPetal)); |
| | }; |
| |
|
| | Sakura.prototype.start = function () { |
| | var animId = this.el.dataset.sakuraAnimId; |
| |
|
| | if (!animId) { |
| | this.el.setAttribute('data-sakura-anim-id', window.requestAnimationFrame(this.createPetal)); |
| | } else { |
| | throw new Error('Sakura is already running.'); |
| | } |
| | }; |
| |
|
| | Sakura.prototype.stop = function () { |
| | var _this2 = this; |
| |
|
| | var graceful = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; |
| | var animId = this.el.dataset.sakuraAnimId; |
| |
|
| | if (animId) { |
| | window.cancelAnimationFrame(animId); |
| | this.el.setAttribute('data-sakura-anim-id', ''); |
| | } |
| | |
| | |
| |
|
| |
|
| | if (!graceful) { |
| | setTimeout(function () { |
| | var petals = document.getElementsByClassName(_this2.settings.className); |
| |
|
| | while (petals.length > 0) { |
| | petals[0].parentNode.removeChild(petals[0]); |
| | } |
| | }, this.settings.delay + 50); |
| | } |
| | }; |