(function ($) {
$.fn.ImageViewer = function( options ) {
var settings = $.extend({
imageSource: "",
frame: ['720px','480px'],
imageSize: ['720px','480px'],
maxZoom: '300%',
zoomFactor: '10%',
setZoomPos: [],
mouse: true,
keyboard: true,
}, options );
var viewer = {
zoomIn: function() {
var frameDimension = self.getFrameSize();
self.zoomTo(self.getZoomLevel()+1, frameDimension[0]/2,frameDimension[1]/2);
}
}
var nextPageFunc
var prevPageFunc
var beginInstantPageFunc
var imageSource = settings.imageSource;
var frame = settings.frame;
var imageSize = settings.imageSize;
var maxZoom = settings.maxZoom;
var zoomFactor = settings.zoomFactor;
var setZoomPos = settings.setZoomPos;
var isMouse = settings.mouse;
var isKeyboard = settings.keyboard;
var self = this;
//var $result = $(this);
var parent = $(this)[0];
var divId = parent.id;
var image = null;
var rotateAngle = 0;
self.frameElement = null;
var orignalW,orignalH, zoomLevel = 0;
var lastMousePosition = null, speed = 5;
var mouseWheelObject = null;
//console.log(self,"\n",parent)
// container가 존재하면 rest하고 img path만 교체한다.
if( parent.firstElementChild != null && parent.firstElementChild.id == 'image_viewer_inner_container' ) {
// image.src를 변경한다.
$(self)[0].firstElementChild.firstElementChild.firstElementChild.src = imageSource
return;
}
// 이미지 교체
self.changeImageSrc = function(src) {
if( parent.firstElementChild != null && parent.firstElementChild.id == 'image_viewer_inner_container' ) {
$("#image_viewer_inner_container").css("width", self.frame[0])
$("#image_viewer_inner_container").css("height", self.frame[1])
// image.src를 변경한다.
$(self)[0].firstElementChild.firstElementChild.firstElementChild.src = src
return;
}
}
/*Methods*/
self.getFrameSize = function() {
return [self.frameElement.clientWidth, self.frameElement.clientHeight];
}
self.setImageSize = function(width,height) { //width and height of image
image.width=Math.round(width);
image.height=Math.round(height);
}
self.getImageSize = function() {
return [image.width, image.height];
}
self.getImageNaturalSize = function() {
return [image.naturalWidth, image.naturalHeight];
}
self.setPosition = function(x,y) { //x and y coordinate of image
image.style.left=(Math.round(x)+'px');
image.style.top=(Math.round(y)+'px');
}
self.getPosition = function() {
return [retInt(image.style.left,'px'),retInt(image.style.top,'px')];
}
self.setMouseCursor = function() {
var dimension = self.getImageSize();
var frameDimension = self.getFrameSize();
var cursor='crosshair';
if(dimension[0]>frameDimension[0] && dimension[1]>frameDimension[1])
cursor='move';
else if(dimension[0]>frameDimension[0])
cursor='e-resize';
else if(dimension[1]>frameDimension[1])
cursor='n-resize';
image.style.cursor=cursor;
}
self.setupKeyboardEvent = function() {
if(isKeyboard == false) { return }
self.frameElement.onkeypress = self.onkeypress;
self.frameElement.onkeyup = self.onkeyup;
}
self.setupMouseWheel = function() {
if (isMouse == false) { return }
mouseWheelObject = new mouseWheel();
mouseWheelObject.init(image, self.onmousewheel);
image.onmousedown = self.onmousedown;
}
self.maxZoomCheck = function(width,height) {
if(typeof width=='undefined' || typeof height=='undefined') {
var temp = self.getImageSize();
width=temp[0], height=temp[1];
}
if(typeof maxZoom=='number') {
return ((width/orignalW)>maxZoom || (height/orignalH)>maxZoom);
}
else if(typeof maxZoom=='object') {
return (width>maxZoom[0] || height>maxZoom[1]);
}
}
self.fitToFrame = function(width, height) { //width and height of image
var newWidth = width, newHeight = height;
var frameSize = self.getFrameSize()
if (width > frameSize[0]) { // landscape image
newWidth = frameSize[0]
newHeight = Math.round((newWidth / width) * height)
if (newHeight > frameSize[1]) {
newHeight = frameSize[1]
newWidth = Math.round((newHeight / height) * width)
}
} else if (height > frameSize[1]) { // portrait image
newHeight = frameSize[1]
newWidth = Math.round((newHeight / height) * width)
if (newWidth > frameSize[0]) {
newWidth = frameSize[0]
newHeight = Math.round((newWidth / width) * height)
}
}
return [newWidth, newHeight]
}
self.getZoomLevel = function() {
return zoomLevel;
}
self.getCookieForZoomLevel = function() {
var zlv = Cookies.get('zoomLevel');
if (isUndefined(zlv)) {
return -1
}
return zlv
}
self.setCookieForZoomLevel = function(level) {
Cookies.set('zoomLevel', level)
}
self.zoomTo = function(newZoomLevel, x, y) {
var frameDimension = self.getFrameSize();
//check if x and y coordinate is within the self.frameElement
// x width의 절반을 넘지 못하게, y height의 절반을 넘지 못하게
if(newZoomLevel<0 || x<0 || y<0 || x>=frameDimension[0] || y>=frameDimension[1])
return false;
var dimension = self.fitToFrame(orignalW,orignalH);
for(var i=newZoomLevel; i>0;i--)
dimension[0] *= zoomFactor,
dimension[1] *= zoomFactor;
//Calculate percentage increase/decrease and fix the image over given x,y coordinate
var curWidth=image.width, curHeight=image.height;
var position = self.getPosition();
console.log("x: " + x + " y: " + y + " frameW: " + frameDimension[0] + " frameH: " + frameDimension[1])
console.log("zoomFactor: " + zoomFactor + " curW:"+curWidth+" curH"+curHeight+" dimension: " + dimension[0] + " dimension: " + dimension[0])
position[0]-=((x-position[0])*((dimension[0]/curWidth)-1)),
position[1]-=((y-position[1])*((dimension[1]/curHeight)-1));
position = self.centerImage(dimension[0],dimension[1], position[0],position[1]);
//Set dimension and position
if(!self.maxZoomCheck(dimension[0],dimension[1])) {
self.setZoomPosition(newZoomLevel,dimension[0],dimension[1],position[0],position[1]);
} else {
return false;
}
return true;
}
// 확대
self.zoomIn = function(curDimension) {
var imageDimension = curDimension;
imageDimension[0] *= zoomFactor,
imageDimension[1] *= zoomFactor;
var position = self.getPosition();
position = self.centerImage(imageDimension[0],imageDimension[1], position[0],position[1]);
if(!self.maxZoomCheck(imageDimension[0],imageDimension[1])) {
self.setZoomPosition(imageDimension[0],imageDimension[1],position[0],position[1]);
} else {
return false;
}
return true;
}
// 축소
self.zoomOut = function(curDimension) {
var imageDimension = curDimension;
imageDimension[0] *=(2.0 - zoomFactor),
imageDimension[1] *= (2.0 - zoomFactor);
if (imageDimension[0] <= 250) { return }
var position = self.getPosition();
position = self.centerImage(imageDimension[0],imageDimension[1], position[0],position[1]);
if(!self.maxZoomCheck(imageDimension[0],imageDimension[1])) {
self.setZoomPosition(imageDimension[0],imageDimension[1],position[0],position[1]);
} else {
return false;
}
return true;
}
self.actualSize = function() {
self.setImageSize(image.naturalWidth, image.naturalHeight);
var pos = self.centerImage(image.naturalWidth, image.naturalHeight, 0,0);
self.setPosition(pos[0],pos[1]);
}
// self.setZoomPosition = function(zoomLvl,dX,dY,pX ,pY){
// zoomLevel = parseInt(zoomLvl);
// console.log("zoomLevel: " + zoomLevel)
// self.setImageSize(dX,dY);
// console.log("setZoomPos: dX="+dX+", dY="+dY+" pX="+pX+" PY="+pY);
// self.setPosition(pX,pY);
// self.setMouseCursor();
// self.setCookieForZoomLevel(zoomLevel)
// }
self.setZoomPosition = function(dX,dY,pX ,pY){
self.setImageSize(dX,dY);
console.log("setZoomPos: dX="+dX+", dY="+dY+" pX="+pX+" PY="+pY);
self.setPosition(pX,pY);
self.setMouseCursor();
}
self.getZoomInf = function(){
var dim_array = self.getImageSize();
var pos_array = self.getPosition();
console.log("[zoomLevel, dimensionX, dimensionY, positionX, positionY]=");
console.log("[",zoomLevel,",",dim_array[0],",",dim_array[1],",",pos_array[0],",",pos_array[1],"]");
//console.log($("#"+divId + " .image_pos_info").length)
//$("#"+divId).append('
חדששש
');
}
//width and height of image and (x,y) is the (left,top) of the image
self.centerImage = function(width, height, x, y) {
if(typeof width=='undefined' || typeof height=='undefined') {
var temp = self.getImageSize();
width=temp[0], height=temp[1];
}
if(typeof x=='undefined' || typeof y=='undefined') {
var temp = self.getPosition();
x=temp[0], y=temp[1];
}
// return [self.frameElement.clientWidth, self.frameElement.clientHeight];
var frameDimension = self.getFrameSize();
if(width <= frameDimension[0])
x = Math.round((frameDimension[0] - width)/2);
if(height <= frameDimension[1])
y = Math.round((frameDimension[1] - height)/2);
if(width>frameDimension[0]) {
if(x>0)
x=0;
else
if((x+width)frameDimension[1]) {
if(y>0)
y=0;
else
if((y+height) -1
}
function isWindows() {
return navigator.platform.indexOf('Win') > -1
}
/*Event handlers*/
self.onmousewheel = function(event,object,direction) {
self.frameElement.focus();
if (!event){ //For IE
event = window.event, event.returnValue = false;
}else if (event.preventDefault){
event.preventDefault();
}
// if((zoomLevel+direction)>=0) {
// var mousePos = getMouseXY(event);
// var framePos = getObjectXY(self.frameElement);
// self.zoomTo(zoomLevel+direction, mousePos[0]-framePos[0], mousePos[1]-framePos[1]);
// }
if (direction < 0) {
var imageSize = ImageViewer.getImageSize();
if (isMacintosh()) {
self.zoomOut(imageSize);
} else {
self.zoomIn(imageSize);
}
} else {
var imageSize = ImageViewer.getImageSize();
if (isMacintosh()) {
self.zoomIn(imageSize);
} else {
self.zoomOut(imageSize);
}
}
}
self.onmousemove = function(event) {
if (!event){ //For IE
event = window.event, event.returnValue = false;
}else if (event.preventDefault){
event.preventDefault();
}
var mousePosition = getMouseXY(event);
//return [retInt(image.style.left,'px'),retInt(image.style.top,'px')];
var position = self.getPosition();
position[0] += (mousePosition[0]-lastMousePosition[0])
position[1] += (mousePosition[1]-lastMousePosition[1])
lastMousePosition = mousePosition;
//position = self.centerImage(image.width, image.height, position[0], position[1]);
var frame = self.getFrameSize()
// x좌표 벗어나지 않게
if (position[0] > 0) {
if (position[0] > frame[0] * 2 / 3) { return }
} else {
var imgSize = self.getImageSize()
if (imgSize[0] + position[0] < frame[0] / 3) { return }
}
// y좌표 벗어나지 않게
if (position[1] > 0) {
if (position[1] > frame[1] * 2 / 3) { return }
} else {
var imgSize = self.getImageSize()
if (imgSize[1] + position[1] < frame[1] / 3) { return }
}
self.setPosition(position[0], position[1]);
}
var DELAY = 300, clicks = 0, timer = null;
var rightClicks = 0, rightTimer = null;
self.onmouseup_or_out = function(event) {
if (!event){ //For IE
event = window.event, event.returnValue = false;
}else if (event.preventDefault){
event.preventDefault();
}
if (event.which == 3) { // 우측 마우스 버튼
rightClicks++
if (rightClicks == 1) { // single click
rightTimer = setTimeout(function() {
rightClicks = 0
}, DELAY)
} else { // dbl click
clearTimeout(rightTimer)
rightClicks = 0
console.log("Right Button Double Click");
}
}
image.onmousemove = image.onmouseup = image.onmouseout = null;
image.onmousedown = self.onmousedown;
}
self.onmousedown = function(event) {
self.frameElement.focus();
if (!event){ //For IE
event = window.event, event.returnValue = false;
}else if (event.preventDefault){
event.preventDefault();
}
clicks++;
if(clicks === 1) { // single click
timer = setTimeout(function() {
clicks = 0;
}, DELAY);
} else { // dbl click
clearTimeout(timer);
console.log("Double Click");
(self.nextPageFunc)();
clicks = 0;
}
lastMousePosition = getMouseXY(event);
image.onmousemove = self.onmousemove;
image.onmouseup = image.onmouseout = self.onmouseup_or_out;
// image.onmouseup = self.onmouseup_or_out;
// image.click = self.onClick;
}
self.onkeydown = function(event) {
if (event.target.id == 'w2int' || event.target.id == 'searchWord') { return }
var position = self.getPosition();
switch (event.which) {
case 39: // Right
position[0] -= speed;
break;
case 37: // Left
position[0]+=speed;
break;
case 38: // Up
position[1] += speed;
break;
case 40: // Down
position[1] -= speed;
break;
case 13: // enter
//self.reset()
(self.beginInstantPageFunc)()
break;
default:
break;
}
position = self.centerImage(image.width,image.height, position[0],position[1]);
self.setPosition(position[0],position[1]);
speed += 2;
}
// self.onkeypress = function(event) {
//
// if (event.target.id == 'w2int' || event.target.id == 'searchWord') { return }
//
// var keyCode;
// // if(window.event){ // IE
// // event = window.event, keyCode = event.keyCode, event.returnValue = false;
// // } else if(event.which){
// // keyCode = event.which, event.preventDefault();
// // }
// keyCode = event.which, event.preventDefault();
// keyCode = String.fromCharCode(keyCode);
// var position = self.getPosition();
// var LEFT='a',UP='w',RIGHT='d',DOWN='s', CENTER_IMAGE='c', ZOOMIN='=', ZOOMOUT='-' , ZOOM_INFO='i'; ///Keys a,w,d,s
// if(keyCode == LEFT){
// position[0]+=speed;
// }else if(keyCode == UP){
// position[1] += speed;
// }else if(keyCode == RIGHT){
// position[0] -= speed;
// }else if(keyCode==DOWN){
// position[1] -= speed;
// }else if(keyCode == CENTER_IMAGE || keyCode == 'C'){
// self.reset();
// }else if(keyCode == ZOOMIN || keyCode == '+' || keyCode == 'x' || keyCode == 'X'){
// self.zoomTo(zoomLevel+1, self.frameElement.clientWidth/2, self.frameElement.clientHeight/2);
// }else if( (keyCode == ZOOMOUT || keyCode == 'z' || keyCode == 'Z') && zoomLevel > 0){
// self.zoomTo(zoomLevel-1, self.frameElement.clientWidth/2, self.frameElement.clientHeight/2);
// }else if(keyCode==ZOOM_INFO || keyCode == 'I'){
// self.getZoomInf();
// }
// if(keyCode == LEFT || keyCode == UP || keyCode == RIGHT || keyCode == DOWN) {
// position = self.centerImage(image.width,image.height, position[0], position[1]);
// self.setPosition(position[0],position[1]);
// speed += 2;
// }
// }
self.onkeyup = function(event) {
speed = 5;
}
/*Initializaion*/
self.setZoomProp = function(newZoomFactor,newMaxZoom) {
if(newZoomFactor == null){
zoomFactor = 10;
}
zoomFactor = 1 + retInt(newZoomFactor,'%')/100;
if(typeof newMaxZoom == 'string'){
maxZoom = retInt(newMaxZoom,'%')/100;
}else if(typeof newMaxZoom == 'object' && newMaxZoom != null) {
maxZoom[0] = retInt(newMaxZoom[0],'px');
maxZoom[1] = retInt(newMaxZoom[1],'px');
}else{
maxZoom = '300%';
}
}
self.initImage = function() {
if (image.width == 0 && image.height == 0) {
//image.width = self.imageSize[0] // drawPages에서 한 페이지의 w,h
//image.height = self.imageSize[1]
if (image.naturalWidth == 0 && image.naturalHeight == 0) {
image.width = self.imageSize[0] // drawPages에서 한 페이지의 w,h
image.height = self.imageSize[1]
} else {
image.width = image.naturalWidth
image.height = image.naturalHeight
}
}
orignalW = image.width;
orignalH = image.height;
// var dimension = self.fitToFrame(image.width, image.height);
// self.setImageSize(dimension[0], dimension[1]);
// var pos = self.centerImage(dimension[0],dimension[1], 0,0);
// self.setPosition(pos[0],pos[1]);
self.setMouseCursor();
self.setupMouseWheel();
self.setupKeyboardEvent();
if(setZoomPos.length == 5){
var zLvl = setZoomPos[0];
var dimX = setZoomPos[1];
var dimY = setZoomPos[2];
var posX = setZoomPos[3];
var posY = setZoomPos[4];
//self.setZoomPosition(zLvl,dimX, dimY,posX, posY);
self.setZoomPosition(dimX, dimY,posX, posY);
} else if(setZoomPos.length > 0 && setZoomPos.length < 5){
console.log("Error: 'setZoomPos' setting array must contain 5 numbers: [zoomLevel, dimensionX, dimensionY, positionX, positionY].'\n" +
"click 'i' key after zooming the image to see this information in the console.")
}
// 실제 이미지의 종횡비로 보정을 해준다.
var naturalSize = ImageViewer.getImageNaturalSize();
var horRate = naturalSize[0] / naturalSize[1];
var newImageSize = [image.width, image.height]
newImageSize[0] = newImageSize[1] * horRate; // 가로 * 세로배율
self.setImageSize(newImageSize[0], newImageSize[1]); // image.width/height 수정
var pos = self.centerImage(image.width, image.height, 0,0);
self.setPosition(pos[0],pos[1]);
return
// 원본크기로 츌력하기
var level = self.getCookieForZoomLevel()
if (level < 0) {
self.setImageSize(image.naturalWidth, image.naturalHeight);
var pos = self.centerImage(image.naturalWidth, image.naturalHeight, 0,0);
self.setPosition(pos[0],pos[1]);
level = parseInt((image.width / orignalW - 1.0) * 10)
self.setCookieForZoomLevel(level)
} else {
// 현재 줌 레벨로 이미지의 배율 적용하기
/*
var dimension = self.fitToFrame(orignalW,orignalH);
var resizingW = dimension[0];
var resizingH = dimension[1];
for(var i=level; i>0;i--)
resizingW *= zoomFactor,
resizingH *= zoomFactor;
self.setImageSize(resizingW, resizingH);
var pos = self.centerImage(resizingW, resizingH, 0,0);
self.setPosition(pos[0],pos[1]);
*/
//var frame = self.getFrameSize()
var pos = self.centerImage(image.width, image.height, 0,0);
self.setPosition(pos[0],pos[1]);
}
}
self.frameElement = document.createElement('div');
self.frameElement.id = 'image_viewer_inner_container';
self.frameElement.className = 'image_viewer_inner_container';
self.frameElement.style.width = frame[0];
self.frameElement.style.height = frame[1];
self.frameElement.style.border="0px solid #000";
self.frameElement.style.margin="0px";
self.frameElement.style.padding="0px";
self.frameElement.style.overflow="visible";
self.frameElement.style.position="relative";
self.frameElement.style.zIndex=2;
self.frameElement.tabIndex=1;
/*Set a base*/
self.setZoomProp(zoomFactor,maxZoom);
if(image!=null) {
if (parent != null) {
image.parentNode.removeChild(image);
parent.appendChild(self.frameElement);
}else{
image.parentNode.replaceChild(self.frameElement,image);
}
image.style.margin=image.style.padding="0";
image.style.borderWidth="0px";
image.style.position='absolute';
image.style.zIndex=3;
self.frameElement.appendChild(image);
//if(imageSource!=null)
// self.preInitImage();
//else
// self.initImage();
} else {
if(parent!=null) {
parent.appendChild(self.frameElement);
}
self.frameElement.style.width = frame[0];
self.frameElement.style.height = frame[1];
var div_imge_container = document.createElement('div');
div_imge_container.className = 'jqvsiv_main_image_content';
image = document.createElement('img');
image.style.position='absolute';
image.style.zIndex=3;
div_imge_container.appendChild(image);
self.frameElement.appendChild(div_imge_container);
$("#image_viewer_inner_container").css("width", frame[0])
$("#image_viewer_inner_container").css("height",frame[1])
image.onload = self.initImage;
image.src = imageSource;
}
return this
}
function getObjectXY(object) {
var left,top;
objectCopy=object;
if (object.offsetParent) {
left=top=0;
do {
left += object.offsetLeft;
if(object.style.borderLeftWidth!='')
left+=parseInt(object.style.borderLeftWidth);
else
object.style.borderLeftWidth='0px';
top += object.offsetTop;
if(object.style.borderTopWidth!='')
top+=parseInt(object.style.borderTopWidth);
else
object.style.borderTopWidth='0px';
}
while (object = object.offsetParent);
}
return [left-parseInt(objectCopy.style.borderLeftWidth),top-parseInt(objectCopy.style.borderLeftWidth)];
}
function retInt(str, suffix) {
if(typeof str=='number')
return str;
var result=str.indexOf(suffix);
return parseInt(str.substring(0,(result!=-1)?result:str.length))
}
/*Mouse related functions*/
//Used to retrieve the mouse cursor position on screen (but event is needed as argument)
function getMouseXY(event) {
var posx = 0, posy = 0;
if (!event) event = window.event; //firefox
if (event.pageX || event.pageY) {
posx = event.pageX;
posy = event.pageY;
}
else if (event.clientX || event.clientY) { //IE
posx = event.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = event.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
return [posx,posy];
}
function mouseWheel() {
var self=this;
/*Event handlers*/
/*Mouse wheel functions*/
//Default mouse wheel callback function
//Variable local to 'this'
var wheelCallback = function(event,object,delta){
/*Override this function and write your code there*/
/*
delta=-1 when mouse wheel is rolled backwards (towards yourself)
delta=1 when mouse wheel is rolled forward (away from one's self)
Note: Here is where you can call the getMouseXY function using the 'event' argument
*/
}
//Mouse wheel event handler
self.wheelHandler = function (event){
var delta = 0;
if (!event) //For IE
event = window.event;
if (event.wheelDelta) //IE
{
delta = event.wheelDelta/120;
//if (window.opera) delta = -delta; //for Opera...hmm I read somewhere opera 9 need the delta sign inverted...tried in opera 10 and it doesnt require this!?
}
else if (event.detail) //firefox
delta = -event.detail/3;
if (event.preventDefault)
event.preventDefault();
event.returnValue = false;
if (delta)
wheelCallback(event,this,delta); //callback function
}
//Mouse wheel initialization
self.init = function(object,callback) {
if (object.addEventListener) //For firefox
object.addEventListener('DOMMouseScroll', this.wheelHandler, false); //Mouse wheel initialization
//For IE
object.onmousewheel = this.wheelHandler; //Mouse wheel initialization
wheelCallback=callback;
}
this.setCallback = function(callback){
wheelCallback=callback;
}
}
}(jQuery));