From c94fb32c7a3c28b18a27460aa2447eeec1fac1de Mon Sep 17 00:00:00 2001 From: Pascal Szewczyk Date: Mon, 18 Jul 2016 23:23:54 +0200 Subject: uikit added --- js/components/parallax.js | 462 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100755 js/components/parallax.js (limited to 'js/components/parallax.js') diff --git a/js/components/parallax.js b/js/components/parallax.js new file mode 100755 index 0000000..e706abb --- /dev/null +++ b/js/components/parallax.js @@ -0,0 +1,462 @@ +/*! UIkit 2.26.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ +(function(addon) { + + var component; + + if (window.UIkit) { + component = addon(UIkit); + } + + if (typeof define == "function" && define.amd) { + define("uikit-parallax", ["uikit"], function(){ + return component || addon(UIkit); + }); + } + +})(function(UI){ + + "use strict"; + + var parallaxes = [], + supports3d = false, + scrolltop = 0, + wh = window.innerHeight, + checkParallaxes = function() { + + scrolltop = UI.$win.scrollTop(); + + window.requestAnimationFrame(function(){ + for (var i=0; i < parallaxes.length; i++) { + parallaxes[i].process(); + } + }); + }; + + + UI.component('parallax', { + + defaults: { + velocity : 0.5, + target : false, + viewport : false, + media : false + }, + + boot: function() { + + supports3d = (function(){ + + var el = document.createElement('div'), + has3d, + transforms = { + 'WebkitTransform':'-webkit-transform', + 'MSTransform':'-ms-transform', + 'MozTransform':'-moz-transform', + 'Transform':'transform' + }; + + // Add it to the body to get the computed style. + document.body.insertBefore(el, null); + + for (var t in transforms) { + if (el.style[t] !== undefined) { + el.style[t] = "translate3d(1px,1px,1px)"; + has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); + } + } + + document.body.removeChild(el); + + return (has3d !== undefined && has3d.length > 0 && has3d !== "none"); + })(); + + // listen to scroll and resize + UI.$doc.on("scrolling.uk.document", checkParallaxes); + UI.$win.on("load resize orientationchange", UI.Utils.debounce(function(){ + wh = window.innerHeight; + checkParallaxes(); + }, 50)); + + // init code + UI.ready(function(context) { + + UI.$('[data-uk-parallax]', context).each(function() { + + var parallax = UI.$(this); + + if (!parallax.data("parallax")) { + UI.parallax(parallax, UI.Utils.options(parallax.attr("data-uk-parallax"))); + } + }); + }); + }, + + init: function() { + + this.base = this.options.target ? UI.$(this.options.target) : this.element; + this.props = {}; + this.velocity = (this.options.velocity || 1); + + var reserved = ['target','velocity','viewport','plugins','media']; + + Object.keys(this.options).forEach(function(prop){ + + if (reserved.indexOf(prop) !== -1) { + return; + } + + var start, end, dir, diff, startend = String(this.options[prop]).split(','); + + if (prop.match(/color/i)) { + start = startend[1] ? startend[0] : this._getStartValue(prop), + end = startend[1] ? startend[1] : startend[0]; + + if (!start) { + start = 'rgba(255,255,255,0)'; + } + + } else { + start = parseFloat(startend[1] ? startend[0] : this._getStartValue(prop)), + end = parseFloat(startend[1] ? startend[1] : startend[0]); + diff = (start < end ? (end-start):(start-end)); + dir = (start < end ? 1:-1); + } + + this.props[prop] = { 'start': start, 'end': end, 'dir': dir, 'diff': diff }; + + }.bind(this)); + + parallaxes.push(this); + }, + + process: function() { + + if (this.options.media) { + + switch(typeof(this.options.media)) { + case 'number': + if (window.innerWidth < this.options.media) { + return false; + } + break; + case 'string': + if (window.matchMedia && !window.matchMedia(this.options.media).matches) { + return false; + } + break; + } + } + + var percent = this.percentageInViewport(); + + if (this.options.viewport !== false) { + percent = (this.options.viewport === 0) ? 1 : percent / this.options.viewport; + } + + this.update(percent); + }, + + percentageInViewport: function() { + + var top = this.base.offset().top, + height = this.base.outerHeight(), + distance, percentage, percent; + + if (top > (scrolltop + wh)) { + percent = 0; + } else if ((top + height) < scrolltop) { + percent = 1; + } else { + + if ((top + height) < wh) { + + percent = (scrolltop < wh ? scrolltop : scrolltop - wh) / (top+height); + + } else { + + distance = (scrolltop + wh) - top; + percentage = Math.round(distance / ((wh + height) / 100)); + percent = percentage/100; + } + } + + return percent; + }, + + update: function(percent) { + + var $this = this, + css = {transform:'', filter:''}, + compercent = percent * (1 - (this.velocity - (this.velocity * percent))), + opts, val; + + if (compercent < 0) compercent = 0; + if (compercent > 1) compercent = 1; + + if (this._percent !== undefined && this._percent == compercent) { + return; + } + + Object.keys(this.props).forEach(function(prop) { + + opts = this.props[prop]; + + if (percent === 0) { + val = opts.start; + } else if(percent === 1) { + val = opts.end; + } else if(opts.diff !== undefined) { + val = opts.start + (opts.diff * compercent * opts.dir); + } + + if ((prop == 'bg' || prop == 'bgp') && !this._bgcover) { + this._bgcover = initBgImageParallax(this, prop, opts); + } + + switch(prop) { + + // transforms + case 'x': + css.transform += supports3d ? ' translate3d('+val+'px, 0, 0)':' translateX('+val+'px)'; + break; + case 'xp': + css.transform += supports3d ? ' translate3d('+val+'%, 0, 0)':' translateX('+val+'%)'; + break; + case 'y': + css.transform += supports3d ? ' translate3d(0, '+val+'px, 0)':' translateY('+val+'px)'; + break; + case 'yp': + css.transform += supports3d ? ' translate3d(0, '+val+'%, 0)':' translateY('+val+'%)'; + break; + case 'rotate': + css.transform += ' rotate('+val+'deg)'; + break; + case 'scale': + css.transform += ' scale('+val+')'; + break; + + // bg image + case 'bg': + + // don't move if image height is too small + // if ($this.element.data('bgsize') && ($this.element.data('bgsize').h + val - window.innerHeight) < 0) { + // break; + // } + + css['background-position'] = '50% '+val+'px'; + break; + case 'bgp': + css['background-position'] = '50% '+val+'%'; + break; + + // color + case 'color': + case 'background-color': + case 'border-color': + css[prop] = calcColor(opts.start, opts.end, compercent); + break; + + // CSS Filter + case 'blur': + css.filter += ' blur('+val+'px)'; + break; + case 'hue': + css.filter += ' hue-rotate('+val+'deg)'; + break; + case 'grayscale': + css.filter += ' grayscale('+val+'%)'; + break; + case 'invert': + css.filter += ' invert('+val+'%)'; + break; + case 'fopacity': + css.filter += ' opacity('+val+'%)'; + break; + case 'saturate': + css.filter += ' saturate('+val+'%)'; + break; + case 'sepia': + css.filter += ' sepia('+val+'%)'; + break; + + default: + css[prop] = val; + break; + } + + }.bind(this)); + + if (css.filter) { + css['-webkit-filter'] = css.filter; + } + + this.element.css(css); + + this._percent = compercent; + }, + + _getStartValue: function(prop) { + + var value = 0; + + switch(prop) { + case 'scale': + value = 1; + break; + default: + value = this.element.css(prop); + } + + return (value || 0); + } + + }); + + + // helper + + function initBgImageParallax(obj, prop, opts) { + + var img = new Image(), url, element, size, check, ratio, width, height; + + element = obj.element.css({'background-size': 'cover', 'background-repeat': 'no-repeat'}); + url = element.css('background-image').replace(/^url\(/g, '').replace(/\)$/g, '').replace(/("|')/g, ''); + check = function() { + + var w = element.innerWidth(), h = element.innerHeight(), extra = (prop=='bg') ? opts.diff : (opts.diff/100) * h; + + h += extra; + w += Math.ceil(extra * ratio); + + if (w-extra < size.w && h < size.h) { + return obj.element.css({'background-size': 'auto'}); + } + + // if element height < parent height (gap underneath) + if ((w / ratio) < h) { + + width = Math.ceil(h * ratio); + height = h; + + if (h > window.innerHeight) { + width = width * 1.2; + height = height * 1.2; + } + + // element width < parent width (gap to right) + } else { + + width = w; + height = Math.ceil(w / ratio); + } + + element.css({'background-size': (width+'px '+height+'px')}).data('bgsize', {w:width,h:height}); + }; + + img.onerror = function(){ + // image url doesn't exist + }; + + img.onload = function(){ + size = {w:img.width, h:img.height}; + ratio = img.width / img.height; + + UI.$win.on("load resize orientationchange", UI.Utils.debounce(function(){ + check(); + }, 50)); + + check(); + }; + + img.src = url; + + return true; + } + + + // Some named colors to work with, added by Bradley Ayers + // From Interface by Stefan Petre + // http://interface.eyecon.ro/ + var colors = { + 'black': [0,0,0,1], + 'blue': [0,0,255,1], + 'brown': [165,42,42,1], + 'cyan': [0,255,255,1], + 'fuchsia': [255,0,255,1], + 'gold': [255,215,0,1], + 'green': [0,128,0,1], + 'indigo': [75,0,130,1], + 'khaki': [240,230,140,1], + 'lime': [0,255,0,1], + 'magenta': [255,0,255,1], + 'maroon': [128,0,0,1], + 'navy': [0,0,128,1], + 'olive': [128,128,0,1], + 'orange': [255,165,0,1], + 'pink': [255,192,203,1], + 'purple': [128,0,128,1], + 'violet': [128,0,128,1], + 'red': [255,0,0,1], + 'silver': [192,192,192,1], + 'white': [255,255,255,1], + 'yellow': [255,255,0,1], + 'transparent': [255,255,255,0] + }; + + function calcColor(start, end, pos) { + + start = parseColor(start); + end = parseColor(end); + pos = pos || 0; + + return calculateColor(start, end, pos); + } + + /**! + * @preserve Color animation 1.6.0 + * http://www.bitstorm.org/jquery/color-animation/ + * Copyright 2011, 2013 Edwin Martin + * Released under the MIT and GPL licenses. + */ + + // Calculate an in-between color. Returns "#aabbcc"-like string. + function calculateColor(begin, end, pos) { + var color = 'rgba(' + + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ',' + + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ',' + + parseInt((begin[2] + pos * (end[2] - begin[2])), 10) + ',' + + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1); + + color += ')'; + return color; + } + + // Parse an CSS-syntax color. Outputs an array [r, g, b] + function parseColor(color) { + + var match, quadruplet; + + // Match #aabbcc + if (match = /#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})/.exec(color)) { + quadruplet = [parseInt(match[1], 16), parseInt(match[2], 16), parseInt(match[3], 16), 1]; + + // Match #abc + } else if (match = /#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/.exec(color)) { + quadruplet = [parseInt(match[1], 16) * 17, parseInt(match[2], 16) * 17, parseInt(match[3], 16) * 17, 1]; + + // Match rgb(n, n, n) + } else if (match = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) { + quadruplet = [parseInt(match[1]), parseInt(match[2]), parseInt(match[3]), 1]; + + } else if (match = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9\.]*)\s*\)/.exec(color)) { + quadruplet = [parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3], 10),parseFloat(match[4])]; + + // No browser returns rgb(n%, n%, n%), so little reason to support this format. + } else { + quadruplet = colors[color] || [255,255,255,0]; + } + return quadruplet; + } + + return UI.parallax; +}); -- cgit v1.2.3