Skip to content

Instantly share code, notes, and snippets.

@Stanley
Created September 3, 2010 10:24
Show Gist options
  • Save Stanley/563718 to your computer and use it in GitHub Desktop.
Save Stanley/563718 to your computer and use it in GitHub Desktop.
// Author: Stanisław Wasiutyński
// Date: 14.07.2010
(function($){
$.fn.big_preview = function(img_url, opts) {
var defaults = {
on_wait: "Please wait...",
show_all: true,
show_all_label: "Click to fit image to screen",
thumb_move_label: "Drag to change image position",
loading: "../images/big_black.gif"
}
var options = $.extend(defaults, opts);
return this.each(function() {
var scale = 1
var container = $(this)
var load_img = new Image()
load_img.src = options.loading
var loading = $("<div class='loading ui-corner-all' />").append(load_img).append($("<p />").text(defaults.on_wait))
var draggable = $("<div class='draggable' />")
var zoom_val = $("<div class='zoom_val' />")
var zoom_out = $("<a class='slider_button ui-state-default ui-corner-all' />").text("-")
var zoom_in = $("<a class='slider_button ui-state-default ui-corner-all' />").text("+")
var slider = $("<div class='slider' />").slider({
value: 1,
step: 0.05,
min: 0.1,
max: 10,
slide: function(event, ui) {
draggable.trigger("zoom", [ui.value, draggable.width() / 2, draggable.height() / 2])
}
})
var slider_wrapper = $("<span class='slider_wrapper' />").append(slider)
var slider_container = $("<div class='slider_container' />")
.append(zoom_out)
.append(slider_wrapper)
.append(zoom_in)
var in_view = $("<div class='in_view' />").attr("title", options.thumb_move_label)
var preview = $("<div class='preview_thumb' />").append(in_view).css("background-image", "url("+options.thumb+")").attr("title", options.show_all_label)
var background = new Image()
draggable.append(slider_container).append(preview).append(zoom_val)
$(background).load(function(){
var width = this.width
var height = this.height
draggable.append(this)
var big_image = $(this)
draggable.bind('zoom', function(_, new_scale, xScreen, yScreen) {
var x = parseInt(big_image.css('left'))
var y = parseInt(big_image.css('top'))
var xImg = (-x + xScreen) / scale
var yImg = (-y + yScreen) / scale
new_scale = new_scale < 0.1 ? 0.1 : (new_scale > 10 ? 10 : new_scale);
scale = new_scale
var dx = xImg - (-x + xScreen) / scale
var dy = yImg - (-y + yScreen) / scale
big_image.css('left', Math.round(x - dx * scale)+"px")
.css('top', Math.round(y - dy * scale)+"px")
.css('width', Math.round(scale*width)+"px")
.css('height', Math.round(scale*height)+"px")
preview.trigger("my_update")
slider.slider("value", scale)
zoom_val.text(Math.round(scale*100) + "%")
})
.bind('mousewheel', function(e, delta) {
var xScreen = e.pageX - $(this).offset().left;
var yScreen = e.pageY - $(this).offset().top;
// determine the new scale
if (delta > 0) d = 12/10;
else d = 10/12;
draggable.trigger("zoom", [scale*d, xScreen, yScreen])
})
preview.bind("my_update", function(){
var ratio = $(this).width()/width
var w = parseInt($(this).width() / (width * scale / draggable.width()))
var h = parseInt($(this).height() / (height * scale / draggable.height()))
var x = parseInt(big_image.css('left'))
var y = parseInt(big_image.css('top'))
in_view.css({
width: function(){
return w
},
height: function(){
return h
},
left: function(){
return (-ratio*x/scale) + "px"
},
top: function(){
return (-ratio*y/scale) + "px"
}
})
})
big_image.bind("fit", function(){
// Show all
draggable.trigger('zoom', [container.height()/height, 0, 0])
// Move to the middle
$(this).css("left", (draggable.width() - this.width) / 2)
$(this).css("top", 0)
preview.trigger("my_update")
})
.draggable({
drag: function(event) {
preview.trigger("my_update")
}
})
.dblclick(function(e){
var xScreen = e.pageX - draggable.offset().left;
var yScreen = e.pageY - draggable.offset().top;
draggable.trigger("zoom", [scale*1.5, xScreen , yScreen ])
})
preview.click(function(){
big_image.trigger("fit")
})
in_view.draggable({
drag: function(event){
var y_ratio = height / preview.height()
var x = parseInt($(this).css('left'))
var y = parseInt($(this).css('top'))
big_image.css("left", -x*y_ratio*scale + "px")
big_image.css("top", -y*y_ratio*scale + "px")
}
})
zoom_in.click(function(){
draggable.trigger("zoom", [scale*1.5, draggable.width() / 2, draggable.height() / 2])
})
zoom_in.dblclick(function(){
return false
})
zoom_out.click(function(){
draggable.trigger("zoom", [scale/1.5, draggable.width() / 2, draggable.height() / 2])
})
zoom_out.dblclick(function(){
return false
})
loading.hide()
container.append(draggable)
slider_container.hide().fadeIn("slow")
preview.hide().fadeIn("slow")
big_image.trigger("fit")
// IE version of user-select:none
$('.slider_container > a').each(function() {
this.onselectstart = function() {
return false
}
})
// Opera version of user-select:none
$('.slider_container > a').bind('mousedown.disableTextSelect', function() {
return false;
});
})
container.append(loading)
background.src = img_url;
background.onerror = function() { alert("Image file "+img_url+" could not be loaded!"); }
});
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment