/** TODO * - mouse zooming * - IE support * - own PNG images * - test Opera/FF/Safari * - fix scroll issue */ (function( $ ){ window.requestAnimFrame = (function(callback) { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 250); }; })(); var settings, canvas, context, target_x, target_y, target_zoom = 1, x, y, mx, my, init = false, active = false, angle = 0, image, width, height, loading = true, drag = false, zoom = 1, bar, bar_drag = false, circle; var methods = { init : function(options) { if(!init){ init = true; $("body").prepend('
'); $("#smoothoom").css({background:settings.background}); bar = $(".smoothoom-bar"); circle = $(".smoothoom-circle"); circle.bind('mousedown.smoothoom', methods.barmousedown); canvas = document.getElementById('smoothoom-canvas'); if (typeof(G_vmlCanvasManager) != 'undefined'){ G_vmlCanvasManager.initElement(canvas); } context = canvas.getContext('2d'); $(".smoothoom-close").bind('click.smoothoom', methods.hide); $(".smoothoom-plus").bind('click.smoothoom', methods.zoomIn); $(".smoothoom-minus").bind('click.smoothoom', methods.zoomOut); canvas.addEventListener('DOMMouseScroll', methods.mousewheel,false); canvas.addEventListener('mousewheel', methods.mousewheel,false); $("#smoothoom").bind('mousemove.smoothoom', methods.mousemove); $("#smoothoom").bind('mousedown.smoothoom', methods.mousedown); $("#smoothoom").bind('mouseup.smoothoom', methods.mouseup); $(document).bind('keyup.smoothoom', methods.keyup); $(window).bind('resize.smoothoom', methods.resize); methods.resize(); } }, click : function() { methods.show($(this).attr("href")); return false; }, resize : function() { canvas.width = $("#smoothoom").width(); canvas.height = $("#smoothoom").height(); target_x = canvas.width/2; target_y = canvas.height/2; }, show : function(src) { $("body").css({overflow:"hidden"}); methods.resize(); loading = true; active = true; methods.draw(); zoom = 0.01; image = new Image(); target_zoom = settings.min; target_x = x = canvas.width/2; target_y = y = canvas.height/2; image.onload = function(){ loading = false; width = image.width; height = image.height; zoom = 0.01; target_zoom = ($(window).height()-90)/image.height; } image.src = src; $("#smoothoom").fadeIn(settings.duration, function(){ methods.draw(); }); }, hide : function() { $("body").css({overflow:"scroll"}); target_zoom *= 2; $("#smoothoom").fadeOut(settings.duration, function(){ active = false; }); }, zoomIn: function() { target_zoom = Math.min(settings.max, target_zoom * 1.2); }, zoomOut: function() { target_zoom = Math.max(settings.min, target_zoom / 1.2); }, keyup: function(e) { if(active) { switch(e.keyCode) { case 27: methods.hide(); break; case 107: case 187: methods.zoomIn(); break; case 109: case 189: methods.zoomOut(); break; case 37: target_x += 200; break; case 39: target_x -= 200; break; case 40: target_y -= 200; break; case 38: target_y += 200; break; } } }, mousewheel: function(e) { var delta = e.wheelDelta ? e.wheelDelta/40 : e.detail ? -e.detail : 0; if (delta) { delta > 0 ? methods.zoomIn() : methods.zoomOut(); } return e.preventDefault() && false; }, barmousedown: function(e) { bar_drag = true; return e.preventDefault() && false; }, mousemove: function(e) { if(bar_drag){ var offset = bar.offset(); var pos = (e.clientX - offset.left)/416 * (settings.max - settings.min); target_zoom = Math.max(settings.min, Math.min(settings.max, pos)); } else if(drag){ target_x += (e.clientX - mx); mx = e.clientX; target_y += (e.clientY - my); my = e.clientY; } }, mousedown: function(e) { drag = true; mx = e.clientX; my = e.clientY; return e.preventDefault() && false; }, mouseup: function(e) { drag = false; bar_drag = false; }, draw : function( content ) { methods.tween(); context.fillStyle = settings.background; context.fillRect(0, 0, canvas.width, canvas.height); methods.zoomBar(); if(loading) methods.drawPreloader(); else methods.drawImage(); if(active) window.requestAnimFrame(methods.draw); }, zoomBar: function(){ circle.css({left: (zoom / (settings.max - settings.min)) * 410 - 10}); }, tween: function() { if(Math.abs(target_zoom - zoom) > 0.01) { zoom += (target_zoom - zoom)/10; } if(Math.abs(target_x - x) > 0.01) { x += (target_x - x)/10; } if(Math.abs(target_y - y) > 0.01) { y += (target_y - y)/10; } }, drawImage: function() { context.drawImage(image, x - width/2 * zoom, y - height/2 * zoom, image.width*zoom, image.height*zoom); }, drawPreloader: function() { angle++; context.beginPath(); context.arc(canvas.width/2, canvas.height/2, settings.preloaderRadius, (angle/50) * Math.PI, (1.5+angle/50) * Math.PI); context.lineWidth = settings.preloaderWidth; context.strokeStyle = settings.preloaderColor; context.stroke(); }, requestAnimFrame: function(callback) { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); }; } }; $.fn.smoothoom = function(options) { settings = $.extend( { background:'#111', fadeDuration:300, preloaderRadius:12, preloaderWidth:5, preloaderColor:'#aaa', min:0.25, max:3, level:2 }, options); methods.init(); return this.each(function() { $(this).bind('click.smoothoom', methods.click); }); }; })( jQuery );