(function ( $ ) {
$.fn.finepic = function( pid, options ){
var $this = this;
$this.settings = $.extend({
host: "finepic.sk",
thumbsWidth: 800,
thumbsHeight: 600,
defaultZoomBoxWidth:240,
defaultZoomBoxHeight:200,
startRotate: 0,
boxCss: {
cursor: 'w-resize'
}
}, options);
$this.ready = false;
$this.startRotate = $this.settings.startRotate;;
$this.rotate = $this.startRotate;
$this.init = function(){
// do not touch you stinky lil shit!!!
var width = $this.get(0).clientWidth;
var height = $this.get(0).clientHeight;
$this.product.width = width;
$this.product.height = height;
$this.width = width;
$this.height = height;
if ( width > 0 && height >0 ){
$this.product.load( pid, width, height );
}
return $this;
};
// PRODUCT
$this.product = new function(){
var product = this;
this.pid = pid;
this.total_frames = 90;
this.load = function( pid, width, height ){
this.pid = pid;
this.width = width;
this.height = height;
if (this.pid.length && this.width > 0 && this.height > 0){
this.loadData()
}
};
this.loadData = function(){
$.ajax({
url: 'https://ngn.' + $this.settings.host + '/?v=v2&pid=' + this.pid + '&w=' + this.width + '&h=' + this.height,
dataType: 'json'
}).done( function( product_data ){
$this.product.layers = product_data.layers;
$this.product.total_frames = product_data.total_frames;
$this.product.category_alias = product_data.category_alias;
$this.product.manufacturer_alias = product_data.manufacturer_alias;
$this.product.product_alias = product_data.product_alias;
$this.product.frames = product_data.frames;
$this.events.onLoadData( product_data );
});
return $this;
};
};
//RENDERER
$this.renderer = new function(){
var renderer = this;
renderer.currentFrame = 0;
renderer.hoverBack = true;
renderer.loadedLayers = 0;
this.applyCss = function( css ){
for (i in css){
$this.css( i, css[i] );
}
};
this.prepareLayers = function(){
if ($this.product.layers.length > 0){
renderer.layers = [];
for (i in $this.product.layers){
layer = $this.product.layers[i];
if (layer.url) {
var img = $("
");
img.load(function(e){
renderer.loadedLayers++;
if (renderer.loadedLayers == $this.product.layers.length){
$this.events.onLoadedLayers();
}
});
console.log(img);
img.attr("src", layer.url);
var layerBox = $("
");
layerBox.append(img);
renderer.layers.push(img);
}
}
}
};
this.showCanvas = function(){
renderer.canvas.css({
opacity: 1
});
};
this.prepareViewBox = function(){
var holder = $("");
var introFrame = $("");
var canvas = $("");
var progressBox = $("");
var dragBox = $("");
//css
holder.css({
position: 'relative',
overflow: 'hidden',
width: $this.product.width,
height: $this.product.height
});
holder.addClass("holder");
introFrame.css({
width: $this.width,
height: $this.height,
position: 'absolute',
top: '0',
left: '0',
background: 'url(https://thumb.'+$this.settings.host + '/prods/' + $this.product.category_alias + '/' + $this.product.manufacturer_alias + '/' + $this.product.product_alias + "/cropped/" + $this.width + "x" + $this.height + '/' + $this.product.frames[renderer.currentFrame] + ')'
});
introFrame.addClass("introFrame");
canvas.css({
width: $this.width,
height: $this.height,
position: 'absolute',
top: '0',
left: '0',
opacity: 0
});
canvas.addClass("canvas");
progressBox.css({
width: $this.width,
height: $this.height,
position: 'absolute',
top: 0,
left: 0,
opacity: 1,
background: "url('https://ngn." + $this.settings.host + "/res/progress.gif') 95% 5% no-repeat"
});
progressBox.addClass("progressBox");
dragBox.css({
width: $this.width,
height: $this.height,
position: 'absolute',
top: 0,
left: 0,
background: 'white',
opacity: 0
});
dragBox.addClass("dragBox");
//appending
$this.append(holder);
holder.append(introFrame);
holder.append(canvas);
holder.append(progressBox);
holder.append(dragBox);
renderer.canvas = canvas;
renderer.holder = holder;
renderer.introFrame = introFrame;
renderer.progressBox = progressBox;
renderer.dragBox = dragBox;
};
this.appendLayers = function(){
for ( i=0; i < renderer.layers.length; i++ ){
layer_img = renderer.layers[i];
renderer.canvas.append(layer_img);
}
};
this.setRotate = function( deg ){
$this.rotate = deg % 359;
if ( $this.rotate < 0) $this.rotate += 359;
frame_id = Math.round((($this.product.total_frames - 1) / 359) * $this.rotate);
this.showFrame( frame_id );
};
this.showFrame = function( frame_id ){
renderer.currentFrame = frame_id;
renderer.canvas.css({
left : (-$this.product.width * frame_id)
})
};
this.animRotate = function( deg, time ){
if (!time) time = 250;
$({rot: $this.rotate}).animate({rot: deg},{
duration: time,
step: function(){
renderer.setRotate( this.rot )
}
});
};
this.hideProgressBox = function(){
$this.renderer.progressBox.animate({opacity:0}, 400);
};
// Static functions
this.showStaticBox = function(){
var staticBox = $("");
var holder = $("");
staticBox.css({
width: $this.width,
height: $this.height,
position: 'absolute',
top: '0',
left: '0',
background: 'url(https://thumb.'+$this.settings.host + '/prods/' + $this.product.category_alias + '/' + $this.product.manufacturer_alias + '/' + $this.product.product_alias + "/thumbs/" + $this.width + "x" + $this.height + '/' + $this.product.frames[renderer.currentFrame] + ') center center no-repeat'
});
staticBox.addClass("staticBox");
//css
holder.css({
position: 'relative',
overflow: 'hidden',
width: $this.product.width,
height: $this.product.height
});
holder.addClass("holder");
holder.append( staticBox )
$this.append( holder );
$this.renderer.staticBox = staticBox;
};
return renderer;
};
//ZOOM
$this.zoom = function(){
var zoom = this;
zoom.show = function(){
var current_frame = $this.renderer.currentFrame;
var thumb_name = $this.product.frames[ current_frame ];
var width = $this.settings.thumbsWidth;
var height = $this.settings.thumbsHeight;
var product_alias = $this.product.product_alias;
var category_alias = $this.product.category_alias;
var manufacturer_alias = $this.product.manufacturer_alias;
var thumb_uri = "https://thumb." + $this.settings.host + "/prods/" + category_alias + "/" + manufacturer_alias + "/" + product_alias + "/thumbs/" + width + "x" + height + "/" + thumb_name;
zoom.showBox(
thumb_uri
);
};
zoom.getDimensions = function( img_width, img_height ){
var window_width = $(window).innerWidth() * 0.9;
var window_height = $(window).innerHeight() * 0.9;
var max_width = Math.min( img_width, window_width );
var max_height = Math.min( img_height, window_height );
var ratio = img_width / img_height;
if (window_width / window_height > ratio ){
var width = max_height * ratio;
var height = max_height;
}else{
var width = max_width;
var height = max_width / ratio;
}
return {
width: Math.round(width),
height: Math.round(height),
top: Math.round(($(window).innerHeight() - height) / 2),
left: Math.round(($(window).innerWidth() - width) / 2)
}
};
zoom.showBox = function( img_uri ){
var dimensions = zoom.getDimensions( $this.settings.defaultZoomBoxWidth, $this.settings.defaultZoomBoxHeight );
var overlay = $("");
overlay.css({
position: 'fixed',
width: '100%',
height: '100%',
top: '0',
left: '0',
background: '#000',
opacity: '0',
'z-index': '9990'
});
var box = $("");
box.css(
{
'position': 'fixed',
'left': dimensions.left,
'top': dimensions.top,
'min-width': $this.settings.defaultZoomBoxWidth,
'min-height': $this.settings.defaultZoomBoxHeight,
'padding': 3,
'z-index': '9991',
'opacity': 0,
'border-radius': '5px',
'background': 'white url("https://ngn.' + $this.settings.host + '/res/progress.gif")center center no-repeat',
'overflow': 'hidden'
}
);
var centerBox = $("");
var tr = $("
");
var td = $(" | ").css({width: '100%', height: '100%', 'vertical-align': 'middle', 'padding': '0'});
tr.append(td);
centerBox.append(tr).css({ background: 'white', 'border-radius': '3px' });
box.append(centerBox);
$("body").append(overlay).append(box);
//animated show overlay and zoombox
box.animate({opacity:1}, 200);
overlay.animate({opacity:0.4}, 100);
$(overlay).mouseup(function(){
box.remove();
overlay.remove();
});
//Image - load and show
var img = $("
").attr( "src", img_uri );
img.one('load', function(){
// append image to box
td.append( img );
zoom.imgRealWidth = img.width();
zoom.imgRealHeight = img.height();
img.css({
'display': 'block',
'width': '100%'
});
dimensions = zoom.getDimensions(img.width(), img.height() );
box.css({
'left': dimensions.left,
'top': dimensions.top,
'width': dimensions.width,
'height': dimensions.height,
'min-height': '0',
'min-width': '0',
'background': 'white'
});
//set resizing
$(window).resize(function(){
dimensions = zoom.getDimensions( zoom.imgRealWidth, zoom.imgRealHeight );
box.css({
'width': dimensions.width,
'left': dimensions.left,
'height': dimensions.height,
'top': dimensions.top
});
});
});
};
return zoom;
};
// EVENTS
$this.events = new function(){
var events = this;
events.pointer = {
draging: false,
x: 0,
y:0
};
this.onLoadData = function( product_data ){
if ( product_data.status == 1 ){
$this.ready = true;
$this.renderer.applyCss( $this.settings.boxCss );
$this.renderer.prepareViewBox();
$this.renderer.prepareLayers();
events.setEvents();
touchEvents = new $this.touchEvents();
touchEvents.setEvents();
}
if ( product_data.status == 2 ){
$this.renderer.showStaticBox();
}
};
this.onLoadFx = function(){
$this.fx.init();
};
this.onMouseOverFx = function(){
$this.fx.pause(true);
if (!window.finePicDraging && $this.renderer.hoverBack){
$this.renderer.animRotate( $this.rotate - 25, 100 );
}
};
this.onMouseOutFx = function(){
if (!window.finePicDraging && $this.renderer.hoverBack){
$this.renderer.animRotate( $this.rotate + 25 , 100 )
$this.fx.pause(false);
}
};
$this.onClick = function(e){
$this.zoom().show();
};
this.onMouseDown = function(e){
events.lastRotation = $this.rotate;
};
this.onMouseUp = function(e){
};
this.onLoadedLayers = function(){
$this.renderer.appendLayers();
$this.renderer.showCanvas();
$this.renderer.hideProgressBox();
events.onLoadFx();
};
this.onDrag = function(e){
$this.renderer.setRotate(events.lastRotation - events.pointer.x);
};
this.setEvents = function(){
// handle hover
$this.renderer.dragBox.hover(function(){
events.onMouseOverFx();
}, function(){
events.onMouseOutFx();
});
// handle dragging
$this.renderer.dragBox.mousedown(function(e){
e.preventDefault();
events.pointer.startX = e.pageX;
events.pointer.startY = e.pageY;
events.pointer.d = 0;
events.onMouseDown(e);
$(document).bind("mousemove",function(e){
e.preventDefault();
e.stopPropagation();
window.finePicDraging = true;
events.pointer.x = e.pageX - events.pointer.startX;
events.pointer.y = e.pageY - events.pointer.startY;
events.pointer.d = Math.sqrt((events.pointer.x * events.pointer.x) + (events.pointer.y * events.pointer.y));
events.onDrag(e);
})
});
$this.renderer.dragBox.mouseup(function(e){
e.preventDefault();
if (events.pointer.d < 2) {
$this.onClick(e);
}
events.onMouseUp(e);
});
$(document).mouseup(function(e){
e.preventDefault();
e.stopPropagation();
if (events.pointer.d >= 2) {
$this.renderer.hoverBack = false;
}
$(document).unbind("mousemove");
window.finePicDraging = false;
});
}
};
//TOUCH EVENTS
$this.touchEvents = function(){
var touchEvents = this;
touchEvents.startX = false;
touchEvents.startY = false;
touchEvents.dX = 0;
touchEvents.dY = 0;
touchEvents.startRotate = 0;
touchEvents.setEvents = function(){
$this.renderer.dragBox.bind("touchstart", touchEvents.touchStart);
$this.renderer.dragBox.bind("touchend", touchEvents.touchEnd);
$this.renderer.dragBox.bind("touchmove", touchEvents.touchMove);
$this.renderer.dragBox.bind("touchCancel", touchEvents.touchCancel);
$this.renderer.dragBox.bind("touchLeave", touchEvents.touchLeave);
};
touchEvents.touchStart = function(e){
e = e.originalEvent;
e.preventDefault();
e.stopPropagation();
touchEvents.startX = e.touches[0].pageX;
touchEvents.startY = e.touches[0].pageY;
touchEvents.startRotate = $this.rotate;
};
touchEvents.touchEnd = function(e){
e = e.originalEvent;
e.preventDefault();
e.stopPropagation();
if (Math.sqrt((touchEvents.dX * touchEvents.dX) + (touchEvents.dY * touchEvents.dY)) < 10){
$this.zoom().show();
}
touchEvents.dX = 0;
touchEvents.dY = 0;
};
touchEvents.touchMove = function(e){
e = e.originalEvent;
e.preventDefault();
e.stopPropagation();
touch = e.touches[0];
touchEvents.dX = touch.pageX - touchEvents.startX;
touchEvents.dY = touch.pageY - touchEvents.startY;
rotate = touchEvents.startRotate - Math.round(touchEvents.dX / 1.5);
$this.renderer.setRotate( rotate );
};
touchEvents.touchCancel = function(e){
e = e.originalEvent;
e.preventDefault();
e.stopPropagation();
};
touchEvents.touchLeave = function(e){
e = e.originalEvent;
e.preventDefault();
e.stopPropagation();
};
return touchEvents;
};
$this.fx = new function(){
var fx = this;
fx.allowed = true;
fx.defaults = {
autoRotate:{
speed: 100,
direction : 1
},
autoSwing: {
speed: 50,
direction: 1
}
};
fx.init = function(){
$this.renderer.animRotate( $this.startRotate - 35);
if ($this.settings.autoRotate){
fx.autoRotate();
}
if ($this.settings.autoSwing){
fx.autoSwing();
}
};
fx.pause = function( stop ){
fx.allowed = !stop;
};
fx.autoRotate = function(){
fx.autoRotate.speed = $this.settings.autoRotate.speed ? $this.settings.autoRotate.speed : fx.defaults.autoRotate.speed;
fx.autoRotate.direction = $this.settings.autoRotate.direction ? $this.settings.autoRotate.direction : fx.defaults.autoRotate.direction;
this.interval = setInterval(function(){
if (fx.allowed){
$this.renderer.setRotate( $this.rotate + fx.autoRotate.direction );
}
}, 1000 / fx.autoRotate.speed);
};
fx.autoSwing = function(){
fx.autoSwing.index = 0;
fx.autoSwing.speed = $this.settings.autoSwing.speed ? $this.settings.autoSwing.speed : fx.defaults.autoSwing.speed;
fx.autoSwing.direction = $this.settings.autoSwing.direction ? $this.settings.autoSwing.direction : fx.defaults.autoSwing.direction;
this.interval = setInterval(function(){
if (fx.allowed){
fx.autoSwing.index = (fx.autoSwing.index + fx.autoSwing.direction) % 360;
offset = Math.sin( fx.autoSwing.index * Math.PI / 180 );
$this.renderer.setRotate( $this.rotate + offset );
}
}, 1000 / fx.autoSwing.speed);
};
};
$this.init();
return $this;
};
}( jQuery ));