Skip to content

Instantly share code, notes, and snippets.

@coryasilva
Last active December 15, 2015 15:20
Show Gist options
  • Save coryasilva/efbca9cca01176fc5daf to your computer and use it in GitHub Desktop.
Save coryasilva/efbca9cca01176fc5daf to your computer and use it in GitHub Desktop.
AngularJs Directive for OKZoom Loupe
var app = angular.module('loupe', []);
app.controller('MainCtrl', ['$scope',
function($scope) {
$scope.title = 'AngularJS Image Loupe';
$scope.image = 'puppy.jpg';
$scope.loupeOptions = {
width: 360,
height: 144,
round: false,
scaleWidth: '1600',
background: "#fff",
backgroundRepeat: "no-repeat",
shadow: "0 0 5px #000",
border: "1px solid black"
};
}
]);
app.directive('appImageLoupe', ['$document',
function($document) {
return {
restrict: 'AE',
scope: {
options: '=appImageLoupe'
},
link: function(scope, element, attrs) {
// Square Image Helper
scope.options.height = scope.options.height || scope.options.width;
/* Init */
var base = {};
base.$el = element;
base.$el.data("okzoom", base);
base.image_from_data = base.$el.data("okimage");
base.has_data_image = typeof base.image_from_data !== "undefined";
base.msie = -1; // Return value assumes failure.
if (base.has_data_image) {
base.img = new Image ();
base.img.src = base.image_from_data;
}
// IE Goodness
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
base.msie = parseFloat(RegExp.$1);
}
}
var listener = $document[0].createElement('div');
var $listener = $(listener).addClass('ok-listener').css({
position: 'absolute',
zIndex: 10000
});
$('body').append($listener);
var loupe = $document[0].createElement("div");
loupe.id = "ok-loupe";
loupe.style.position = "absolute";
loupe.style.backgroundRepeat = "no-repeat";
loupe.style.pointerEvents = "none";
loupe.style.display = "none";
loupe.style.zIndex = 7879;
$('body').append(loupe);
/* end Init */
// Mouse Over Event
element.bind('mouseover', (function(e) {
if (! base.has_data_image) {
base.img = element;
}
else if (base.image_from_data != base.$el.attr('data-loupe')) {
// data() returns cached values, whereas attr() returns from the dom.
base.image_from_data = base.$el.attr('data-loupe');
$(base.img).remove();
base.img = new Image();
base.img.src = base.image_from_data;
}
if (base.msie > -1 && base.msie < 9.0 && !base.img.naturalized) {
var naturalize = function(img) {
img = img || this;
var io = new Image();
io.el = img;
io.src = img.src;
img.naturalWidth = io.width;
img.naturalHeight = io.height;
img.naturalized = true;
};
if (base.img.complete) naturalize(base.img);
else return;
}
base.offset = element.offset();
base.width = element.width();
base.height = element.height();
$listener.css({
display: 'block',
width: element.outerWidth(),
height: element.outerHeight(),
top: element.offset().top,
left: element.offset().left
});
if (scope.options.scaleWidth) {
base.naturalWidth = scope.options.scaleWidth;
base.naturalHeight = Math.round( base.img[0].naturalHeight * scope.options.scaleWidth / base.img[0].naturalWidth );
} else {
base.naturalWidth = base.img[0].naturalWidth;
base.naturalHeight = base.img[0].naturalHeight;
}
base.widthRatio = base.naturalWidth / base.width;
base.heightRatio = base.naturalHeight / base.height;
loupe.style.width = scope.options.width + "px";
loupe.style.height = scope.options.height + "px";
loupe.style.border = scope.options.border;
loupe.style.background = scope.options.background + " url(" + base.img[0].src + ")";
loupe.style.backgroundRepeat = scope.options.backgroundRepeat;
loupe.style.backgroundSize = scope.options.scaleWidth ?
base.naturalWidth + "px " + base.naturalHeight + "px" : "auto";
loupe.style.borderRadius =
loupe.style.OBorderRadius =
loupe.style.MozBorderRadius =
loupe.style.WebkitBorderRadius = scope.options.round ? scope.options.width + "px" : 0;
loupe.style.boxShadow = scope.options.shadow;
}));
// Mouse Move Event
$listener.bind('mousemove', (function(e) {
var shimLeft = scope.options.width / 2;
var shimTop = scope.options.height / 2;
var pageX = typeof e.pageX !== 'undefined' ? e.pageX :
(e.clientX + $document[0].documentElement.scrollLeft);
var pageY = typeof e.pageY !== 'undefined' ? e.pageY :
(e.clientY + $document[0].documentElement.scrollTop);
var scaleLeft = -1 * Math.floor( (pageX - base.offset.left) * base.widthRatio - shimLeft );
var scaleTop = -1 * Math.floor( (pageY - base.offset.top) * base.heightRatio - shimTop );
$document[0].body.style.cursor = "none";
loupe.style.display = "block";
loupe.style.left = pageX - shimLeft + "px";
loupe.style.top = pageY - shimTop + "px";
loupe.style.backgroundPosition = scaleLeft + "px " + scaleTop + "px";
}));
// Mouse Out Event
$listener.bind('mouseout', (function(e) {
loupe.style.display = "none";
loupe.style.background = "none";
listener.style.display = "none";
$document[0].body.style.cursor = "auto";
}));
// Teardown
scope.$on('$destroy', function () {
$listener.unbind('mouseout mousemove mouseover');
$listener.remove();
loupe.remove();
});
}
};
}
]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment