2451 lines
100 KiB
JavaScript
2451 lines
100 KiB
JavaScript
/*
|
|
Smooth Zoom Pan - jQuery Image Viewer
|
|
Copyright (c) 2011-12 Ramesh Kumar
|
|
http://codecanyon.net/user/VF
|
|
|
|
Version: 1.6.7
|
|
RELEASE: 09 SEP 2011
|
|
UPDATE: 27 SEP 2012
|
|
|
|
Built using:
|
|
jQuery version:1.7.1 http://jquery.com/
|
|
Modernizr version:2.5.3 http://www.modernizr.com/
|
|
MouseWheel version:3.0.6 http://brandonaaron.net/code/mousewheel/docs
|
|
|
|
*/
|
|
|
|
(function ($, window, document) {
|
|
|
|
/*****************************************************************************
|
|
Default settings:
|
|
For detailed description of individual parameters, see the help document
|
|
******************************************************************************/
|
|
var defaults = {
|
|
|
|
width: '', //Width of the view area [480, '480px', '100%']
|
|
height: '', //Height of the view area [480, '480px', '100%']
|
|
|
|
initial_ZOOM: '', //Initial zoom level to start with (in percentage) [100]
|
|
initial_POSITION: '', //Initial location to be focused in pixel value [150,150 or 150 150]
|
|
|
|
animation_SMOOTHNESS: 5.5, //Ease or smoothness of all movements [Any number from 0]
|
|
animation_SPEED_ZOOM: 5.5, //Speed of zoom movements [Any number from 0]
|
|
animation_SPEED_PAN: 5.5, //Speed of pan movements [Any number from 0]
|
|
|
|
zoom_MAX: 800, //Maximum limit for zooming (in percentage)
|
|
zoom_MIN: '', //Minimum limit for zooming (in percentage)
|
|
zoom_SINGLE_STEP: false, //To reach maximum and minimum zoom levels in single click
|
|
zoom_OUT_TO_FIT: true, //To allow image to be zoomed out with whitespace on sides
|
|
zoom_BUTTONS_SHOW: true, //To enable/disable the + and - buttons
|
|
|
|
pan_BUTTONS_SHOW: true, //To enable/disable the arrow and reset buttons
|
|
pan_LIMIT_BOUNDARY: true, //To allow/restrict moving the image beyond boundaries
|
|
pan_REVERSE: false,
|
|
|
|
reset_ALIGN_TO: 'center center', //Image can be aligned to desired position on reset. Example: 'Top Left'
|
|
reset_TO_ZOOM_MIN: true, //How it should behave if zoom_MIN value set and while clicking reset button,
|
|
|
|
button_SIZE: 18, //Button width and height (in pixels)
|
|
button_SIZE_TOUCH_DEVICE: 30, //Button width and height (in pixels) on touch devices
|
|
button_COLOR: '#FFFFFF', //Button color in hexadecimal
|
|
button_BG_COLOR: '#000000', //Button set's background color in hexadecimal
|
|
button_BG_TRANSPARENCY: 55, //Background transparency (in percentage)
|
|
button_AUTO_HIDE: false, //To hide the button set when mouse moved outside the view area
|
|
button_AUTO_HIDE_DELAY: 1, //Auto hide delay time in seconds
|
|
button_ALIGN: 'bottom right', //Button set can be aligned to any side or center
|
|
button_MARGIN: 10, //Space between button set and view port's edge
|
|
button_ROUND_CORNERS: true, //To enable disable roundness of button corner
|
|
|
|
touch_DRAG: true, //Enable/disable the dragability of image (touch)
|
|
mouse_DRAG: true, //Enable/disable the dragability of image (mouse)
|
|
mouse_WHEEL: true, //Enable/disable mousewheel zoom
|
|
mouse_WHEEL_CURSOR_POS: true, //Enable/disable position sensitive mousewheel zoom
|
|
mouse_DOUBLE_CLICK: true, //Enable/disable zoom action with double click
|
|
|
|
background_COLOR: '#FFFFFF', //Background colour of image container
|
|
border_SIZE: 1, //Border size of view area
|
|
border_COLOR: '#000000', //Border color of view area
|
|
border_TRANSPARENCY: 10, //Border transparency of view area
|
|
|
|
image_url: '', //Set url or image to be zoomed
|
|
image_original_width: '', //Original width of main image
|
|
image_original_height: '', //Original height of main image
|
|
container: '', //Set container element of image (id of container)
|
|
|
|
on_IMAGE_LOAD: '', //To Call external function immediatly after image loaded
|
|
on_ZOOM_PAN_UPDATE: '', //To Call external function for each zoom, pan animation frame
|
|
on_ZOOM_PAN_COMPLETE: '', //To Call external function whenever zoom, pan animation completes
|
|
on_LANDMARK_STATE_CHANGE: '', //To Call external function whenever the zoom leval crosses global "data-show-at-zoom" value
|
|
|
|
use_3D_Transform: true, //To enable / disable Hardware acceleration on webkit browsers
|
|
|
|
responsive: false, //To enable / disable Responsive / fluid layout
|
|
responsive_maintain_ratio: true, //To maintain view area width/height ratio or not
|
|
max_WIDTH: '', //Maximum allowed width of view area (helpful when 'width' parameter set with % and need limit)
|
|
max_HEIGHT: '' //Maximum allowed height of view area (helpful when 'height' parameter set with % and need limit)
|
|
};
|
|
|
|
function Zoomer($elem, params) {
|
|
|
|
var self = this;
|
|
this.$elem = $elem;
|
|
var op = $.extend({}, defaults, params);
|
|
|
|
/**********************************************************
|
|
Option values verified and formated if needed
|
|
**********************************************************/
|
|
this.sW = op.width;
|
|
this.sH = op.height;
|
|
|
|
this.init_zoom = op.initial_ZOOM / 100;
|
|
this.init_pos = op.initial_POSITION.replace(/,/g, ' ').replace(/\s{2,}/g, ' ').split(' ');
|
|
|
|
this.zoom_max = op.zoom_MAX / 100;
|
|
this.zoom_min = op.zoom_MIN / 100;
|
|
|
|
this.zoom_single = checkBoolean(op.zoom_SINGLE_STEP);
|
|
this.zoom_fit = checkBoolean(op.zoom_OUT_TO_FIT);
|
|
this.zoom_speed = 1 + (((op.animation_SPEED === 0 || op.animation_SPEED ? op.animation_SPEED : op.animation_SPEED_ZOOM) + 1) / 20);
|
|
this.zoom_show = checkBoolean(op.zoom_BUTTONS_SHOW);
|
|
|
|
this.pan_speed_o = (op.animation_SPEED === 0 || op.animation_SPEED ? op.animation_SPEED : op.animation_SPEED_PAN);
|
|
this.pan_show = checkBoolean(op.pan_BUTTONS_SHOW);
|
|
this.pan_limit = checkBoolean(op.pan_LIMIT_BOUNDARY);
|
|
this.pan_rev = checkBoolean(op.pan_REVERSE);
|
|
|
|
this.reset_align = op.reset_ALIGN_TO.toLowerCase().split(' ');
|
|
this.reset_to_zmin = checkBoolean(op.reset_TO_ZOOM_MIN);
|
|
|
|
if (supportsTouch) {
|
|
this.bu_size = parseInt(op.button_SIZE_TOUCH_DEVICE / 2) * 2;
|
|
} else {
|
|
this.bu_size = parseInt(op.button_SIZE / 2) * 2;
|
|
}
|
|
this.bu_color = op.button_COLOR;
|
|
this.bu_bg = op.button_BG_COLOR;
|
|
this.bu_bg_alpha = op.button_BG_TRANSPARENCY / 100;
|
|
this.bu_icon = op.button_ICON_IMAGE;
|
|
this.bu_auto = checkBoolean(op.button_AUTO_HIDE);
|
|
|
|
this.bu_delay = op.button_AUTO_HIDE_DELAY * 1000;
|
|
this.bu_align = op.button_ALIGN.toLowerCase().split(' ');
|
|
this.bu_margin = op.button_MARGIN;
|
|
this.bu_round = checkBoolean(op.button_ROUND_CORNERS);
|
|
|
|
this.touch_drag = checkBoolean(op.touch_DRAG);
|
|
this.mouse_drag = checkBoolean(op.mouse_DRAG);
|
|
this.mouse_wheel = checkBoolean(op.mouse_WHEEL);
|
|
this.mouse_wheel_cur = checkBoolean(op.mouse_WHEEL_CURSOR_POS);
|
|
this.mouse_dbl_click = checkBoolean(op.mouse_DOUBLE_CLICK);
|
|
|
|
this.ani_smooth = Math.max(1, (op.animation_SMOOTHNESS + 1) / 1.45);
|
|
|
|
this.bg_color = op.background_COLOR;
|
|
this.bord_size = op.border_SIZE;
|
|
this.bord_color = op.border_COLOR;
|
|
this.bord_alpha = op.border_TRANSPARENCY / 100;
|
|
|
|
this.container = op.container;
|
|
this.image_url = op.image_url;
|
|
this.image_width = op.image_original_width;
|
|
this.image_height = op.image_original_height;
|
|
|
|
this.responsive = checkBoolean(op.responsive);
|
|
this.maintain_ratio = checkBoolean(op.responsive_maintain_ratio);
|
|
this.w_max = op.max_WIDTH;
|
|
this.h_max = op.max_HEIGHT;
|
|
|
|
this.onLOAD = op.on_IMAGE_LOAD;
|
|
this.onUPDATE = op.on_ZOOM_PAN_UPDATE;
|
|
this.onZOOM_PAN = op.on_ZOOM_PAN_COMPLETE;
|
|
this.onLANDMARK = op.on_LANDMARK_STATE_CHANGE;
|
|
|
|
/***********************************************************
|
|
Variables for inner operation.
|
|
x, y, width, height and scale value of image
|
|
***********************************************************/
|
|
this._x;
|
|
this._y;
|
|
this._w;
|
|
this._h;
|
|
this._sc = 0;
|
|
|
|
this.rA = 1;
|
|
this.rF = 1;
|
|
this.rR = 1;
|
|
this.iW = 0;
|
|
this.iH = 0;
|
|
this.tX = 0;
|
|
this.tY = 0;
|
|
this.oX = 0;
|
|
this.oY = 0;
|
|
this.fX = 0;
|
|
this.fY = 0;
|
|
this.dX = 0;
|
|
this.dY = 0;
|
|
this.cX = 0;
|
|
this.cY = 0;
|
|
|
|
this.transOffX = 0;
|
|
this.transOffY = 0;
|
|
this.focusOffX = 0;
|
|
this.focusOffY = 0;
|
|
this.offX = 0;
|
|
this.offY = 0;
|
|
|
|
/***********************************************************
|
|
Flags that convey current states and events
|
|
***********************************************************/
|
|
this._playing = false;
|
|
this._dragging = false;
|
|
this._onfocus = false;
|
|
this._moveCursor = false;
|
|
this._wheel = false;
|
|
this._recent = 'zoomOut';
|
|
this._pinching = false;
|
|
this._landmark = false;
|
|
this._rA;
|
|
this._centx;
|
|
this._centy;
|
|
this._onButton = false;
|
|
this._onHitArea = false;
|
|
this.cFlag = {
|
|
_zi: false,
|
|
_zo: false,
|
|
_ml: false,
|
|
_mr: false,
|
|
_mu: false,
|
|
_md: false,
|
|
_rs: false,
|
|
_nd: false
|
|
};
|
|
|
|
/***********************************************************
|
|
Elements and arrays that references elements
|
|
***********************************************************/
|
|
this.$holder;
|
|
this.$hitArea;
|
|
this.$controls;
|
|
this.$loc_cont;
|
|
this.map_coordinates = [];
|
|
this.locations = [];
|
|
this.buttons = [];
|
|
this.border = [];
|
|
|
|
/***********************************************************
|
|
miscellaneous
|
|
***********************************************************/
|
|
this.buttons_total = 7;
|
|
this.cButtId = 0;
|
|
this.pan_speed;
|
|
this.auto_timer;
|
|
this.ani_timer;
|
|
this.ani_end;
|
|
this.focusSpeed = this.reduction = .5;
|
|
this.orig_style;
|
|
this.mapAreas;
|
|
this.icons;
|
|
this.show_at_zoom;
|
|
this.assetsLoaded = false;
|
|
this.zStep = 0;
|
|
this.sRed = 300;
|
|
this.use3D = op.use_3D_Transform && supportsTrans3D;
|
|
|
|
if (supportsTouch) {
|
|
this.event_down = 'touchstart.sz';
|
|
this.event_up = 'touchend.sz';
|
|
this.event_move = 'touchmove.sz';
|
|
} else {
|
|
this.event_down = 'mousedown.sz';
|
|
this.event_up = 'mouseup.sz';
|
|
this.event_move = 'mousemove.sz';
|
|
}
|
|
|
|
//Case 1: Image specificed (possibly) through img tag:
|
|
if (this.image_url == '') {
|
|
this.$image = $elem;
|
|
this.id = this.$image.attr('id');
|
|
|
|
//Case 2: Image url specificed through parameter:
|
|
} else {
|
|
var img = new Image();
|
|
if (this.image_width) {
|
|
img.width = this.image_width;
|
|
}
|
|
if (this.image_height) {
|
|
img.height = this.image_height;
|
|
}
|
|
img.src = this.image_url;
|
|
this.$image = $(img).appendTo($elem);
|
|
}
|
|
|
|
|
|
//Prepare container div (Basically the element that masks image with overflow hidden)
|
|
this.setContainer();
|
|
|
|
//Get button icon image's url
|
|
var testOb;
|
|
if (!this.bu_icon) {
|
|
var regx = /url\(["']?([^'")]+)['"]?\)/;
|
|
testOb = $('<div class="smooth_zoom_icons"></div>');
|
|
this.$holder.append(testOb);
|
|
this.bu_icon = testOb.css("background-image").replace(regx, '$1');
|
|
if (this.bu_icon == 'none') {
|
|
this.bu_icon = 'zoom_assets/icons.png';
|
|
}
|
|
testOb.remove();
|
|
}
|
|
|
|
//Firefox feature checkup
|
|
if (this.$image.css('-moz-transform') && prop_transform) {
|
|
testOb = $('<div style="-moz-transform: translate(1px, 1px)"></div>');
|
|
this.$holder.append(testOb);
|
|
this.fixMoz = testOb.position().left === 1 ? false : true;
|
|
testOb.remove();
|
|
} else {
|
|
this.fixMoz = false;
|
|
}
|
|
|
|
//Preload icons and main image.
|
|
this.$image.hide();
|
|
this.imgList = [
|
|
{ loaded: false, src: this.bu_icon || 'zoom_assets/icons.png' }, //Icon image
|
|
{ loaded: false, src: this.image_url == '' ? this.$image.attr('src') : this.image_url } // Main image
|
|
];
|
|
|
|
$.each(this.imgList, function (i) {
|
|
var _img = new Image();
|
|
$(_img).bind('load', { id: i, self: self }, self.loadComplete)
|
|
.bind('error', { id: i, self: self }, self.loadComplete); //Allow initiation even if image is not there :(
|
|
_img.src = self.imgList[i].src;
|
|
});
|
|
|
|
}
|
|
|
|
Zoomer.prototype = {
|
|
|
|
/*Preload the icon and main image
|
|
*********************************************************************************************************************/
|
|
loadComplete: function (e) {
|
|
var self = e.data.self,
|
|
complete = true;
|
|
|
|
self.imgList[e.data.id].loaded = true;
|
|
for (var j = 0; j < self.imgList.length; j++) {
|
|
if (!self.imgList[j].loaded) {
|
|
complete = false;
|
|
}
|
|
}
|
|
if (complete) {
|
|
self.assetsLoaded = true;
|
|
if (self.onLOAD !== '') {
|
|
self.onLOAD();
|
|
}
|
|
|
|
//Assets loaded, initiate plugin
|
|
self.init();
|
|
}
|
|
},
|
|
|
|
|
|
/*Initiate after assets loaded
|
|
***********************************************************************************************************************/
|
|
init: function () {
|
|
var self = this,
|
|
$image = self.$image,
|
|
sW = self.sW,
|
|
sH = self.sH,
|
|
container = self.container,
|
|
cBW, cBH, pan_show = self.pan_show,
|
|
zoom_show = self.zoom_show,
|
|
$controls = self.$controls,
|
|
buttons = self.buttons,
|
|
cFlag = self.cFlag,
|
|
bu_align = self.bu_align,
|
|
bu_margin = self.bu_margin,
|
|
$holder = self.$holder;
|
|
|
|
//Store the default image properties so that it can be reverted back when plugin needs to be destroyed
|
|
self.orig_style = self.getStyle();
|
|
|
|
//IE 6 Image tool bar disabled
|
|
$image.attr('galleryimg', 'no');
|
|
|
|
if (!navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad)/)) {
|
|
$image.removeAttr('width');
|
|
$image.removeAttr('height');
|
|
}
|
|
|
|
//In case parent element's display property set to 'none', we need to first set them 'block', measure the width and height and then set them back to 'none'
|
|
var temp = $image,
|
|
dispArray = [];
|
|
for (var i = 0; i < 5; i++) {
|
|
if (temp && temp[0].tagName !== 'BODY' && temp[0].tagName !== 'HTML') {
|
|
if (temp.css('display') == 'none') {
|
|
temp.css('display', 'block');
|
|
dispArray.push(temp);
|
|
}
|
|
temp = temp.parent();
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
self.iW = $image.width();
|
|
self.iH = $image.height();
|
|
|
|
for (var i = 0; i < dispArray.length; i++) {
|
|
dispArray[i].css('display', 'none');
|
|
}
|
|
|
|
//Initially the image needs to be resized to fit container. To do so, first measure the scaledown ratio
|
|
self.rF = self.rR = self.checkRatio(sW, sH, self.iW, self.iH, self.zoom_fit);
|
|
|
|
//If NO Minimum zoom value set
|
|
if (self.zoom_min == 0 || self.init_zoom != 0) {
|
|
if (self.init_zoom != '') {
|
|
self.rA = self._sc = self.init_zoom;
|
|
} else {
|
|
self.rA = self._sc = self.rF;
|
|
}
|
|
if (self.zoom_min != 0) {
|
|
self.rF = self.zoom_min;
|
|
}
|
|
|
|
//If Minimum zoom value set
|
|
} else {
|
|
if (self.rF < self.zoom_min) {
|
|
self.rF = self.zoom_min;
|
|
if (self.reset_to_zmin) {
|
|
self.rR = self.zoom_min
|
|
}
|
|
self.rA = self._sc = self.zoom_min;
|
|
} else {
|
|
self.rA = self._sc = self.rR;
|
|
}
|
|
}
|
|
|
|
//Width and Height to be applied to the image
|
|
self._w = self._sc * self.iW;
|
|
self._h = self._sc * self.iH;
|
|
|
|
//Resize the image and position it centered inside the wrapper
|
|
if (self.init_pos == '') {
|
|
self._x = self.tX = (sW - self._w) / 2;
|
|
self._y = self.tY = (sH - self._h) / 2;
|
|
} else {
|
|
self._x = self.tX = (sW / 2) - parseInt(self.init_pos[0]) * self._sc;
|
|
self._y = self.tY = (sH / 2) - parseInt(self.init_pos[1]) * self._sc;
|
|
self.oX = (self.tX - ((sW - self._w) / 2)) / (self._w / sW);
|
|
self.oY = (self.tY - ((sH - self._h) / 2)) / (self._h / sH);
|
|
}
|
|
|
|
if ((!self.pan_limit || self._moveCursor || self.init_zoom != self.rF) && self.mouse_drag) {
|
|
$image.css('cursor', 'move');
|
|
self.$hitArea.css('cursor', 'move');
|
|
}
|
|
|
|
if ($.browser.mozilla && supportsTrans3D) {
|
|
$image.css('opacity', 0);
|
|
}
|
|
|
|
if (prop_transform) {
|
|
self.$image.css(prop_origin, '0 0');
|
|
}
|
|
if (self.use3D) {
|
|
$image.css({
|
|
'-webkit-backface-visibility': 'hidden',
|
|
'-webkit-perspective': 1000
|
|
});
|
|
}
|
|
|
|
//Start displaying the image
|
|
$image.css({
|
|
position: 'absolute',
|
|
'z-index': 2,
|
|
left: '0px',
|
|
top: '0px',
|
|
'-webkit-box-shadow': '1px 1px rgba(0,0,0,0)'
|
|
})
|
|
.hide()
|
|
.fadeIn(500, function () {
|
|
$holder.css('background-image', 'none');
|
|
if ($.browser.mozilla && supportsTrans3D) {
|
|
$image.css('opacity', 1);
|
|
}
|
|
});
|
|
|
|
//Create Control buttons and events
|
|
var self = self,
|
|
bs = self.bu_size,
|
|
iSize = 50,
|
|
sDiff = 2,
|
|
bSpace = 3,
|
|
mSize = Math.ceil(self.bu_size / 4),
|
|
iconOff = bs < 16 ? 50 : 0,
|
|
bsDiff = bs - sDiff;
|
|
|
|
//Show all buttons
|
|
if (pan_show) {
|
|
if (zoom_show) {
|
|
cBW = parseInt(bs + (bs * .85) + (bsDiff * 3) + (bSpace * 2) + (mSize * 2));
|
|
} else {
|
|
cBW = parseInt((bsDiff * 3) + (bSpace * 2) + (mSize * 2));
|
|
}
|
|
cBH = parseInt((bsDiff * 3) + (bSpace * 2) + (mSize * 2));
|
|
|
|
//Show zoom buttons only
|
|
} else {
|
|
if (zoom_show) {
|
|
cBW = parseInt(bs + mSize * 2);
|
|
cBH = parseInt(bs * 2 + mSize * 3);
|
|
cBW = parseInt(cBW / 2) * 2;
|
|
cBH = parseInt(cBH / 2) * 2;
|
|
} else {
|
|
cBW = 0;
|
|
cBH = 0;
|
|
}
|
|
}
|
|
|
|
var pOff = (iSize - bs) / 2,
|
|
resetCenterX = cBW - ((bs - (pan_show ? sDiff : 0)) * 2) - mSize - bSpace,
|
|
resetCenterY = (cBH / 2) - ((bs - (pan_show ? sDiff : 0)) / 2);
|
|
|
|
var hProp, vProp, hVal, vVal;
|
|
//Align button set as per settings
|
|
if (bu_align[0] == 'top') {
|
|
vProp = 'top';
|
|
vVal = bu_margin;
|
|
} else if (bu_align[0] == 'center') {
|
|
vProp = 'top';
|
|
vVal = parseInt((sH - cBH) / 2);
|
|
} else {
|
|
vProp = 'bottom';
|
|
vVal = bu_margin;
|
|
}
|
|
if (bu_align[1] == 'right') {
|
|
hProp = 'right';
|
|
hVal = bu_margin;
|
|
} else if (bu_align[1] == 'center') {
|
|
hProp = 'right';
|
|
hVal = parseInt((sW - cBW) / 2);
|
|
} else {
|
|
hProp = 'left';
|
|
hVal = bu_margin;
|
|
}
|
|
|
|
//Buttons Container
|
|
$controls = $(
|
|
'<div style="position: absolute; ' + hProp + ':' + hVal + 'px; ' + vProp + ': ' + vVal + 'px; width: ' + cBW + 'px; height: ' + cBH + 'px; z-index: 20;" class="noSel;">\
|
|
<div class="noSel controlsBg" style="position: relative; width: 100%; height: 100%; z-index: 1;">\
|
|
</div>\
|
|
</div>'
|
|
);
|
|
|
|
$holder.append($controls);
|
|
var $controlsBg = $controls.find('.controlsBg');
|
|
|
|
//Make the corners rounded
|
|
if (self.bu_round) {
|
|
if (prop_radius) {
|
|
$controlsBg
|
|
.css(prop_radius, (iconOff > 0 ? 4 : 5) + 'px')
|
|
.css('background-color', self.bu_bg);
|
|
} else {
|
|
self.roundBG(
|
|
$controlsBg,
|
|
'cBg',
|
|
cBW,
|
|
cBH,
|
|
iconOff > 0 ? 4 : 5,
|
|
375,
|
|
self.bu_bg,
|
|
self.bu_icon,
|
|
1,
|
|
iconOff ? 50 : 0
|
|
);
|
|
}
|
|
} else {
|
|
$controlsBg.css('background-color', self.bu_bg);
|
|
}
|
|
|
|
$controlsBg.css('opacity', self.bu_bg_alpha);
|
|
|
|
//Generating Button properties (7 buttons)
|
|
buttons[0] = {
|
|
_var: '_zi',
|
|
l: mSize,
|
|
t: pan_show ? (cBH - (bs * 2) - (bSpace * 2) + 2) / 2 : mSize,
|
|
w: bs,
|
|
h: bs,
|
|
bx: -pOff,
|
|
by: -pOff - iconOff
|
|
};
|
|
|
|
buttons[1] = {
|
|
_var: '_zo',
|
|
l: mSize,
|
|
t: pan_show ? ((cBH - (bs * 2) - (bSpace * 2) + 2) / 2) + bs + (bSpace * 2) - 2 : cBH - bs - mSize,
|
|
w: bs,
|
|
h: bs,
|
|
bx: -iSize - pOff,
|
|
by: -pOff - iconOff
|
|
};
|
|
|
|
buttons[2] = {
|
|
_var: self.pan_rev ? '_ml' : '_mr',
|
|
l: resetCenterX - bsDiff - bSpace,
|
|
t: resetCenterY,
|
|
w: bsDiff,
|
|
h: bsDiff,
|
|
bx: -(sDiff / 2) - iSize * 2 - pOff,
|
|
by: -(sDiff / 2) - pOff - iconOff
|
|
};
|
|
|
|
buttons[3] = {
|
|
_var: self.pan_rev ? '_mr' : '_ml',
|
|
l: resetCenterX + bsDiff + bSpace,
|
|
t: resetCenterY,
|
|
w: bsDiff,
|
|
h: bsDiff,
|
|
bx: -(sDiff / 2) - iSize * 3 - pOff,
|
|
by: -(sDiff / 2) - pOff - iconOff
|
|
};
|
|
|
|
buttons[4] = {
|
|
_var: self.pan_rev ? '_md' : '_mu',
|
|
l: resetCenterX,
|
|
t: resetCenterY + bsDiff + bSpace,
|
|
w: bsDiff,
|
|
h: bsDiff,
|
|
bx: -(sDiff / 2) - iSize * 4 - pOff,
|
|
by: -(sDiff / 2) - pOff - iconOff
|
|
};
|
|
|
|
buttons[5] = {
|
|
_var: self.pan_rev ? '_mu' : '_md',
|
|
l: resetCenterX,
|
|
t: resetCenterY - bsDiff - bSpace,
|
|
w: bsDiff,
|
|
h: bsDiff,
|
|
bx: -(sDiff / 2) - iSize * 5 - pOff,
|
|
by: -(sDiff / 2) - pOff - iconOff
|
|
};
|
|
|
|
buttons[6] = {
|
|
_var: '_rs',
|
|
l: resetCenterX,
|
|
t: resetCenterY,
|
|
w: bsDiff,
|
|
h: bsDiff,
|
|
bx: -(sDiff / 2) - iSize * 6 - pOff,
|
|
by: -(sDiff / 2) - pOff - iconOff
|
|
};
|
|
|
|
for (var i = 0; i < 7; i++) {
|
|
buttons[i].$ob = $(
|
|
'<div style="position: absolute; display: ' + (i < 2 ? zoom_show ? 'block' : 'none' : pan_show ? 'block' : 'none') + '; left: ' + (buttons[i].l - 1) + 'px; top: ' + (buttons[i].t - 1) + 'px; width: ' + (buttons[i].w + 2) + 'px; height: ' + (buttons[i].h + 2) + 'px; z-index:' + (i + 1) + ';" class="noSel">\
|
|
</div>'
|
|
)
|
|
.css('opacity', .7)
|
|
.bind((supportsTouch ? "" : 'mouseover.sz mouseout.sz ') + self.event_down, {
|
|
id: i
|
|
|
|
}, function (e) {
|
|
self._onfocus = false;
|
|
$this = $(this);
|
|
|
|
//Button over
|
|
if (e.type == 'mouseover') {
|
|
if ($this.css('opacity') > .5) {
|
|
$this.css('opacity', 1);
|
|
}
|
|
|
|
//Button out
|
|
} else if (e.type == 'mouseout') {
|
|
if ($this.css('opacity') > .5) {
|
|
$this.css('opacity', .7);
|
|
}
|
|
|
|
//Button press/down
|
|
} else if (e.type == 'mousedown' || e.type == 'touchstart') {
|
|
self.cButtId = e.data.id;
|
|
self._onButton = true;
|
|
self._wheel = false;
|
|
|
|
//If NOT already down..
|
|
if ($this.css('opacity') > .5) {
|
|
$this.css('opacity', 1);
|
|
$holder.find('#' + buttons[self.cButtId]._var + 'norm').hide();
|
|
$holder.find('#' + buttons[self.cButtId]._var + 'over').show();
|
|
|
|
//CASE 1: If zoomIn pressed and single step zoom enabled
|
|
if (self.cButtId <= 1 && self.zoom_single) {
|
|
if (!cFlag[buttons[self.cButtId]._var]) {
|
|
self.sRed = 300;
|
|
cFlag[buttons[self.cButtId]._var] = true;
|
|
}
|
|
|
|
//CASE 2: If any button except RESET pressed
|
|
} else if (self.cButtId < 6) {
|
|
cFlag[buttons[self.cButtId]._var] = true;
|
|
|
|
//CASE 3: RESET pressed
|
|
} else {
|
|
cFlag._rs = true;
|
|
self.rA = self.rR;
|
|
if (self.reset_align[0] == 'top') {
|
|
self.fY = (self.sH / 2) * (self.rA / 2);
|
|
} else if (self.reset_align[0] == 'bottom') {
|
|
self.fY = -(self.sH / 2) * (self.rA / 2);
|
|
} else {
|
|
self.fY = 0;
|
|
}
|
|
if (self.reset_align[1] == 'left') {
|
|
self.fX = (self.sW / 2) * (self.rA / 2);
|
|
} else if (self.reset_align[1] == 'right') {
|
|
self.fX = -(self.sW / 2) * (self.rA / 2);
|
|
} else {
|
|
self.fX = 0;
|
|
}
|
|
}
|
|
|
|
self.focusOffX = self.focusOffY = 0;
|
|
self.changeOffset(true, true);
|
|
if (!self._playing) {
|
|
self.Animate();
|
|
}
|
|
}
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
});
|
|
|
|
//Make 2 BGs for Button Normal and Over state
|
|
//Button BG normal
|
|
var tpm = $(
|
|
'<div id="' + buttons[i]._var + 'norm" style="position: absolute; left: 1px; top: 1px; width: ' + buttons[i].w + 'px; height: ' + buttons[i].h + 'px; ' + (prop_radius || !self.bu_round ? 'background:' + self.bu_color : '') + '">\
|
|
</div>'
|
|
);
|
|
|
|
//Button BG hover
|
|
var tpmo = $(
|
|
'<div id="' + buttons[i]._var + 'over" style="position: absolute; left: 0px; top: 0px; width: ' + (buttons[i].w + 2) + 'px; height: ' + (buttons[i].h + 2) + 'px; display: none; ' + (prop_radius || !self.bu_round ? 'background:' + self.bu_color : '') + '">\
|
|
</div>'
|
|
);
|
|
|
|
//Add the button icons
|
|
var cont = $(
|
|
'<div id="' + buttons[i]._var + '_icon" style="position: absolute; left: 1px; top: 1px; width: ' + buttons[i].w + 'px; height: ' + buttons[i].h + 'px; background: transparent url(' + self.bu_icon + ') ' + buttons[i].bx + 'px ' + buttons[i].by + 'px no-repeat;" >\
|
|
</div>'
|
|
);
|
|
|
|
buttons[i].$ob.append(tpm, tpmo, cont);
|
|
$controls.append(buttons[i].$ob);
|
|
|
|
//Apply corner radius
|
|
if (self.bu_round) {
|
|
if (prop_radius) {
|
|
tpm.css(prop_radius, '2px');
|
|
tpmo.css(prop_radius, '2px');
|
|
} else {
|
|
self.roundBG(
|
|
tpm,
|
|
buttons[i]._var + "norm",
|
|
buttons[i].w,
|
|
buttons[i].h,
|
|
2,
|
|
425,
|
|
self.bu_color,
|
|
self.bu_icon,
|
|
i + 1,
|
|
iconOff ? 50 : 0
|
|
);
|
|
self.roundBG(
|
|
tpmo,
|
|
buttons[i]._var + "over",
|
|
buttons[i].w + 2,
|
|
buttons[i].h + 2,
|
|
2,
|
|
425,
|
|
self.bu_color,
|
|
self.bu_icon,
|
|
i + 1,
|
|
iconOff ? 50 : 0
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Add Events for mouse drag / touch swipe action
|
|
$(document).bind(self.event_up + self.id, { self: self }, self.mouseUp);
|
|
|
|
if ((self.mouse_drag && !supportsTouch) || (self.touch_drag && supportsTouch)) {
|
|
self.$holder.bind(self.event_down, { self: self }, self.mouseDown);
|
|
if (supportsTouch) {
|
|
$(document).bind(self.event_move + self.id, { self: self }, self.mouseDrag);
|
|
}
|
|
}
|
|
|
|
//Add Double click / Double tap zoom
|
|
if (self.mouse_dbl_click) {
|
|
var dClickedX,
|
|
dClickedY,
|
|
dbl_click_dir = 1;
|
|
|
|
self.$holder.bind('dblclick.sz', function (e) {
|
|
self.focusOffX = e.pageX - $holder.offset().left - (self.sW / 2);
|
|
self.focusOffY = e.pageY - $holder.offset().top - (self.sH / 2);
|
|
self.changeOffset(true, true);
|
|
self._wheel = false;
|
|
|
|
if (self.rA < self.zoom_max && dbl_click_dir == -1 && dClickedX != self.focusOffX && dClickedY != self.focusOffY) {
|
|
dbl_click_dir = 1;
|
|
}
|
|
|
|
dClickedX = self.focusOffX;
|
|
dClickedY = self.focusOffY;
|
|
|
|
if (self.rA >= self.zoom_max && dbl_click_dir == 1) {
|
|
dbl_click_dir = -1;
|
|
}
|
|
if (self.rA <= self.rF && dbl_click_dir == -1) {
|
|
dbl_click_dir = 1;
|
|
}
|
|
if (dbl_click_dir > 0) {
|
|
self.rA *= 2;
|
|
self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA;
|
|
cFlag._zi = true;
|
|
clearTimeout(self.ani_timer);
|
|
self._playing = true;
|
|
self.Animate();
|
|
cFlag._zi = false;
|
|
|
|
} else {
|
|
self.rA /= 2;
|
|
self.rA = self.rA < self.rF ? self.rF : self.rA;
|
|
cFlag._zo = true;
|
|
clearTimeout(self.ani_timer);
|
|
self._playing = true;
|
|
self.Animate();
|
|
cFlag._zo = false;
|
|
}
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
});
|
|
}
|
|
|
|
//Add mouse wheel event if enabled
|
|
if (self.mouse_wheel) {
|
|
$holder.bind('mousewheel.sz', { self: this }, self.mouseWheel);
|
|
}
|
|
|
|
//Auto Hide the control buttons if enabled
|
|
if (self.bu_auto) {
|
|
$holder.bind('mouseleave.sz', { self: this }, self.autoHide);
|
|
}
|
|
|
|
//Prevent Controls Bg from start dragging image
|
|
$controls.bind(self.event_down, function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
});
|
|
|
|
//Prevent Controls Bg from double click zoom
|
|
if (self.mouse_dbl_click) {
|
|
$controls.bind('dblclick.sz', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
});
|
|
}
|
|
|
|
//Prevent text selection for smoother dragging and button focus
|
|
$('.noSel').each(function () {
|
|
this.onselectstart = function () {
|
|
return false;
|
|
};
|
|
});
|
|
|
|
self.$holder = $holder;
|
|
self.$controls = $controls;
|
|
self.sW = sW;
|
|
self.sH = sH;
|
|
self.cBW = cBW;
|
|
self.cBH = cBH;
|
|
|
|
//Apply initial transformation
|
|
self.Animate();
|
|
},
|
|
|
|
|
|
/*Prepare the container (holder) element and get landmarks if available
|
|
***********************************************************************************************************************/
|
|
setContainer: function () {
|
|
var self = this,
|
|
$image = self.$image,
|
|
bord_size = self.bord_size,
|
|
border = self.border,
|
|
$holder = self.$holder;
|
|
|
|
//Wrap a container for image or get the container if specified through options:
|
|
if (self.container == '' && self.image_url == '') {
|
|
$holder = self.$image.wrap(
|
|
'<div class="noSel smooth_zoom_preloader">\
|
|
</div>'
|
|
).parent();
|
|
|
|
} else {
|
|
if (self.image_url == '') {
|
|
$holder = $('#' + self.container);
|
|
} else {
|
|
$holder = self.$elem;
|
|
}
|
|
$holder.addClass('noSel smooth_zoom_preloader');
|
|
self.locations = [];
|
|
self.$loc_cont = $holder.find('.landmarks');
|
|
if (self.$loc_cont[0]) {
|
|
var locs = self.$loc_cont.children('.item');
|
|
self.loc_clone = self.$loc_cont.clone();
|
|
self.show_at_zoom = parseInt(self.$loc_cont.data('show-at-zoom'), 10) / 100;
|
|
self.allow_scale = checkBoolean(self.$loc_cont.data('allow-scale'));
|
|
self.allow_drag = checkBoolean(self.$loc_cont.data('allow-drag'));
|
|
locs.each(function () {
|
|
self.setLocation($(this));
|
|
});
|
|
}
|
|
}
|
|
|
|
$holder.css({
|
|
'position': 'relative',
|
|
'overflow': 'hidden',
|
|
'text-align': 'left',
|
|
'-moz-user-select': 'none',
|
|
'-khtml-user-select': 'none',
|
|
'-webkit-user-select': 'none',
|
|
'user-select': 'none',
|
|
'-webkit-touch-callout': 'none',
|
|
'-webkit-tap-highlight-color': 'rgba(255, 255, 255, 0)',
|
|
'background-color': self.bg_color,
|
|
'background-position': 'center center',
|
|
'background-repeat': 'no-repeat'
|
|
})
|
|
|
|
self.$hitArea = $('<div style="position: absolute; z-index: 1; top: 0px; left: 0px; width: 100%; height: 100%;" ></div>').appendTo($holder);
|
|
|
|
self.getContainerSize(self.sW, self.sH, $holder, self.w_max, self.h_max);
|
|
|
|
if (self.responsive) {
|
|
$(window).bind("orientationchange.sz" + self.id + " resize.sz" + self.id, { self: self }, self.resize);
|
|
}
|
|
var sW = self.sW;
|
|
var sH = self.sH;
|
|
|
|
//Add Image container properties
|
|
$holder.css({
|
|
'width': sW,
|
|
'height': sH
|
|
});
|
|
|
|
//Add border if needed
|
|
if (bord_size > 0) {
|
|
border[0] = $('<div style="position: absolute; width: ' + bord_size + 'px; height: ' + sH + 'px; top: 0px; left: 0px; z-index: 3; background-color: ' + self.bord_color + ';"></div>').css('opacity', self.bord_alpha);
|
|
border[1] = $('<div style="position: absolute; width: ' + bord_size + 'px; height: ' + sH + 'px; top: 0px; left: ' + (sW - bord_size) + 'px; z-index: 4; background-color: ' + self.bord_color + ';"></div>').css('opacity', self.bord_alpha);
|
|
border[2] = $('<div style="position: absolute; width: ' + (sW - (bord_size * 2)) + 'px; height: ' + bord_size + 'px; top: 0px; left: ' + bord_size + 'px; z-index: 5; background-color: ' + self.bord_color + '; line-height: 1px;"></div>').css('opacity', self.bord_alpha);
|
|
border[3] = $('<div style="position: absolute; width: ' + (sW - (bord_size * 2)) + 'px; height: ' + bord_size + 'px; top: ' + (sH - bord_size) + 'px; left: ' + bord_size + 'px; z-index: 6; background-color: ' + self.bord_color + '; line-height: 1px;"></div>').css('opacity', self.bord_alpha);
|
|
$holder.append(border[0], border[1], border[2], border[3]);
|
|
}
|
|
|
|
//Get Image maps if exists
|
|
if ($image.attr('usemap') != undefined) {
|
|
self.mapAreas = $("map[name='" + ($image.attr('usemap').split('#').join('')) + "']").children('area');
|
|
self.mapAreas.each(function (i) {
|
|
var area = $(this);
|
|
area.css('cursor', 'pointer');
|
|
if (self.mouse_drag) {
|
|
area.bind(self.event_down, { self: self }, self.mouseDown);
|
|
}
|
|
if (self.mouse_wheel) {
|
|
area.bind('mousewheel.sz', { self: self }, self.mouseWheel);
|
|
}
|
|
self.map_coordinates.push(area.attr('coords').split(','));
|
|
});
|
|
}
|
|
|
|
self.$holder = $holder;
|
|
self.sW = sW;
|
|
self.sH = sH;
|
|
},
|
|
|
|
getContainerSize: function (sW, sH, $holder, w_max, h_max) {
|
|
if (sW === '' || sW === 0) {
|
|
if (this.image_url == '') {
|
|
sW = Math.max($holder.parent().width(), 100);
|
|
} else {
|
|
sW = Math.max($holder.width(), 100);
|
|
}
|
|
|
|
} else if (!isNaN(sW) || String(sW).indexOf('px') > -1) {
|
|
sW = this.oW = parseInt(sW);
|
|
if (this.responsive) {
|
|
sW = Math.min($holder.parent().width(), sW);
|
|
}
|
|
} else if (String(sW).indexOf('%') > -1) {
|
|
sW = $holder.parent().width() * (sW.split('%')[0] / 100);
|
|
} else {
|
|
sW = 100;
|
|
}
|
|
if (w_max !== 0 && w_max !== '') {
|
|
sW = Math.min(sW, w_max);
|
|
}
|
|
if (sH === '' || sH === 0) {
|
|
if (this.image_url == '') {
|
|
sH = Math.max($holder.parent().height(), 100);
|
|
} else {
|
|
sH = Math.max($holder.height(), 100);
|
|
}
|
|
} else if (!isNaN(sH) || String(sH).indexOf('px') > -1) {
|
|
sH = this.oH = parseInt(sH);
|
|
|
|
} else if (String(sH).indexOf('%') > -1) {
|
|
sH = $holder.parent().height() * (sH.split('%')[0] / 100);
|
|
} else {
|
|
sH = 100;
|
|
}
|
|
if (h_max !== 0 && h_max !== '') {
|
|
sH = Math.min(sH, h_max);
|
|
}
|
|
|
|
if (this.oW && sW !== this.oW) {
|
|
if (this.oH && this.maintain_ratio) {
|
|
sH = sW / (this.oW / this.oH);
|
|
}
|
|
}
|
|
|
|
this.sW = sW;
|
|
this.sH = sH;
|
|
},
|
|
|
|
|
|
/*Each landmark / location / lable initiated here
|
|
***********************************************************************************************************************/
|
|
setLocation: function (lc) {
|
|
var self = this,
|
|
ob = lc,
|
|
w2, h2, pos, sc;
|
|
|
|
if (prop_origin) {
|
|
ob.css(prop_origin, '0 0');
|
|
}
|
|
|
|
ob.css({
|
|
'display': 'block',
|
|
'z-index': 2
|
|
})
|
|
if (self.use3D) {
|
|
ob.css({
|
|
'-webkit-backface-visibility': 'hidden',
|
|
'-webkit-perspective': 1000
|
|
});
|
|
}
|
|
|
|
w2 = ob.outerWidth() / 2;
|
|
h2 = ob.outerHeight() / 2;
|
|
pos = ob.data('position').split(',');
|
|
sc = ob.data('allow-scale');
|
|
if (sc == undefined) {
|
|
sc = self.allow_scale;
|
|
} else {
|
|
sc = checkBoolean(sc);
|
|
}
|
|
|
|
if (ob.hasClass('mark')) {
|
|
var imgw = ob.find('img').css('vertical-align', 'bottom').width();
|
|
$(ob.children()[0]).css({
|
|
'position': 'absolute',
|
|
'left': (-ob.width() / 2),
|
|
'bottom': parseInt(ob.css('padding-bottom')) * 2
|
|
});
|
|
var txt = ob.find('.text');
|
|
self.locations.push({
|
|
ob: ob,
|
|
x: parseInt(pos[0]),
|
|
y: parseInt(pos[1]),
|
|
w2: w2,
|
|
h2: h2,
|
|
w2pad: w2 + (txt[0] ? parseInt(txt.css('padding-left')) : 0),
|
|
vis: false,
|
|
lab: false,
|
|
lpx: '0',
|
|
lpy: '0',
|
|
showAt: isNaN(ob.data('show-at-zoom')) ? self.show_at_zoom : parseInt(ob.data('show-at-zoom'), 10) / 100,
|
|
scale: sc
|
|
});
|
|
|
|
} else if (ob.hasClass('lable')) {
|
|
var bg = ob.data('bg-color'),
|
|
opacity = ob.data('bg-opacity'),
|
|
cont = $(ob.eq(0).children()[0])
|
|
.css({
|
|
'position': 'absolute',
|
|
'z-index': 2,
|
|
left: -w2,
|
|
top: -h2
|
|
});
|
|
|
|
self.locations.push({
|
|
ob: ob,
|
|
x: parseInt(pos[0]),
|
|
y: parseInt(pos[1]),
|
|
w2: w2,
|
|
h2: h2,
|
|
w2pad: w2,
|
|
vis: false,
|
|
lab: true,
|
|
lpx: '0',
|
|
lpy: '0',
|
|
showAt: isNaN(ob.data('show-at-zoom')) ? self.show_at_zoom : parseInt(ob.data('show-at-zoom'), 10) / 100,
|
|
scale: sc
|
|
});
|
|
|
|
if (bg !== "") {
|
|
if (!bg) {
|
|
bg = "#000000";
|
|
opacity = .7;
|
|
}
|
|
var bgob = $('<div style="position: absolute; left: ' + (-w2) + 'px; top: ' + (-h2) + 'px; width: ' + ((w2 - parseInt(cont.css('padding-left'))) * 2) + 'px; height:' + ((h2 - parseInt(cont.css('padding-top'))) * 2) + 'px; background-color: ' + bg + ';"></div>').appendTo(ob);
|
|
if (opacity) {
|
|
bgob.css('opacity', opacity);
|
|
}
|
|
}
|
|
}
|
|
ob.hide();
|
|
if (prop_transform) {
|
|
ob.css('opacity', 0);
|
|
}
|
|
if (!self.allow_drag) {
|
|
ob.bind(self.event_down, function (e) {
|
|
//e.preventDefault();
|
|
e.stopPropagation();
|
|
})
|
|
}
|
|
},
|
|
|
|
/*Storing the original style of image (needed only when destroying)
|
|
***********************************************************************************************************************/
|
|
getStyle: function () {
|
|
var el = this.$image;
|
|
return {
|
|
prop_origin: [prop_origin, prop_origin !== false && prop_origin !== undefined ? el.css(prop_origin) : null],
|
|
prop_transform: [prop_transform, prop_transform !== false && prop_transform !== undefined ? el.css(prop_transform) : null],
|
|
'position': ['position', el.css('position')],
|
|
'z-index': ['z-index', el.css('z-index')],
|
|
'cursor': ['cursor', el.css('cursor')],
|
|
'left': ['left', el.css('left')],
|
|
'top': ['top', el.css('top')],
|
|
'width': ['width', el.css('width')],
|
|
'height': ['height', el.css('height')]
|
|
};
|
|
},
|
|
|
|
/*Find the scale ratios
|
|
***********************************************************************************************************************/
|
|
checkRatio: function (sW, sH, iW, iH, zoom_fit) {
|
|
var rF;
|
|
if (iW == sW && iH == sH) {
|
|
rF = 1;
|
|
} else if (iW < sW && iH < sH) {
|
|
rF = sW / iW;
|
|
if (zoom_fit) {
|
|
if (rF * iH > sH) {
|
|
rF = sH / iH;
|
|
}
|
|
} else {
|
|
if (rF * iH < sH) {
|
|
rF = sH / iH;
|
|
}
|
|
if (sW / iW !== sH / iH && this.mouse_drag) {
|
|
this._moveCursor = true;
|
|
this.$image.css('cursor', 'move');
|
|
this.$hitArea.css('cursor', 'move');
|
|
}
|
|
}
|
|
} else {
|
|
|
|
rF = sW / iW;
|
|
if (zoom_fit) {
|
|
if (rF * iH > sH) {
|
|
rF = sH / iH;
|
|
}
|
|
if (rF < this.init_zoom && this.mouse_drag) {
|
|
this._moveCursor = true;
|
|
this.$image.css('cursor', 'move');
|
|
this.$hitArea.css('cursor', 'move');
|
|
}
|
|
} else {
|
|
if (rF * iH < sH) {
|
|
rF = sH / iH;
|
|
}
|
|
if (sW / iW !== sH / iH && this.mouse_drag) {
|
|
this._moveCursor = true;
|
|
this.$image.css('cursor', 'move');
|
|
this.$hitArea.css('cursor', 'move');
|
|
}
|
|
}
|
|
}
|
|
return rF;
|
|
},
|
|
|
|
|
|
/*Returns distance between 2 points (used for touch gesture)
|
|
***********************************************************************************************************************/
|
|
getDistance: function (x1, y1, x2, y2) {
|
|
return Math.sqrt(Math.abs(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))));
|
|
},
|
|
|
|
|
|
/*Image Events for Dragging and Mouse Wheel
|
|
***********************************************************************************************************************/
|
|
mouseDown: function (e) {
|
|
var self = e.data.self;
|
|
self._onfocus = self._dragging = false;
|
|
if (self.cFlag._nd) {
|
|
if (self.fixMoz) {
|
|
self.correctTransValue();
|
|
}
|
|
self.samePointRelease = false;
|
|
if (e.type == 'mousedown') {
|
|
self.stX = e.pageX;
|
|
self.stY = e.pageY;
|
|
self.offX = e.pageX - self.$holder.offset().left - self.$image.position().left;
|
|
self.offY = e.pageY - self.$holder.offset().top - self.$image.position().top;
|
|
$(document).bind(self.event_move + self.id, { self: self }, self.mouseDrag);
|
|
} else {
|
|
var te = e.originalEvent;
|
|
if (te.targetTouches.length > 1) {
|
|
self._pinching = true;
|
|
self._rA = self.rA;
|
|
self.dStart = self.getDistance(te.touches[0].pageX, te.touches[0].pageY, te.touches[1].pageX, te.touches[1].pageY);
|
|
} else {
|
|
self.offX = te.touches[0].pageX - self.$holder.offset().left - self.$image.position().left;
|
|
self.offY = te.touches[0].pageY - self.$holder.offset().top - self.$image.position().top;
|
|
self.setDraggedPos(te.touches[0].pageX - self.$holder.offset().left - self.offX, te.touches[0].pageY - self.$holder.offset().top - self.offY, self._sc);
|
|
self._recent = 'drag';
|
|
self._dragging = true;
|
|
}
|
|
}
|
|
self._onHitArea = true;
|
|
}
|
|
if (e.type == 'mousedown') {
|
|
e.preventDefault();
|
|
}
|
|
},
|
|
|
|
|
|
/*Mouse Drag / Touch swipe operations handled here
|
|
***********************************************************************************************************************/
|
|
mouseDrag: function (e) {
|
|
var self = e.data.self;
|
|
|
|
//Mouse
|
|
if (e.type == 'mousemove') {
|
|
self.setDraggedPos(e.pageX - self.$holder.offset().left - self.offX, e.pageY - self.$holder.offset().top - self.offY, self._sc);
|
|
self._recent = 'drag';
|
|
self._dragging = true;
|
|
if (!self._playing) {
|
|
self.Animate();
|
|
}
|
|
return false;
|
|
|
|
//Touch
|
|
} else {
|
|
if (self._dragging || self._pinching) {
|
|
e.preventDefault();
|
|
}
|
|
if (self._onHitArea) {
|
|
var touches = e.originalEvent.touches;
|
|
if (self._pinching || touches.length > 1) {
|
|
if (!self._pinching) {
|
|
self._pinching = true;
|
|
self._rA = self.rA;
|
|
if (touches.length > 1) {
|
|
self.dStart = self.getDistance(touches[0].pageX, touches[0].pageY, touches[1].pageX, touches[1].pageY);
|
|
}
|
|
}
|
|
if (touches.length > 1) {
|
|
self._centx = (touches[0].pageX + touches[1].pageX) / 2;
|
|
self._centy = (touches[0].pageY + touches[1].pageY) / 2;
|
|
self.focusOffX = self._centx - self.$holder.offset().left - (self.sW / 2);
|
|
self.focusOffY = self._centy - self.$holder.offset().top - (self.sH / 2);
|
|
self.changeOffset(true, true);
|
|
self._wheel = true;
|
|
self._dragging = false;
|
|
if (self.zoom_single) {
|
|
self.sRed = 300;
|
|
|
|
} else {
|
|
self.dEnd = self.getDistance(touches[0].pageX, touches[0].pageY, touches[1].pageX, touches[1].pageY);
|
|
self.rA = self._rA * (self.dEnd / self.dStart);
|
|
self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA;
|
|
self.rA = self.rA < self.rF ? self.rF : self.rA;
|
|
}
|
|
if (self._sc < self.rA) {
|
|
self.cFlag._zo = false;
|
|
self.cFlag._zi = true;
|
|
} else {
|
|
self.cFlag._zi = false;
|
|
self.cFlag._zo = true;
|
|
}
|
|
if (!self._playing) {
|
|
self.Animate();
|
|
}
|
|
}
|
|
|
|
} else if (self._dragging && touches.length < 2) {
|
|
self.setDraggedPos(touches[0].pageX - self.$holder.offset().left - self.offX, touches[0].pageY - self.$holder.offset().top - self.offY, self._sc);
|
|
self._recent = 'drag';
|
|
if (!self._playing) {
|
|
self.Animate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
|
|
/*Global Mouse Up / Touch End
|
|
***********************************************************************************************************************/
|
|
mouseUp: function (e) {
|
|
var self = e.data.self;
|
|
|
|
//If one of the buttons released
|
|
if (self._onButton) {
|
|
self.$holder.find('#' + self.buttons[self.cButtId]._var + 'norm').show();
|
|
self.$holder.find('#' + self.buttons[self.cButtId]._var + 'over').hide();
|
|
if (self.cButtId !== 6) {
|
|
self.cFlag[self.buttons[self.cButtId]._var] = false;
|
|
}
|
|
if (e.type == 'touchend' && self.buttons[self.cButtId].$ob.css('opacity') > .5) {
|
|
self.buttons[self.cButtId].$ob.css('opacity', .7);
|
|
}
|
|
self._onButton = false;
|
|
e.stopPropagation();
|
|
return false;
|
|
|
|
//If the mouse drag or touch swipe completed
|
|
} else if (self._onHitArea) {
|
|
if (self.mouse_drag || self.touch_drag) {
|
|
//Mouse
|
|
if (e.type == 'mouseup') {
|
|
$(document).unbind(self.event_move + self.id);
|
|
if (self.stX == e.pageX && self.stY == e.pageY) {
|
|
self.samePointRelease = true;
|
|
}
|
|
self._recent = 'drag';
|
|
self._dragging = false;
|
|
if (!self._playing) {
|
|
self.Animate();
|
|
}
|
|
self._onHitArea = false;
|
|
|
|
//Touch
|
|
} else {
|
|
e.preventDefault();
|
|
self._dragging = false;
|
|
if (self._pinching) {
|
|
self._pinching = false;
|
|
self._wheel = false;
|
|
self.cFlag._nd = true;
|
|
self.cFlag._zi = false;
|
|
self.cFlag._zo = false;
|
|
} else {
|
|
self._recent = 'drag';
|
|
if (!self._playing) {
|
|
self.Animate();
|
|
}
|
|
}
|
|
self._onHitArea = false;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
|
|
/*Mouse wheel zoom in-out
|
|
***********************************************************************************************************************/
|
|
mouseWheel: function (e, delta) {
|
|
var self = e.data.self;
|
|
self._onfocus = self._dragging = false;
|
|
if (self.mouse_wheel_cur) {
|
|
self.focusOffX = e.pageX - self.$holder.offset().left - (self.sW / 2);
|
|
self.focusOffY = e.pageY - self.$holder.offset().top - (self.sH / 2);
|
|
self.changeOffset(true, true);
|
|
}
|
|
|
|
self._dragging = false;
|
|
if (delta > 0) {
|
|
if (self.rA != self.zoom_max) {
|
|
if (self.zoom_single) {
|
|
if (!self._wheel) {
|
|
self.sRed = 300;
|
|
}
|
|
} else {
|
|
self.rA *= delta < 1 ? 1 + (.3 * delta) : 1.3;
|
|
self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA;
|
|
}
|
|
self._wheel = true;
|
|
self.cFlag._zi = true;
|
|
clearTimeout(self.ani_timer);
|
|
self._playing = true;
|
|
self.Animate();
|
|
self.cFlag._zi = false;
|
|
}
|
|
} else {
|
|
if (self.rA != self.rF) {
|
|
if (self.zoom_single) {
|
|
if (!self._wheel) {
|
|
self.sRed = 300;
|
|
}
|
|
} else {
|
|
self.rA /= delta > -1 ? 1 + (.3 * -delta) : 1.3;
|
|
self.rA = self.rA < self.rF ? self.rF : self.rA;
|
|
}
|
|
self._wheel = true;
|
|
self.cFlag._zo = true;
|
|
clearTimeout(self.ani_timer);
|
|
self._playing = true;
|
|
self.Animate();
|
|
self.cFlag._zo = false;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
|
|
|
|
/*Control buttons Auto hide
|
|
***********************************************************************************************************************/
|
|
autoHide: function (e) {
|
|
var self = e.data.self;
|
|
|
|
clearTimeout(self.auto_timer);
|
|
self.auto_timer = setTimeout(function () {
|
|
self.$controls.fadeOut(600);
|
|
}, self.bu_delay);
|
|
|
|
self.$holder.bind('mouseenter.sz', function (e) {
|
|
clearTimeout(self.auto_timer);
|
|
self.$controls.fadeIn(300);
|
|
});
|
|
},
|
|
|
|
|
|
/*Mozilla works differently than others when getting translated positions. So this correction needed
|
|
***********************************************************************************************************************/
|
|
correctTransValue: function () {
|
|
var v = this.$image.css('-moz-transform').toString().replace(')', '').split(',');
|
|
this.transOffX = parseInt(v[4]);
|
|
this.transOffY = parseInt(v[5]);
|
|
},
|
|
|
|
|
|
/*Make sure the dragged position obeying limits
|
|
***********************************************************************************************************************/
|
|
setDraggedPos: function (xp, yp, s) {
|
|
var self = this;
|
|
|
|
if (xp !== '') {
|
|
self.dX = xp + self.transOffX;
|
|
if (self.pan_limit) {
|
|
self.dX = self.dX + (s * self.iW) < self.sW ? self.sW - (s * self.iW) : self.dX;
|
|
self.dX = self.dX > 0 ? 0 : self.dX;
|
|
if ((s * self.iW) < self.sW) {
|
|
self.dX = (self.sW - (s * self.iW)) / 2;
|
|
}
|
|
} else {
|
|
self.dX = self.dX + (s * self.iW) < self.sW / 2 ? (self.sW / 2) - (s * self.iW) : self.dX;
|
|
self.dX = self.dX > self.sW / 2 ? self.sW / 2 : self.dX;
|
|
}
|
|
}
|
|
if (yp !== '') {
|
|
self.dY = yp + self.transOffY;
|
|
if (self.pan_limit) {
|
|
self.dY = self.dY + (s * self.iH) < self.sH ? self.sH - (s * self.iH) : self.dY;
|
|
self.dY = self.dY > 0 ? 0 : self.dY;
|
|
if ((s * self.iH) < self.sH) {
|
|
self.dY = (self.sH - (s * self.iH)) / 2;
|
|
}
|
|
} else {
|
|
self.dY = self.dY + (s * self.iH) < self.sH / 2 ? (self.sH / 2) - (s * self.iH) : self.dY;
|
|
self.dY = self.dY > self.sH / 2 ? self.sH / 2 : self.dY;
|
|
}
|
|
}
|
|
},
|
|
|
|
/*Called to animate image transformation whenever the navigation events occur
|
|
***********************************************************************************************************************/
|
|
Animate: function () {
|
|
|
|
var self = this;
|
|
var pixTol = .5;
|
|
|
|
self.cFlag._nd = true;
|
|
self.ani_end = false;
|
|
|
|
//Zoom In
|
|
if (self.cFlag._zi) {
|
|
if (!self._wheel && !self.zoom_single) {
|
|
self.rA *= self.zoom_speed;
|
|
}
|
|
if (self.rA > self.zoom_max) {
|
|
self.rA = self.zoom_max;
|
|
}
|
|
self.cFlag._nd = false;
|
|
self.cFlag._rs = false;
|
|
self._recent = 'zoomIn';
|
|
self._onfocus = self._dragging = false;
|
|
}
|
|
|
|
//Zoom Out
|
|
if (self.cFlag._zo) {
|
|
if (!self._wheel && !self.zoom_single) {
|
|
self.rA /= self.zoom_speed;
|
|
}
|
|
if (self.zoom_min != 0) {
|
|
if (self.rA < self.zoom_min) {
|
|
self.rA = self.zoom_min;
|
|
}
|
|
} else {
|
|
if (self.rA < self.rF) {
|
|
self.rA = self.rF;
|
|
}
|
|
}
|
|
|
|
self.cFlag._nd = false;
|
|
self.cFlag._rs = false;
|
|
self._recent = 'zoomOut';
|
|
self._onfocus = self._dragging = false;
|
|
}
|
|
|
|
//Zoom In or Out - Single Step
|
|
if (self.zoom_single && !self.cFlag._rs) {
|
|
if (self._recent == 'zoomIn') {
|
|
self.sRed += (10 - self.sRed) / 6;
|
|
self.rA += (self.zoom_max - self.rA) / (((1 / (self.pan_speed_o + 1)) * self.sRed) + 1);
|
|
|
|
} else if (self._recent == 'zoomOut') {
|
|
self.sRed += (3 - self.sRed) / 3;
|
|
self.rA += (self.rF - self.rA) / (((1 / self.pan_speed_o + 1) * self.sRed) + 1);
|
|
}
|
|
}
|
|
|
|
//Pan speed needs to adjust according to application dimension and zoom level
|
|
self.pan_speed = (Math.max(1, 1 + ((self.sW + self.sH) / 500)) + (self.pan_speed_o * self.pan_speed_o / 4)) / Math.max(1, self.rA / 2);
|
|
|
|
//Move Left
|
|
if (self.cFlag._ml) {
|
|
self.oX -= self.pan_speed;
|
|
self.cFlag._nd = false;
|
|
self.cFlag._rs = false;
|
|
self._recent = 'left';
|
|
self._onfocus = self._dragging = false;
|
|
}
|
|
|
|
//Move Right
|
|
if (self.cFlag._mr) {
|
|
self.oX += self.pan_speed;
|
|
self.cFlag._nd = false;
|
|
self.cFlag._rs = false;
|
|
self._recent = 'right';
|
|
self._onfocus = self._dragging = false;
|
|
}
|
|
|
|
//Move Up
|
|
if (self.cFlag._mu) {
|
|
self.oY -= self.pan_speed;
|
|
self.cFlag._nd = false;
|
|
self.cFlag._rs = false;
|
|
self._recent = 'up';
|
|
self._onfocus = self._dragging = false;
|
|
}
|
|
|
|
//Move Down
|
|
if (self.cFlag._md) {
|
|
self.oY += self.pan_speed;
|
|
self.cFlag._nd = false;
|
|
self.cFlag._rs = false;
|
|
self._recent = 'down';
|
|
self._onfocus = self._dragging = false;
|
|
}
|
|
|
|
//Reset
|
|
if (self.cFlag._rs) {
|
|
self.oX += (self.fX - self.oX) / 8;
|
|
self.oY += (self.fY - self.oY) / 8;
|
|
self.cFlag._nd = false;
|
|
self._recent = 'reset';
|
|
self._onfocus = self._dragging = false;
|
|
}
|
|
|
|
//Find scale value, width and height
|
|
//Case 1: Single Step Zoom
|
|
if (self.zoom_single && (self._recent !== 'reset')) {
|
|
if (self._onfocus) {
|
|
self._sc += (self.rA - self._sc) / self.reduction;
|
|
} else {
|
|
self._sc = self.rA;
|
|
}
|
|
|
|
//Case 2: Normal Zoom
|
|
} else {
|
|
self._sc += (self.rA - self._sc) / (self.ani_smooth / (self._onfocus ? self.reduction : 1));
|
|
}
|
|
|
|
self._w = self._sc * self.iW;
|
|
self._h = self._sc * self.iH;
|
|
|
|
//Dragging
|
|
if (self._dragging) {
|
|
self.tX = self.dX;
|
|
self.tY = self.dY;
|
|
self.changeOffset(true, true);
|
|
}
|
|
|
|
//Check if Zoom In completed
|
|
if (self._recent == "zoomIn") {
|
|
if (self._w > (self.rA * self.iW) - pixTol && !self.zoom_single) {
|
|
if (self.cFlag._nd) {
|
|
self.ani_end = true;
|
|
}
|
|
self._sc = self.rA;
|
|
} else if (self._w > (self.zoom_max * self.iW) - pixTol && self.zoom_single) {
|
|
if (self.cFlag._nd) {
|
|
self.ani_end = true;
|
|
}
|
|
self._sc = self.rA = self.zoom_max;
|
|
}
|
|
if (self.ani_end) {
|
|
self._w = self._sc * self.iW;
|
|
self._h = self._sc * self.iH;
|
|
}
|
|
|
|
//Check if Zoom Out completed
|
|
} else if (self._recent == "zoomOut") {
|
|
if (self._w < (self.rA * self.iW) + pixTol && !self.zoom_single) {
|
|
if (self.cFlag._nd) {
|
|
self.ani_end = true;
|
|
}
|
|
self._sc = self.rA;
|
|
} else if (self._w < (self.rF * self.iW) + pixTol && self.zoom_single) {
|
|
if (self.cFlag._nd) {
|
|
self.ani_end = true;
|
|
}
|
|
self._sc = self.rA = self.rF;
|
|
}
|
|
if (self.ani_end) {
|
|
self._w = self._sc * self.iW;
|
|
self._h = self._sc * self.iH;
|
|
}
|
|
}
|
|
|
|
//Move image according to boundary limits
|
|
self.limitX = (((self._w - self.sW) / (self._w / self.sW)) / 2);
|
|
self.limitY = (((self._h - self.sH) / (self._h / self.sH)) / 2);
|
|
|
|
if (!self._dragging) {
|
|
if (self.pan_limit) {
|
|
if (self.oX < -self.limitX - self.focusOffX) {
|
|
self.oX = -self.limitX - self.focusOffX;
|
|
}
|
|
if (self.oX > self.limitX - self.focusOffX) {
|
|
self.oX = self.limitX - self.focusOffX;
|
|
}
|
|
if (self._w < self.sW) {
|
|
self.tX = (self.sW - self._w) / 2;
|
|
self.changeOffset(true, false);
|
|
}
|
|
if (self.oY < -self.limitY - self.focusOffY) {
|
|
self.oY = -self.limitY - self.focusOffY;
|
|
}
|
|
if (self.oY > self.limitY - self.focusOffY) {
|
|
self.oY = self.limitY - self.focusOffY;
|
|
}
|
|
if (self._h < self.sH) {
|
|
self.tY = (self.sH - self._h) / 2;
|
|
self.changeOffset(false, true);
|
|
}
|
|
} else {
|
|
if (self.oX < -self.limitX - (self.focusOffX / self._w * self.sW) - ((self.sW / 2) / (self._w / self.sW))) {
|
|
self.oX = -self.limitX - (self.focusOffX / self._w * self.sW) - ((self.sW / 2) / (self._w / self.sW));
|
|
}
|
|
|
|
if (self.oX > self.limitX - (self.focusOffX / self._w * self.sW) + ((self.sW / 2) / (self._w / self.sW))) {
|
|
self.oX = self.limitX - (self.focusOffX / self._w * self.sW) + ((self.sW / 2) / (self._w / self.sW));
|
|
}
|
|
|
|
if (self.oY < -self.limitY - (self.focusOffY / self._h * self.sH) - (self.sH / (self._h / self.sH * 2))) {
|
|
self.oY = -self.limitY - (self.focusOffY / self._h * self.sH) - (self.sH / (self._h / self.sH * 2));
|
|
}
|
|
|
|
if (self.oY > self.limitY - (self.focusOffY / self._h * self.sH) + (self.sH / (self._h / self.sH * 2))) {
|
|
self.oY = self.limitY - (self.focusOffY / self._h * self.sH) + (self.sH / (self._h / self.sH * 2));
|
|
}
|
|
}
|
|
}
|
|
if (!self._dragging && self._recent != "drag") {
|
|
self.tX = ((self.sW - self._w) / 2) + self.focusOffX + (self.oX * (self._w / self.sW));
|
|
self.tY = ((self.sH - self._h) / 2) + self.focusOffY + (self.oY * (self._h / self.sH));
|
|
if (self.ani_smooth === 1) {
|
|
self.cFlag._nd = true;
|
|
self.ani_end = true;
|
|
}
|
|
}
|
|
if (self._recent == "zoomIn" || self._recent == "zoomOut" || self.cFlag._rs) {
|
|
self._x = self.tX;
|
|
self._y = self.tY;
|
|
} else {
|
|
self._x += (self.tX - self._x) / (self.ani_smooth / (self._onfocus ? self.reduction : 1));
|
|
self._y += (self.tY - self._y) / (self.ani_smooth / (self._onfocus ? self.reduction : 1));
|
|
}
|
|
|
|
//Check if Left movement completed
|
|
if (self._recent == "left") {
|
|
if (self._x < self.tX + pixTol || self.ani_smooth === 1) {
|
|
self.cFlag._nd ? self.ani_end = true : "";
|
|
self._recent = '';
|
|
self._x = self.tX;
|
|
}
|
|
|
|
//Check if Right movement completed
|
|
} else if (self._recent == "right") {
|
|
if (self._x > self.tX - pixTol || self.ani_smooth === 1) {
|
|
self.cFlag._nd ? self.ani_end = true : "";
|
|
self._recent = '';
|
|
self._x = self.tX;
|
|
}
|
|
|
|
//Check if Up movement completed
|
|
} else if (self._recent == "up") {
|
|
if (self._y < self.tY + pixTol || self.ani_smooth === 1) {
|
|
self.cFlag._nd ? self.ani_end = true : "";
|
|
self._recent = '';
|
|
self._y = self.tY;
|
|
}
|
|
|
|
//Check if Down movement completed
|
|
} else if (self._recent == "down") {
|
|
if (self._y > self.tY - pixTol || self.ani_smooth === 1) {
|
|
self.cFlag._nd ? self.ani_end = true : "";
|
|
self._recent = '';
|
|
self._y = self.tY;
|
|
}
|
|
|
|
//Check if Dragging completed
|
|
} else if (self._recent == "drag") {
|
|
if (self._x + pixTol >= self.tX && self._x - pixTol <= self.tX && self._y + pixTol >= self.tY && self._y - pixTol <= self.tY || self.ani_smooth === 1) {
|
|
if (self._onfocus) {
|
|
self._dragging = false;
|
|
}
|
|
self.cFlag._nd ? self.ani_end = true : "";
|
|
self._recent = '';
|
|
self._x = self.tX;
|
|
self._y = self.tY;
|
|
}
|
|
}
|
|
|
|
//Check if Reset completed
|
|
if (self.cFlag._rs && self._w + pixTol >= (self.rA * self.iW) && self._w - pixTol <= (self.rA * self.iW) && self.oX <= self.fX + pixTol && self.oX >= self.fX - pixTol && self.oY <= self.fY + pixTol && self.oY >= self.fY - pixTol) {
|
|
self.ani_end = true;
|
|
self._recent = '';
|
|
self.cFlag._rs = false;
|
|
self.cFlag._nd = true;
|
|
self._x = self.tX;
|
|
self._y = self.tY;
|
|
self._sc = self.rA;
|
|
self._w = self._sc * self.iW;
|
|
self._h = self._sc * self.iH;
|
|
}
|
|
|
|
//When the image fits exactly to container size, disable the pan, zoom out and reset buttons
|
|
if (self.rA == self.rF && self.iW * self.rA <= self.sW && self.iH * self.rA <= self.sH) {
|
|
if (self.buttons[1].$ob.css('opacity') > .5) {
|
|
if (self.rA >= self.rF && (self.init_zoom == '' || self.rA < self.init_zoom) && (self.zoom_min == '' || self.rA < self.zoom_min)) {
|
|
if (self.pan_limit && self._moveCursor && !self._moveCursor) {
|
|
self.$image.css('cursor', 'default');
|
|
self.$hitArea.css('cursor', 'default');
|
|
}
|
|
for (var bEn = 1; bEn < (self.pan_limit && !self._moveCursor ? self.buttons_total : 2) ; bEn++) {
|
|
self.buttons[bEn].$ob.css({
|
|
'opacity': .4
|
|
});
|
|
self._wheel = false;
|
|
self.$holder.find('#' + self.buttons[bEn]._var + 'norm').show();
|
|
self.$holder.find('#' + self.buttons[bEn]._var + 'over').hide();
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
if (self.buttons[1].$ob.css('opacity') < .5) {
|
|
if (self._moveCursor && self.mouse_drag) {
|
|
self.$image.css('cursor', 'move');
|
|
self.$hitArea.css('cursor', 'move');
|
|
}
|
|
for (var bEn = 1; bEn < self.buttons_total; bEn++) {
|
|
self.buttons[bEn].$ob.css('opacity', .7);
|
|
}
|
|
}
|
|
}
|
|
|
|
//When the image reaches max zoom, disable the zoom button
|
|
if (self.rA == self.zoom_max) {
|
|
if (self.buttons[0].$ob.css('opacity') > .5) {
|
|
self.buttons[0].$ob.css('opacity', .4);
|
|
self._wheel = false;
|
|
self.$holder.find('#' + self.buttons[0]._var + 'norm').show();
|
|
self.$holder.find('#' + self.buttons[0]._var + 'over').hide();
|
|
}
|
|
|
|
} else {
|
|
if (self.buttons[0].$ob.css('opacity') < .5) {
|
|
self.buttons[0].$ob.css('opacity', .7);
|
|
}
|
|
}
|
|
|
|
//Apply Scale and position to the image:
|
|
if (prop_transform) {
|
|
self.$image.css(prop_transform, 'translate(' + self._x.toFixed(14) + 'px,' + self._y.toFixed(14) + 'px) scale(' + self._sc + ')');
|
|
|
|
} else {
|
|
self.$image.css({
|
|
left: self._x,
|
|
top: self._y,
|
|
width: self._w,
|
|
height: self._h
|
|
});
|
|
}
|
|
|
|
if (self.$loc_cont) {
|
|
self.updateLocations(self._x, self._y, self._sc, self.locations);
|
|
}
|
|
|
|
//In case image Maps used, update them
|
|
if (!prop_transform && self.map_coordinates.length > 0) {
|
|
self.updateMap();
|
|
}
|
|
//If the animation completed, stop running; else continue
|
|
if (self.ani_end && !self._dragging && self._recent != "drag") {
|
|
self._playing = false;
|
|
self._recent = '';
|
|
self.cX = (-self._x + (self.sW / 2)) / self.rA;
|
|
self.cY = (-self._y + (self.sH / 2)) / self.rA;
|
|
if (self.onUPDATE) {
|
|
self.onUPDATE(self.getZoomData(), false);
|
|
}
|
|
if (self.onZOOM_PAN) {
|
|
self.onZOOM_PAN(self.getZoomData());
|
|
}
|
|
clearTimeout(self.ani_timer);
|
|
} else {
|
|
self._playing = true;
|
|
if (self.onUPDATE) {
|
|
self.onUPDATE(self.getZoomData(), true);
|
|
}
|
|
self.ani_timer = setTimeout(function () {
|
|
self.Animate();
|
|
}, 28);
|
|
}
|
|
},
|
|
|
|
|
|
/*Relocate the landmarks according to main image's position
|
|
***********************************************************************************************************************/
|
|
updateLocations: function (_x, _y, _sc, loc) {
|
|
|
|
if (this.onLANDMARK !== '') {
|
|
if (_sc >= this.show_at_zoom) {
|
|
if (!this._landmark) {
|
|
this._landmark = true
|
|
this.onLANDMARK(true);
|
|
}
|
|
} else {
|
|
if (this._landmark) {
|
|
this._landmark = false;
|
|
this.onLANDMARK(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (var p = 0; p < loc.length; p++) {
|
|
var wScaled,
|
|
hScaled,
|
|
lpx = (loc[p].x * _sc) + _x,
|
|
lpy = (loc[p].y * _sc) + _y;
|
|
|
|
if (_sc >= loc[p].showAt) {
|
|
if (loc[p].scale && prop_transform) {
|
|
wScaled = loc[p].w2pad * this._sc;
|
|
hScaled = loc[p].h2 * this._sc;
|
|
} else {
|
|
wScaled = loc[p].w2pad;
|
|
hScaled = loc[p].h2;
|
|
}
|
|
if (lpx > -wScaled && lpx < this.sW + wScaled && ((lpy > -hScaled && lpy < this.sH + hScaled && loc[p].lab) || (lpy > 0 && lpy < this.sH + (hScaled * 2) && !loc[p].lab))) {
|
|
if (!loc[p].vis) {
|
|
loc[p].vis = true;
|
|
if (prop_transform) {
|
|
loc[p].ob.stop()
|
|
.css('display', 'block')
|
|
.animate({
|
|
opacity: 1
|
|
}, 300);
|
|
} else {
|
|
loc[p].ob.show();
|
|
}
|
|
}
|
|
} else {
|
|
if (loc[p].vis) {
|
|
loc[p].vis = false;
|
|
if (prop_transform) {
|
|
loc[p].ob.stop()
|
|
.animate({
|
|
opacity: 0
|
|
}, 200, function () {
|
|
$(this).hide();
|
|
});
|
|
} else {
|
|
loc[p].ob.hide();
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (loc[p].vis) {
|
|
loc[p].vis = false;
|
|
if (prop_transform) {
|
|
loc[p].ob.stop()
|
|
.animate({
|
|
opacity: 0
|
|
}, 200, function () {
|
|
$(this).hide();
|
|
});
|
|
} else {
|
|
loc[p].ob.hide();
|
|
}
|
|
}
|
|
}
|
|
if (lpx !== loc[p].lpx || lpy !== loc[p].lpy && loc[p].vis) {
|
|
if (prop_transform) {
|
|
loc[p].ob.css(prop_transform, 'translate(' + lpx.toFixed(14) + 'px,' + lpy.toFixed(14) + 'px)' + (loc[p].scale ? ' scale(' + this._sc + ')' : ''));
|
|
} else {
|
|
loc[p].ob.css({
|
|
left: lpx,
|
|
top: lpy
|
|
});
|
|
}
|
|
}
|
|
loc[p].lpx = lpx;
|
|
loc[p].lpy = lpy;
|
|
}
|
|
},
|
|
|
|
|
|
/*If the broswer doesn't supports css border radius, we need to go with old school png image for rounded corner
|
|
***********************************************************************************************************************/
|
|
roundBG: function (el, _name, _w, _h, _r, _p, _c, _i, _z, _yoff) {
|
|
var w = 50 / 2;
|
|
|
|
el.append($(
|
|
'<div class="bgi' + _name + '" style="background-position:' + (-(_p - _r)) + 'px ' + (-(w - _r) - _yoff) + 'px"></div>\
|
|
<div class="bgh' + _name + '"></div>\
|
|
<div class="bgi' + _name + '" style="background-position:' + (-_p) + 'px ' + (-(w - _r) - _yoff) + 'px; left:' + (_w - _r) + 'px"></div>\
|
|
<div class="bgi' + _name + '" style="background-position:' + (-(_p - _r)) + 'px ' + (-w - _yoff) + 'px; top:' + (_h - _r) + 'px"></div>\
|
|
<div class="bgh' + _name + '" style = "top:' + (_h - _r) + 'px; left:' + _r + 'px"></div>\
|
|
<div class="bgi' + _name + '" style="background-position:' + (-_p) + 'px ' + (-w - _yoff) + 'px; top:' + (_h - _r) + 'px; left:' + (_w - _r) + 'px"></div>\
|
|
<div class="bgc' + _name + '"></div>'
|
|
));
|
|
$('.bgi' + _name).css({
|
|
position: 'absolute',
|
|
width: _r,
|
|
height: _r,
|
|
'background-image': 'url(' + _i + ')',
|
|
'background-repeat': 'no-repeat',
|
|
'-ms-filter': 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)',
|
|
'filter': 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)',
|
|
'zoom': 1
|
|
});
|
|
$('.bgh' + _name).css({
|
|
position: 'absolute',
|
|
width: _w - _r * 2,
|
|
height: _r,
|
|
'background-color': _c,
|
|
left: _r
|
|
});
|
|
$('.bgc' + _name).css({
|
|
position: 'absolute',
|
|
width: _w,
|
|
height: _h - _r * 2,
|
|
'background-color': _c,
|
|
top: _r,
|
|
left: 0
|
|
});
|
|
},
|
|
|
|
|
|
/*To calibrate position offset when navigation events supposed to be overlapped
|
|
***********************************************************************************************************************/
|
|
changeOffset: function (x, y) {
|
|
if (x) this.oX = (this.tX - ((this.sW - this._w) / 2) - this.focusOffX) / (this._w / this.sW);
|
|
if (y) this.oY = (this.tY - ((this.sH - this._h) / 2) - this.focusOffY) / (this._h / this.sH);
|
|
},
|
|
|
|
|
|
/*Transform Image Maps (hot spots) if any
|
|
***********************************************************************************************************************/
|
|
updateMap: function () {
|
|
var self = this,
|
|
mapId = 0;
|
|
|
|
self.mapAreas.each(function () {
|
|
var new_vals = [];
|
|
for (var i = 0; i < self.map_coordinates[mapId].length; i++) {
|
|
new_vals[i] = self.map_coordinates[mapId][i] * self._sc;
|
|
}
|
|
new_vals = new_vals.join(",");
|
|
$(this).attr('coords', new_vals);
|
|
mapId++;
|
|
});
|
|
},
|
|
|
|
|
|
/*To stop the timer loops immediatly
|
|
***********************************************************************************************************************/
|
|
haltAnimation: function () {
|
|
clearTimeout(this.ani_timer);
|
|
this._playing = false;
|
|
this._recent = '';
|
|
},
|
|
|
|
|
|
/*Method to Remove the plugin instance
|
|
***********************************************************************************************************************/
|
|
destroy: function () {
|
|
var self = this;
|
|
|
|
if (self.assetsLoaded) {
|
|
self.haltAnimation();
|
|
for (prop in self.orig_style) {
|
|
if (self.orig_style[prop][0] !== false && self.orig_style[prop][0] !== undefined) {
|
|
if (self.orig_style[prop][0] === 'width' || self.orig_style[prop][0] === 'height') {
|
|
if (parseInt(self.orig_style[prop][1]) !== 0) {
|
|
self.$image.css(self.orig_style[prop][0], self.orig_style[prop][1]);
|
|
}
|
|
} else {
|
|
self.$image.css(self.orig_style[prop][0], self.orig_style[prop][1]);
|
|
}
|
|
}
|
|
}
|
|
clearTimeout(self.auto_timer);
|
|
$(document).unbind('.sz' + self.id);
|
|
$(window).unbind('.sz' + self.id);
|
|
self.$holder.unbind('.sz');
|
|
self.$controls = undefined;
|
|
} else {
|
|
self.$image.show();
|
|
}
|
|
|
|
if (self.container == '') {
|
|
if (self.image_url == '') {
|
|
self.$image.insertBefore(self.$holder);
|
|
if (self.$holder !== undefined) {
|
|
self.$holder.remove();
|
|
}
|
|
} else {
|
|
self.$elem.empty();
|
|
if (self.$loc_cont[0]) {
|
|
self.$elem.append(self.loc_clone);
|
|
}
|
|
}
|
|
} else {
|
|
self.$image.insertBefore(self.$holder);
|
|
self.$holder.empty();
|
|
self.$image.wrap(self.$holder);
|
|
if (self.$loc_cont[0]) {
|
|
self.$holder.append(self.loc_clone);
|
|
}
|
|
}
|
|
self.$elem.removeData('smoothZoom');
|
|
self.$holder = undefined;
|
|
self.Buttons = undefined;
|
|
self.op = undefined;
|
|
self.$image = undefined;
|
|
},
|
|
|
|
|
|
/*Method to change focus point and level
|
|
***********************************************************************************************************************/
|
|
focusTo: function (params) {
|
|
var self = this;
|
|
|
|
if (self.assetsLoaded) {
|
|
if (params.zoom === undefined || params.zoom === '' || params.zoom == 0) {
|
|
params.zoom = self.rA;
|
|
} else {
|
|
params.zoom /= 100;
|
|
}
|
|
self._onfocus = true;
|
|
if (params.zoom > self.rA && self.rA != self.zoom_max) {
|
|
self.rA = params.zoom;
|
|
self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA;
|
|
} else if (params.zoom < self.rA && self.rA != self.rF) {
|
|
self.rA = params.zoom;
|
|
self.rA = self.rA < self.rF ? self.rF : self.rA;
|
|
}
|
|
self.transOffX = self.transOffY = 0;
|
|
self.setDraggedPos(params.x === undefined || params.x === '' ? "" : (-params.x * self.rA) + (self.sW / 2), params.y === undefined || params.y === '' ? "" : (-params.y * self.rA) + (self.sH / 2), self.rA);
|
|
self.reduction = params.speed ? params.speed / 10 : self.focusSpeed;
|
|
self._recent = 'drag';
|
|
self._dragging = true;
|
|
if (!self._playing) {
|
|
self.Animate();
|
|
}
|
|
}
|
|
},
|
|
|
|
zoomIn: function (params) {
|
|
this.buttons[0].$ob.trigger(this.event_down, {
|
|
id: 0
|
|
});
|
|
},
|
|
|
|
zoomOut: function (params) {
|
|
this.buttons[1].$ob.trigger(this.event_down, {
|
|
id: 1
|
|
});
|
|
},
|
|
|
|
moveRight: function (params) {
|
|
this.buttons[2].$ob.trigger(this.event_down, {
|
|
id: 2
|
|
});
|
|
},
|
|
|
|
moveLeft: function (params) {
|
|
this.buttons[3].$ob.trigger(this.event_down, {
|
|
id: 3
|
|
});
|
|
},
|
|
|
|
moveUp: function (params) {
|
|
this.buttons[4].$ob.trigger(this.event_down, {
|
|
id: 4
|
|
});
|
|
},
|
|
|
|
moveDown: function (params) {
|
|
this.buttons[5].$ob.trigger(this.event_down, {
|
|
id: 5
|
|
});
|
|
},
|
|
|
|
Reset: function (params) {
|
|
this.buttons[6].$ob.trigger(this.event_down, {
|
|
id: 6
|
|
});
|
|
},
|
|
|
|
getZoomData: function (params) {
|
|
return {
|
|
//x offset (without scale ratio multiplied)
|
|
normX: (-this._x / this.rA).toFixed(14),
|
|
|
|
//y offset (without scale ratio multiplied)
|
|
normY: (-this._y / this.rA).toFixed(14),
|
|
|
|
//Original image Width
|
|
normWidth: this.iW,
|
|
|
|
//Original image height
|
|
normHeight: this.iH,
|
|
|
|
//x offset (with scale ratio multiplied)
|
|
scaledX: -this._x.toFixed(14),
|
|
|
|
//y offset (with scale ratio multiplied)
|
|
scaledY: -this._y.toFixed(14),
|
|
|
|
//Scaled image width
|
|
scaledWidth: this._w,
|
|
|
|
//Scaled image height
|
|
scaledHeight: this._h,
|
|
|
|
//The X location on image which is currently on center of canvas
|
|
centerX: (-this._x.toFixed(14) + (this.sW / 2)) / this.rA,
|
|
|
|
//The Y location on image which is currently on center of canvas
|
|
centerY: (-this._y.toFixed(14) + (this.sH / 2)) / this.rA,
|
|
|
|
//Scale ratio
|
|
ratio: this.rA
|
|
};
|
|
},
|
|
|
|
addLandmark: function (loc) {
|
|
if (this.$loc_cont) {
|
|
var total = loc.length;
|
|
|
|
for (var i = 0; i < total; i++) {
|
|
var $loc = $(loc[i]);
|
|
this.$loc_cont.append($loc);
|
|
this.setLocation($loc);
|
|
}
|
|
|
|
if (total > 0) {
|
|
this.updateLocations(this._x, this._y, this._sc, this.locations);
|
|
}
|
|
}
|
|
},
|
|
|
|
attachLandmark: function (loc) {
|
|
if (this.$loc_cont) {
|
|
var total = loc.length;
|
|
for (var i = 0; i < total; i++) {
|
|
this.setLocation(loc[i] instanceof jQuery ? loc[i] : $('#' + loc[i]));
|
|
}
|
|
if (total > 0) {
|
|
this.updateLocations(this._x, this._y, this._sc, this.locations);
|
|
}
|
|
}
|
|
},
|
|
|
|
removeLandmark: function (loc) {
|
|
if (this.$loc_cont) {
|
|
if (loc) {
|
|
var total = loc.length;
|
|
for (var i = 0; i < total; i++) {
|
|
for (var j = 0; j < this.locations.length; j++) {
|
|
if ((loc[i] instanceof jQuery && this.locations[j].ob[0] == loc[i][0]) || (!(loc[i] instanceof jQuery) && this.locations[j].ob.attr('id') == loc[i])) {
|
|
this.locations[j].ob.remove();
|
|
this.locations.splice(j, 1);
|
|
j--;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (this.locations.length > 0) {
|
|
this.locations[this.locations.length - 1].ob.remove();
|
|
this.locations.pop();
|
|
}
|
|
}
|
|
if (total > 0) {
|
|
this.updateLocations(this._x, this._y, this._sc, this.locations);
|
|
}
|
|
}
|
|
},
|
|
|
|
refreshAllLandmarks: function () {
|
|
var self = this;
|
|
var locs = self.$loc_cont.children('.item');
|
|
self.show_at_zoom = parseInt(self.$loc_cont.data('show-at-zoom'), 10) / 100;
|
|
self.allow_scale = checkBoolean(self.$loc_cont.data('allow-scale'));
|
|
self.allow_drag = checkBoolean(self.$loc_cont.data('allow-drag'));
|
|
|
|
//Step 1: Remove records for which the elements no longer exist
|
|
for (var i = 0; i < self.locations.length; i++) {
|
|
var exists = false;
|
|
locs.each(function () {
|
|
if (self.locations[i].ob[0] == $(this)[0]) {
|
|
exists = true;
|
|
}
|
|
});
|
|
if (!exists) {
|
|
self.locations.splice(i, 1);
|
|
i--;
|
|
}
|
|
}
|
|
|
|
//Step 2: Add new elements to record
|
|
locs.each(function () {
|
|
var exists = false;
|
|
for (var i = 0; i < self.locations.length; i++) {
|
|
if (self.locations[i].ob[0] == $(this)[0]) {
|
|
exists = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!exists) {
|
|
self.setLocation($(this));
|
|
}
|
|
|
|
});
|
|
this.updateLocations(this._x, this._y, this._sc, this.locations);
|
|
},
|
|
|
|
|
|
/*On windows resize, adjust some defaults
|
|
***********************************************************************************************************************/
|
|
resize: function (e) {
|
|
var self;
|
|
|
|
if (e.data) {
|
|
e.preventDefault();
|
|
self = e.data.self;
|
|
var pw = self.$holder.parent().width();
|
|
var ph = self.$holder.parent().height();
|
|
|
|
if (self.oW) {
|
|
pw = Math.min(pw, self.oW);
|
|
}
|
|
self.sW = pw;
|
|
|
|
if (self.oH) {
|
|
if (self.oW && self.maintain_ratio) {
|
|
self.sH = pw / (self.oW / self.oH);
|
|
}
|
|
} else {
|
|
self.sH = ph;
|
|
}
|
|
|
|
|
|
} else {
|
|
self = this;
|
|
if (e.width) {
|
|
self.sW = e.width;
|
|
}
|
|
if (e.height) {
|
|
self.sH = e.height;
|
|
}
|
|
if (e.max_WIDTH) {
|
|
self.w_max = e.max_WIDTH;
|
|
}
|
|
if (e.max_HEIGHT) {
|
|
self.h_max = e.max_HEIGHT;
|
|
}
|
|
}
|
|
if (self.w_max !== 0 && self.w_max !== '') {
|
|
self.sW = Math.min(self.sW, self.w_max);
|
|
}
|
|
if (self.h_max !== 0 && self.h_max !== '') {
|
|
self.sH = Math.min(self.sH, self.h_max);
|
|
}
|
|
self.$holder.css({
|
|
'width': self.sW,
|
|
'height': self.sH
|
|
});
|
|
if (self.bord_size > 0) {
|
|
self.border[0].height(self.sH);
|
|
self.border[1].css({
|
|
height: self.sH,
|
|
left: self.sW - self.bord_size
|
|
});
|
|
self.border[2].width(self.sW - (self.bord_size * 2));
|
|
self.border[3].css({
|
|
width: self.sW - (self.bord_size * 2),
|
|
top: self.sH - self.bord_size
|
|
});
|
|
}
|
|
if (self.bu_align[1] == 'center') {
|
|
self.$controls.css('left', parseInt((self.sW - self.cBW) / 2));
|
|
}
|
|
if (self.bu_align[0] == 'center') {
|
|
self.$controls.css('top', parseInt((self.sH - self.cBH) / 2));
|
|
}
|
|
self.rF = self.rR = self.checkRatio(self.sW, self.sH, self.iW, self.iH, self.zoom_fit);
|
|
if (self.zoom_min == 0) {
|
|
if (self.rA < self.rF) {
|
|
self.rA = self.rF;
|
|
}
|
|
}
|
|
|
|
self.focusTo({
|
|
x: self.cX,
|
|
y: self.cY,
|
|
zoom: '',
|
|
speed: 10
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
$.fn.smoothZoom = function (params) {
|
|
var self = this;
|
|
var l = self.length;
|
|
|
|
//For single or more than one plugin instance
|
|
for (var i = 0; i < l; i++) {
|
|
var $elem = $(self[i]);
|
|
var instance = $elem.data('smoothZoom');
|
|
|
|
// Case 1: Initiate the plugin if not already have an instance
|
|
if (!instance) {
|
|
|
|
if (typeof params === 'object' || !params) {
|
|
$elem.data('smoothZoom', new Zoomer($elem, params));
|
|
}
|
|
|
|
// Case 2: If the instance already available - Check for method call
|
|
} else {
|
|
|
|
// getZoomData - Returns {sourceX, sourceY, sourceWidth, sourceHeight, distX, distY, distWidth, distHeight, centerX, centerY, ratio}
|
|
if (params == "getZoomData") {
|
|
return instance[params].apply(instance, Array.prototype.slice.call(arguments, 1));
|
|
|
|
// destroy | focusTo | zoomIn | zoomOut | moveRight| moveLeft | moveUp | moveDown | Reset | addLandmark | removeLandmark | attachLandmark | refreshAllLandmarks
|
|
} else if (instance[params]) {
|
|
instance[params].apply(instance, Array.prototype.slice.call(arguments, 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
//return for chainability for possible cases
|
|
if (params !== "getZoomData") {
|
|
return this;
|
|
}
|
|
};
|
|
|
|
function checkBoolean(_var) {
|
|
if (_var === true) {
|
|
return true;
|
|
} else if (_var) {
|
|
_var = _var.toLowerCase();
|
|
if (_var == 'yes' || _var == 'true') {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
//...................................................................................................................
|
|
//Using Modernizr to check browser capabilities and property names prefixed
|
|
|
|
/* Modernizr 2.5.3 (Custom Build) | MIT & BSD
|
|
* Build: http://www.modernizr.com/download/#-borderradius-csstransforms-csstransforms3d-touch-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes
|
|
*/
|
|
var Modernizr = function (a, b, c) { function y(a) { i.cssText = a } function z(a, b) { return y(l.join(a + ";") + (b || "")) } function A(a, b) { return typeof a === b } function B(a, b) { return !!~("" + a).indexOf(b) } function C(a, b) { for (var d in a) if (i[a[d]] !== c) return b == "pfx" ? a[d] : !0; return !1 } function D(a, b, d) { for (var e in a) { var f = b[a[e]]; if (f !== c) return d === !1 ? a[e] : A(f, "function") ? f.bind(d || b) : f } return !1 } function E(a, b, c) { var d = a.charAt(0).toUpperCase() + a.substr(1), e = (a + " " + n.join(d + " ") + d).split(" "); return A(b, "string") || A(b, "undefined") ? C(e, b) : (e = (a + " " + o.join(d + " ") + d).split(" "), D(e, b, c)) } var d = "2.5.3", e = {}, f = b.documentElement, g = "modernizr", h = b.createElement(g), i = h.style, j, k = {}.toString, l = " -webkit- -moz- -o- -ms- ".split(" "), m = "Webkit Moz O ms", n = m.split(" "), o = m.toLowerCase().split(" "), p = {}, q = {}, r = {}, s = [], t = s.slice, u, v = function (a, c, d, e) { var h, i, j, k = b.createElement("div"), l = b.body, m = l ? l : b.createElement("body"); if (parseInt(d, 10)) while (d--) j = b.createElement("div"), j.id = e ? e[d] : g + (d + 1), k.appendChild(j); return h = ["­", "<style>", a, "</style>"].join(""), k.id = g, (l ? k : m).innerHTML += h, m.appendChild(k), l || (m.style.background = "", f.appendChild(m)), i = c(k, a), l ? k.parentNode.removeChild(k) : m.parentNode.removeChild(m), !!i }, w = {}.hasOwnProperty, x; !A(w, "undefined") && !A(w.call, "undefined") ? x = function (a, b) { return w.call(a, b) } : x = function (a, b) { return b in a && A(a.constructor.prototype[b], "undefined") }, Function.prototype.bind || (Function.prototype.bind = function (b) { var c = this; if (typeof c != "function") throw new TypeError; var d = t.call(arguments, 1), e = function () { if (this instanceof e) { var a = function () { }; a.prototype = c.prototype; var f = new a, g = c.apply(f, d.concat(t.call(arguments))); return Object(g) === g ? g : f } return c.apply(b, d.concat(t.call(arguments))) }; return e }); var F = function (c, d) { var f = c.join(""), g = d.length; v(f, function (c, d) { var f = b.styleSheets[b.styleSheets.length - 1], h = f ? f.cssRules && f.cssRules[0] ? f.cssRules[0].cssText : f.cssText || "" : "", i = c.childNodes, j = {}; while (g--) j[i[g].id] = i[g]; e.touch = "ontouchstart" in a || a.DocumentTouch && b instanceof DocumentTouch || (j.touch && j.touch.offsetTop) === 9, e.csstransforms3d = (j.csstransforms3d && j.csstransforms3d.offsetLeft) === 9 && j.csstransforms3d.offsetHeight === 3 }, g, d) }([, ["@media (", l.join("touch-enabled),("), g, ")", "{#touch{top:9px;position:absolute}}"].join(""), ["@media (", l.join("transform-3d),("), g, ")", "{#csstransforms3d{left:9px;position:absolute;height:3px;}}"].join("")], [, "touch", "csstransforms3d"]); p.touch = function () { return e.touch }, p.borderradius = function () { return E("borderRadius") }, p.csstransforms = function () { return !!E("transform") }, p.csstransforms3d = function () { var a = !!E("perspective"); return a && "webkitPerspective" in f.style && (a = e.csstransforms3d), a }; for (var G in p) x(p, G) && (u = G.toLowerCase(), e[u] = p[G](), s.push((e[u] ? "" : "no-") + u)); return y(""), h = j = null, e._version = d, e._prefixes = l, e._domPrefixes = o, e._cssomPrefixes = n, e.testProp = function (a) { return C([a]) }, e.testAllProps = E, e.testStyles = v, e.prefixed = function (a, b, c) { return b ? E(a, b, c) : E(a, "pfx") }, e }(this, this.document);
|
|
|
|
var prop_transform = Modernizr.prefixed('transform');
|
|
var prop_origin = Modernizr.prefixed('transformOrigin');
|
|
var prop_radius = Modernizr.prefixed('borderRadius');
|
|
var supportsTrans3D = Modernizr.csstransforms3d;
|
|
var supportsTouch = Modernizr.touch;
|
|
|
|
})(jQuery, window, document);
|
|
|
|
//End - smoothZoom
|
|
|
|
//...................................................................................................................
|
|
//For mouse wheel support
|
|
|
|
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
|
* Licensed under the MIT License (LICENSE.txt).
|
|
*
|
|
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
|
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
|
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
|
*
|
|
* Version: 3.0.6
|
|
*
|
|
* Requires: 1.2.2+
|
|
*/
|
|
(function (a) { function d(b) { var c = b || window.event, d = [].slice.call(arguments, 1), e = 0, f = !0, g = 0, h = 0; return b = a.event.fix(c), b.type = "mousewheel", c.wheelDelta && (e = c.wheelDelta / 120), c.detail && (e = -c.detail / 3), h = e, c.axis !== undefined && c.axis === c.HORIZONTAL_AXIS && (h = 0, g = -1 * e), c.wheelDeltaY !== undefined && (h = c.wheelDeltaY / 120), c.wheelDeltaX !== undefined && (g = -1 * c.wheelDeltaX / 120), d.unshift(b, e, g, h), (a.event.dispatch || a.event.handle).apply(this, d) } var b = ["DOMMouseScroll", "mousewheel"]; if (a.event.fixHooks) for (var c = b.length; c;) a.event.fixHooks[b[--c]] = a.event.mouseHooks; a.event.special.mousewheel = { setup: function () { if (this.addEventListener) for (var a = b.length; a;) this.addEventListener(b[--a], d, !1); else this.onmousewheel = d }, teardown: function () { if (this.remove_eventListener) for (var a = b.length; a;) this.remove_eventListener(b[--a], d, !1); else this.onmousewheel = null } }, a.fn.extend({ mousewheel: function (a) { return a ? this.bind("mousewheel", a) : this.trigger("mousewheel") }, unmousewheel: function (a) { return this.unbind("mousewheel", a) } }) })(jQuery)
|
|
|
|
//...................................................................................................................
|