/* * Neighbor.js by OKFocus - http://okfoc.us - @okfocus * Version 1.0 * Licensed under MIT. * */ (function($){ $.neighbor = function(el, options){ var base = this; base.$el = $(el); base.el = el; base.$el.data("neighbor", base); var img; var active = true, hovering = false; var canvas, imageData = null; base.init = function(){ base.options = $.extend({}, $.neighbor.options, options); if (typeof base.options.scale == "string" && base.options.scale.indexOf("%") != -1) { base.options.scale = parseInt( base.options.scale.replace("%","") ) / 100; } var url = base.options.url || base.el.src; if (isCrossOrigin( url )) { Proxy.fetch( url, base.build ); } if (base.options.url) { img = new Image (); img.onload = base.load; img.src = base.options.url; } else { img = base.el; img.onload = base.load; if (img.complete) { base.build( img ); } } }; base.load = function(){ base.build( img ); } base.build = function( img ){ if (canvas) return; canvas = document.createElement("canvas"); var nw = canvas.width = img.naturalWidth; var nh = canvas.height = img.naturalHeight; var neighbor = document.createElement("canvas"); var w, h, scaleW, scaleH; if (base.options.scale) { w = neighbor.width = Math.floor( img.naturalWidth * base.options.scale ); h = neighbor.height = Math.floor( img.naturalHeight * base.options.scale ); } else { var bounds = img.getBoundingClientRect(); w = neighbor.width = bounds.width; h = neighbor.height = bounds.height; } scaleH = nh / h; scaleW = nw / w; var nctx = canvas.getContext( '2d' ); nctx.drawImage( img, 0, 0 ); nidd = nctx.getImageData( 0, 0, canvas.width, canvas.height ) nid = nidd.data; var ctx = neighbor.getContext('2d'); var idd = ctx.createImageData( w, h ); var id = idd.data; for (var i = 0; i <= w; i++) { for (var j = 0; j <= h; j++) { var y = Math.floor( j * scaleH ); var x = Math.floor( i * scaleW ); var np = (y * nw + x ) * 4; var p = (j * w + i ) * 4; id[ p ] = nid[ np ] id[ p+1 ] = nid[ np+1 ] id[ p+2 ] = nid[ np+2 ] id[ p+3 ] = nid[ np+3 ] } } ctx.putImageData( idd, 0, 0 ); if (base.options.url) { base.$el.css("background-image", 'url(' + neighbor.toDataURL() + ')'); } else { base.el.parentNode.insertBefore( neighbor, base.el ); neighbor.style.display = base.el.style.display; base.el.style.display = "none"; } } base.clamp = function (x, min, max) { return Math.max(min, Math.min(max, x)); }; base.detect = function (e){ if (! imageData) { return false; } var offset = base.$el.offset(); var x = e.pageX - offset.left; var y = e.pageY - offset.top; var pixelOffset = (canvas.width * y + x) * 4; var alpha = imageData[ pixelOffset + 3 ]; e.rgba = [ imageData[(canvas.width * y + x) * 4 ], imageData[(canvas.width * y + x) * 4 + 1 ], imageData[(canvas.width * y + x) * 4 + 2 ], imageData[(canvas.width * y + x) * 4 + 3 ] ]; e.alpha = alpha; return alpha > base.options.threshold; } base.init(); }; $.neighbor.options = { url: null, scale: null }; $.fn.neighbor = function(options){ return this.each(function(){ (new $.neighbor(this, options)); }); }; function isCrossOrigin (url) { var partz = url.split("/"); return (partz[0] != window.location.protocol && partz[2] != window.location.hostname); } function detectMobile () { return navigator.userAgent.indexOf("Mobile") !== -1 || navigator.userAgent.indexOf("Android") !== -1; } var Proxy = window['Proxy'] || { fetch: function(url, callback){ var params = { 'url': url }; $.ajax({ 'url': "/proxy/fetch", 'data': params, 'dataType': "jsonp", 'success': function(data){ var img = new Image(); img.onload = function(){ // console.log([data.length, "bytes", img.naturalWidth + "x" + img.naturalHeight].join(" ")); callback(img); }; img.src = data; } }); } }; })(jQuery);