Convert percent to pixel - javascript

I'm using this custom JavaScript range slider, and I want to be able to set a min and max value in pixels. The default is percentage, from 0 - 100.
I was able to implement a min and max setting. The next step is to convert all the percentage to a pixel amount. I was able to do that for the drag function, but I'm having trouble doing it for value.
When I set value to, say 50, instead of going to 50px, it goes to 50%. How can I change all the percentages to pixels?
If you have a better way of doing this, please let me know.
I think this is the main code to change. It's in the last function. It's called initDragger:
cachePosition = ((config.value / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']);
dragger.style[!isVertical ? 'left' : 'top'] = (cachePosition - (woh / 2)) + 'px';
JSFiddle
function rangeSlider(elem, config) {
var html = document.documentElement,
range = document.createElement('div'),
dragger = document.createElement('span'),
down = false,
rangeWidth, rangeOffset, draggerWidth, cachePosition;
var defaults = {
min: 20,
max: 150,
value: 0, // set default value on initiation from `0` to `100` (percentage based)
vertical: false, // vertical or horizontal?
rangeClass: "", // add extra custom class for the range slider track
draggerClass: "", // add extra custom class for the range slider dragger
drag: function(v) { /* console.log(v); */ } // function to return the range slider value into something
};
for (var i in defaults) {
if (typeof config[i] == "undefined") config[i] = defaults[i];
}
function addEventTo(el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
}
var isVertical = config.vertical;
elem.className = (elem.className + ' range-slider ' + (isVertical ? 'range-slider-vertical' : 'range-slider-horizontal')).replace(/^ +/, "");
range.className = ('range-slider-track ' + config.rangeClass).replace(/ +$/, "");
dragger.className = ('dragger ' + config.draggerClass).replace(/ +$/, "");
addEventTo(range, "mousedown", function(e) {
html.className = (html.className + ' no-select').replace(/^ +/, "");
rangeWidth = range[!isVertical ? 'offsetWidth' : 'offsetHeight'];
rangeOffset = range[!isVertical ? 'offsetLeft' : 'offsetTop'];
draggerWidth = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
down = true;
updateDragger(e);
return false;
});
addEventTo(document, "mousemove", function(e) {
updateDragger(e);
});
addEventTo(document, "mouseup", function(e) {
html.className = html.className.replace(/(^| )no-select( |$)/g, "");
down = false;
});
addEventTo(window, "resize", function(e) {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
dragger.style[!isVertical ? 'left' : 'top'] = (((cachePosition / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']) - (woh / 2)) + 'px';
down = false;
});
function updateDragger(e) {
e = e || window.event;
var pos = !isVertical ? e.pageX : e.pageY;
if (!pos) {
pos = !isVertical ? e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
if (down && pos >= rangeOffset && pos <= (rangeOffset + rangeWidth)) {
dragger.style[!isVertical ? 'left' : 'top'] = (pos - rangeOffset - (draggerWidth / 2)) + 'px';
cachePosition = Math.round(((pos - rangeOffset) / rangeWidth) * 100);
cachePositionPixel = Math.round(((cachePosition / 100) * (config.max - config.min)) + config.min);
config.drag(cachePositionPixel);
}
}
function initDragger() {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
cachePosition = ((config.value / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']);
dragger.style[!isVertical ? 'left' : 'top'] = (cachePosition - (woh / 2)) + 'px';
config.drag(config.value);
}
range.appendChild(dragger);
elem.appendChild(range);
initDragger();
}
var slide = document.getElementById('range-slider');
var resultP = document.getElementById('results');
var button = document.getElementById('button');
rangeSlider(slide, {
value: 50,
drag: function(v) {
document.getElementById('results').innerHTML = "Your Current Value is: " + v;
},
max: 60
});
.range-slider-track {
height: 20px;
}
.range-slider-track:before {
content: "";
display: block;
width: 100%;
height: 2px;
background-color: black;
}
.range-slider-track .dragger {
display: block;
width: 10px;
height: inherit;
position: relative;
background-color: red;
}
<div id="range-slider"></div>
<p id="results"></p>

As has become almost customary for me by now, I will offer this answer.
document.getElementById('clickme').onclick = function() {
document.getElementById('slider').value = 37;
};
<input type="range" min="2" max="40" value="23" id="slider" />
<button id="clickme">Set "pixel" to 37</button>
The best solution to a problem is usually the easiest one.

https://github.com/tovic/simple-custom-range-slider - scroll this site to the bottom, there is an answer:
var min = 2, max = 40;
function pixelToPercent(pixel) {
return ((pixel - min) / (max - min)) * 100;
}
function percentToPixel(percent) {
return ((percent / 100) * (max - min)) + min;
}
rangeSlider(document.getElementById('range-slider-1'), {
value: pixelToPercent(10),
drag: function(v) {
document.getElementById('result-area').innerHTML = Math.round(percentToPixel(v));
}
});

It's kinda clunky and it's off by 5px and starts off at 21px so it needs fine-tuning. The function tickDragDist() is an adaptation of this code. tickDragDist() measures the distance between .dragger and .tick (a label that's appended to the .range-slider; .tick is the reference point.)
http://plnkr.co/edit/EckPp81v7xYNHnAArCOt?p=preview
function rangeSlider(elem, config) {
var html = document.documentElement,
range = document.createElement('div'),
dragger = document.createElement('span'),
tick = document.querySelector('.tick'),
down = false,
rangeWidth, rangeOffset, draggerWidth, cachePosition;
var defaults = {
min: 20,
max: 150,
value: 0, // set default value on initiation from `0` to `100` (percentage based)
vertical: false, // vertical or horizontal?
rangeClass: "", // add extra custom class for the range slider track
draggerClass: "", // add extra custom class for the range slider dragger
drag: function(v) { /* console.log(v); */ } // function to return the range slider value into something
};
for (var i in defaults) {
if (typeof config[i] == "undefined") config[i] = defaults[i];
}
function addEventTo(el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
}
var isVertical = config.vertical;
elem.className = (elem.className + ' range-slider ' + (isVertical ? 'range-slider-vertical' : 'range-slider-horizontal')).replace(/^ +/, "");
range.className = ('range-slider-track ' + config.rangeClass).replace(/ +$/, "");
dragger.className = ('dragger ' + config.draggerClass).replace(/ +$/, "");
addEventTo(range, "mousedown", function(e) {
html.className = (html.className + ' no-select').replace(/^ +/, "");
rangeWidth = range[!isVertical ? 'offsetWidth' : 'offsetHeight'];
rangeOffset = range[!isVertical ? 'offsetLeft' : 'offsetTop'];
draggerWidth = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
down = true;
updateDragger(e);
return false;
});
addEventTo(document, "mousemove", function(e) {
updateDragger(e);
});
addEventTo(document, "mouseup", function(e) {
html.className = html.className.replace(/(^| )no-select( |$)/g, "");
down = false;
});
addEventTo(window, "resize", function(e) {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
dragger.style[!isVertical ? 'left' : 'top'] = (((cachePosition / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']) - (woh / 2)) + 'px';
down = false;
});
function updateDragger(e) {
e = e || window.event;
var pos = !isVertical ? e.pageX : e.pageY;
if (!pos) {
pos = !isVertical ? e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
if (down && pos >= rangeOffset && pos <= (rangeOffset + rangeWidth)) {
dragger.style[!isVertical ? 'left' : 'top'] = (pos - rangeOffset - (draggerWidth / 2)) + 'px';
cachePosition = Math.round(((pos - rangeOffset) / rangeWidth) * 100);
cachePositionPixel = Math.round(((cachePosition / 100) * (config.max - config.min)) + config.min);
config.drag(cachePositionPixel);
}
}
function initDragger() {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
cachePosition = ((config.value / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']);
dragger.style[!isVertical ? 'left' : 'top'] = (cachePosition - (woh / 2)) + 'px';
config.drag(config.value);
}
range.appendChild(dragger);
elem.appendChild(range);
initDragger();
}
var slide = document.getElementById('range-slider');
var result = document.getElementById('results');
var button = document.getElementById('button');
var rng = rangeSlider(slide, {
value: 0,
drag: function(v) {
var d = tickDragDist();
document.getElementById('results').value = 'Relative: '+v+'% | Fixed: '+d;
},
max: 100
});
// Calculates the distance between .tick and .dragger
function tickDragDist() {
var tick = document.querySelector('.tick');
var drag = document.querySelector('.dragger');
var tickPos = tick.getBoundingClientRect();
var dragPos = drag.getBoundingClientRect();
var tickX = tickPos.left + tickPos.width/2;
var tickY = tickPos.top + tickPos.height/2;
var dragX = dragPos.left + dragPos.width/2;
var dragY = dragPos.top + dragPos.height/2;
var distSQ = Math.pow(tickX - dragX, 2) + Math.pow(tickY - dragY, 2);
var dist = Math.sqrt(distSQ);
return dist;
}
.range-slider-track { height: 20px; }
.range-slider-track:before { content: ""; display: block; width: 100%; height: 2px; background-color: black; }
.range-slider-track .dragger { display: block; width: 10px; height: inherit; position: relative; background-color: red; }
.range-slider-track .tick { height: 5px; width: 0; position: absolute; left: 0; top: calc(50% - 2.5px); display: inline-block; }
<div id="range-slider">
<label for="range-slider" class="tick">0</label>
</div>
<label for="results">Lengths:
<output id="results"></output>
px</label>

Related

Error "Uncaught TypeError: this.containerDim is undefined" when i open more than 1 tab use firefox, it working normal when i use chrome

I am using firefox to open my page but when I open multiple tabs, the browser console error "Uncaught TypeError: this.containerDim is undefined". If I only open 1 tab then it works fine. This doesn't happen in chrome. Can someone answer for me?
Here is full code error
/*** picture view plugin ****/
(function ($, window, document, undefined) {
"use strict";
//an empty function
var noop = function () {};
var $body = $('body'),
$window = $(window),
$document = $(document);
//constants
var ZOOM_CONSTANT = 15; //increase or decrease value for zoom on mouse wheel
var MOUSE_WHEEL_COUNT = 5; //A mouse delta after which it should stop preventing default behaviour of mouse wheel
//ease out method
/*
t : current time,
b : intial value,
c : changed value,
d : duration
*/
function easeOutQuart(t, b, c, d) {
t /= d;
t--;
return -c * (t * t * t * t - 1) + b;
};
//function to check if image is loaded
function imageLoaded(img) {
return img.complete && (typeof img.naturalWidth === 'undefined' | img.naturalWidth !== 0);
}
var imageViewHtml = '<div class="iv-loader-ss"></div> <div class="iv-snap-view-ss">' + '<div class="iv-snap-image-wrap-ss">' + '<div class="iv-snap-handle-ss"></div>' + '</div>' + '<div class="iv-zoom-slider-ss" id="slider_zoom"><div class="iv-zoom-handle-ss"></div></div></div>' + '<div class="iv-image-view-ss" ><div class="iv-image-wrap-ss" ></div></div>';
//var imageViewHtml = '<div class="iv-zoom-slider id="slider_zoom"><div class="iv-zoom-handle"></div></div>';
var slider_zoom = '<div class="iv-zoom-slider">' + '<div class="iv-zoom-handle"></div>' + '</div>';
function Slider(container, options) {
this.container = container;
this.onStart = options.onStart || noop;
this.onMove = options.onMove || noop;
this.onEnd = options.onEnd || noop;
this.sliderId = options.sliderId || 'slider' + Math.ceil(Math.random() * 1000000);
}
Slider.prototype.init = function () {
var self = this,
container = this.container,
eventSuffix = '.' + this.sliderId;
//assign event on snap image wrap
this.container.on('touchstart' + eventSuffix + ' mousedown' + eventSuffix, function (estart) {
estart.preventDefault();
var touchMove = (estart.type == "touchstart" ? "touchmove" : "mousemove") + eventSuffix,
touchEnd = (estart.type == "touchstart" ? "touchend" : "mouseup") + eventSuffix,
eOrginal = estart.originalEvent,
sx = eOrginal.clientX || eOrginal.touches[0].clientX,
sy = eOrginal.clientY || eOrginal.touches[0].clientY;
var start = self.onStart(estart, {
x: sx,
y: sy
});
if (start === false) return;
var moveListener = function (emove) {
emove.preventDefault();
eOrginal = emove.originalEvent;
//get the cordinates
var mx = eOrginal.clientX,
my = eOrginal.clientY;
self.onMove(emove, {
dx: mx - sx,
dy: my - sy,
mx: mx,
my: my
});
};
var endListener = function () {
$document.off(touchMove, moveListener);
$document.off(touchEnd, endListener);
self.onEnd();
};
$document.on(touchMove, moveListener);
$document.on(touchEnd, endListener);
});
return this;
}
function ImageViewerss(container, options) {
var self = this;
if (container.is('#iv-container-ss')) {
self._fullPage = true;
}
self.container = container;
options = self.options = $.extend({}, ImageViewerss.defaults, options);
self.zoomValue = 100;
if (!container.find('.snap-view').length) {
//container.append(slider_zoom)
container.prepend(imageViewHtml);
}
container.addClass('iv-container-ss');
if (container.css('position') == 'static') container.css('position', 'relative');
self.snapView = container.find('.iv-snap-view-ss');
self.snapImageWrap = container.find('.iv-snap-image-wrap-ss');
self.imageWrap = container.find('.iv-image-wrap-ss');
self.snapHandle = container.find('.iv-snap-handle-ss');
self.zoomHandle = container.find('.iv-zoom-handle-ss');
self._viewerId = 'iv' + Math.floor(Math.random() * 1000000);
}
ImageViewerss.prototype = {
constructor: ImageViewerss,
_init: function () {
var viewerss = this,
options = viewerss.options,
zooming = false, // tell weather we are zooming trough touch
container = this.container;
var eventSuffix = '.' + viewerss._viewerId;
//cache dom refrence
var snapHandle = this.snapHandle;
var snapImgWrap = this.snapImageWrap;
var imageWrap = this.imageWrap;
var snapSlider = new Slider(snapImgWrap, {
sliderId: viewerss._viewerId,
onStart: function () {
if (!viewerss.loaded) return false;
var handleStyle = snapHandle[0].style;
this.curHandleTop = parseFloat(handleStyle.top);
this.curHandleLeft = parseFloat(handleStyle.left);
this.handleWidth = parseFloat(handleStyle.width);
this.handleHeight = parseFloat(handleStyle.height);
this.width = snapImgWrap.width();
this.height = snapImgWrap.height();
//stop momentum on image
clearInterval(imageSlider.slideMomentumCheck);
cancelAnimationFrame(imageSlider.sliderMomentumFrame);
},
onMove: function (e, position) {
var xPerc = this.curHandleLeft + position.dx * 100 / this.width,
yPerc = this.curHandleTop + position.dy * 100 / this.height;
xPerc = Math.max(0, xPerc);
xPerc = Math.min(100 - this.handleWidth, xPerc);
yPerc = Math.max(0, yPerc);
yPerc = Math.min(100 - this.handleHeight, yPerc);
var containerDim = viewerss.containerDim,
imgWidth = viewerss.imageDim.w * (viewerss.zoomValue / 100),
imgHeight = viewerss.imageDim.h * (viewerss.zoomValue / 100),
imgLeft = imgWidth < containerDim.w ? (containerDim.w - imgWidth) / 2 : -imgWidth * xPerc / 100,
imgTop = imgHeight < containerDim.h ? (containerDim.h - imgHeight) / 2 : -imgHeight * yPerc / 100;
snapHandle.css({
top: yPerc + '%',
left: xPerc + '%'
})
viewerss.currentImg.css({
left: imgLeft,
top: imgTop
})
viewerss.compareImg.css({
left: imgLeft,
top: imgTop
})
}
}).init();
/*Add slide interaction to image*/
var imageSlider = viewerss._imageSlider = new Slider(imageWrap, {
sliderId: viewerss._viewerId,
onStart: function (e, position) {
if (!viewerss.loaded) return false;
if (zooming) return;
var self = this;
snapSlider.onStart();
self.imgWidth = viewerss.imageDim.w * viewerss.zoomValue / 100;
self.imgHeight = viewerss.imageDim.h * viewerss.zoomValue / 100;
self.positions = [position, position];
self.startPosition = position;
},
onMove: function (e, position) {
if (zooming) return;
this.currentPos = position;
snapSlider.onMove(e, {
dx: -position.dx * snapSlider.width / this.imgWidth,
dy: -position.dy * snapSlider.height / this.imgHeight
});
},
}).init();
/*Add zoom interation in mouse wheel*/
var changedDelta = 0;
imageWrap.on("mousewheel" + eventSuffix + " DOMMouseScroll" + eventSuffix, function (e) {
if(!options.zoomOnMouseWheel) return;
if (!viewerss.loaded) return;
//clear all animation frame and interval
viewerss._clearFrames();
// cross-browser wheel delta
var delta = Math.max(-1, Math.min(1, (e.originalEvent.wheelDelta || -e.originalEvent.detail))),
zoomValue = viewerss.zoomValue * (100 + delta * ZOOM_CONSTANT) / 100;
if(!(zoomValue >= 100 && zoomValue <= options.maxZoom)){
changedDelta += Math.abs(delta);
}
else{
changedDelta = 0;
}
if(changedDelta > MOUSE_WHEEL_COUNT) return;
e.preventDefault();
var contOffset = container.offset(),
x = (e.pageX || e.originalEvent.pageX) - contOffset.left,
y = (e.pageY || e.originalEvent.pageY) - contOffset.top;
viewerss.zoom(zoomValue, {
x: x,
y: y
});
});
//zoom in zoom out using zoom handle
var slider = viewerss.snapView.find('.iv-zoom-slider-ss');
var zoomSlider = new Slider(slider, {
sliderId: viewerss._viewerId,
onStart: function (eStart) {
if (!viewerss.loaded) return false;
this.leftOffset = slider.offset().left;
this.handleWidth = viewerss.zoomHandle.width();
this.onMove(eStart);
},
onMove: function (e, position) {
var newLeft = (e.pageX || e.originalEvent.touches[0].pageX) - this.leftOffset - this.handleWidth / 2;
newLeft = Math.max(0, newLeft);
newLeft = Math.min(viewerss._zoomSliderLength, newLeft);
var zoomValue = 100 + (options.maxZoom - 100) * newLeft / viewerss._zoomSliderLength;
viewerss.zoom(zoomValue);
}
}).init();
//calculate elments size on window resize
if (options.refreshOnResize) $window.on('resize' + eventSuffix, function () {
//viewerss.refresh()
});
},
//method to zoom images
zoom: function (perc, point) {
perc = Math.max(100, perc);
if ((mouse_hover_depth & show_snap_view) | (!show_snap_view & hover_my & !hover_hang2)){
point = {
x: point_x_depth,
y: point_y_depth
};
console.log("check run if");
console.log("containerDim 00: "+this.containerDim.w);
}else{
console.log("check run else");
point = point || {
x: this.containerDim.w / 2,
y: this.containerDim.h / 2
};
console.log("containerDim 01: "+this.containerDim.w);
console.log("containerDim 02: "+this.containerDim.h);
}
point_x_ir = point.x;
point_y_ir = point.y;
var self = this,
maxZoom = this.options.maxZoom,
curPerc = this.zoomValue,
curImg = this.currentImg,
compareImg = this.compareImg,
containerDim = this.containerDim,
curLeft = parseFloat(curImg.css('left')),
curTop = parseFloat(curImg.css('top'));
console.log("containerDim 1: "+containerDim);
self._clearFrames();
var step = 0;
//calculate base top,left,bottom,right
var containerDim = self.containerDim,
imageDim = self.imageDim;
console.log("self.imageDim: "+self.imageDim);
console.log("self.containerDim 2: "+self.containerDim);
console.log("containerDim 2: "+containerDim);
var baseLeft = (containerDim.w - imageDim.w) / 2,
baseTop = (containerDim.h - imageDim.h) / 2,
baseRight = containerDim.w - baseLeft,
baseBottom = containerDim.h - baseTop;
function zoom() {
step++;
if (step < 20) {
self._zoomFrame = requestAnimationFrame(zoom);
}
var tickZoom = Math.min(maxZoom, easeOutQuart(step, curPerc, perc - curPerc, 20));
var ratio = tickZoom / curPerc,
imgWidth = self.imageDim.w * tickZoom / 100,
imgHeight = self.imageDim.h * tickZoom / 100,
newLeft = -((point.x - curLeft) * ratio - point.x),
newTop = -((point.y - curTop) * ratio - point.y);
/
//fix for left and top
newLeft = Math.min(newLeft, baseLeft);
newTop = Math.min(newTop, baseTop);
//fix for right and bottom
if((newLeft + imgWidth) < baseRight){
newLeft = (self.containerDim.w - imgWidth) ; //newLeft - (newLeft + imgWidth - baseRig
}
if((newTop + imgHeight) < baseBottom){
newTop = (self.containerDim.h - imgHeight) ; //newLeft - (newLeft + imgWidth - baseRig
}
curImg.css({
height: imgHeight + 'px',
width: imgWidth + 'px',
left: newLeft + 'px',
top: newTop + 'px'
});
compareImg.css({
height: 'auto',
width: imgWidth + 'px',
left: newLeft + 'px',
top: newTop + 'px'
});
self.zoomValue = tickZoom;
self._resizeHandle(imgWidth, imgHeight, newLeft, newTop);
//update zoom handle position
self.zoomHandle.css('left', ((tickZoom - 100) * self._zoomSliderLength) / (maxZoom - 100) + 'px');
}
zoom();
},
_clearFrames: function () {
//clearInterval(this._imageSlider.slideMomentumCheck);
cancelAnimationFrame(this._imageSlider.sliderMomentumFrame);
cancelAnimationFrame(this._zoomFrame)
},
//ko có vẫn chạy đc
resetZoom: function () {
this.zoom(this.options.zoomValue);
},
//calculate dimensions of image, container and reset the image
_calculateDimensions: function () {
//calculate content width of image and snap image
var self = this,
curImg = self.currentImg,
compareImg = self.compareImg,
container = self.container,
snapView = self.snapView,
imageWidth = curImg.width(),
imageHeight = curImg.height(),
contWidth = container.width(),
contHeight = container.height(),
snapViewWidth = snapView.innerWidth(),
snapViewHeight = snapView.innerHeight();
//set the container dimension
self.containerDim = {
w: contWidth,
h: contHeight
}
//set the image dimension
var imgWidth, imgHeight, ratio = imageWidth / imageHeight;
imgWidth = (imageWidth > imageHeight && contHeight >= contWidth) || ratio * contHeight > contWidth ? contWidth : ratio * contHeight;
imgHeight = imgWidth / ratio;
self.imageDim = {
w: imgWidth,
h: imgHeight
}
compareImg.css({
width: imgWidth + 'px',
height: 'auto',
left: (contWidth - imgWidth) / 2 + 'px',
top: (contHeight - imgHeight) / 2 + 'px',
'max-width': 'none',
'max-height': 'none'
});
curImg.css({
width: imgWidth + 'px',
height: imgHeight + 'px',
left: (contWidth - imgWidth) / 2 + 'px',
top: (contHeight - imgHeight) / 2 + 'px',
'max-width': 'none',
'max-height': 'none'
});
//set the snap Image dimension
var snapWidth = imgWidth > imgHeight ? snapViewWidth : imgWidth * snapViewHeight / imgHeight,
snapHeight = imgHeight > imgWidth ? snapViewHeight : imgHeight * snapViewWidth / imgWidth;
//ko có cũng ko sao
self.snapImageDim = {
w: snapWidth,
h: snapHeight
}
self.snapImg.css({
width: snapWidth,
height: snapHeight
});
//calculate zoom slider area
self._zoomSliderLength = snapViewWidth - self.zoomHandle.outerWidth();
},
refresh: function () {
if (!this.loaded) return;
this._calculateDimensions();
this.resetZoom();
},
_resizeHandle: function (imgWidth, imgHeight, imgLeft, imgTop) {
var curImg = this.currentImg,
imageWidth = imgWidth || this.imageDim.w * this.zoomValue / 100,
imageHeight = imgHeight || this.imageDim.h * this.zoomValue / 100,
left = Math.max(-(imgLeft || parseFloat(curImg.css('left'))) * 100 / imageWidth, 0),
top = Math.max(-(imgTop || parseFloat(curImg.css('top'))) * 100 / imageHeight, 0),
handleWidth = Math.min(this.containerDim.w * 100 / imageWidth, 100),
handleHeight = Math.min(this.containerDim.h * 100 / imageHeight, 100);
this.snapHandle.css({
top: top + '%',
left: left + '%',
width: handleWidth + '%',
height: handleHeight + '%'
});
},
load: function (image, hiResImg, compare, hiResCompare) {
var self = this,
container = this.container;
container.find('.iv-snap-image-ss,.iv-large-image-ss').remove();
var snapImageWrap = this.container.find('.iv-snap-image-wrap-ss');
snapImageWrap.prepend('<img class="iv-snap-image-ss" style="width:120px; height: 90px;" src="' + image + '" />');
this.imageWrap.prepend('<img class="iv-large-image-ss" src="' + image + '" />');
if (hiResImg) {
this.imageWrap.append('<img class="iv-large-image-ss" src="' + hiResImg + '" />')
}
if(compare) {
this.imageWrap.append('<img class="iv-large-compare-ss" src="' + compare + '" />');
}
var currentImg = this.currentImg = this.container.find('.iv-large-image-ss');
var compareImg = this.compareImg = this.container.find('.iv-large-compare');
this.snapImg = this.container.find('.iv-snap-image-ss');
self.loaded = false;
//show loader
container.find('.iv-loader-ss').show();
currentImg.hide();
compareImg.css('opacity', 0);
self.snapImg.hide();
//refresh the view
function refreshView() {
self.loaded = true;
self.zoomValue = 100;
//reset zoom of images
currentImg.show();
self.snapImg.show();
self.refresh();
self.resetZoom();
//hide loader
container.find('.iv-loader-ss').hide();
}
if (imageLoaded(currentImg[0])) {
refreshView();
} else {
$(currentImg[0]).on('load', refreshView);
}
},
setCompareAlpha: function(alpha) {
/*Add shift binding for image compare toggle*/
this.compareImg.css('opacity', alpha)
}
}
ImageViewerss.defaults = {
zoomValue: 100,
snapView: true,
maxZoom: 300,
refreshOnResize: true,
zoomOnMouseWheel : true
}
window.ImageViewerss = function (container, options) {
var imgElm, imgSrc, compareElm, compareSrc, hiResImg, hiResCompare;
if (!(container && (typeof container == "string" || container instanceof Element || container[0] instanceof Element))) {
options = container;
container = $('#iv-container-ss');
}
container = $(container);
if (container.is('img')) {
imgElm = container;
imgSrc = imgElm[0].src;
hiResImg = imgElm.attr('high-res-src') || imgElm.attr('data-high-res-src');
container = imgElm.wrap('<div class="iv-container-ss" style="display:inline-block; overflow:hidden"></div>').parent();
imgElm.css({
opacity: 0,
position: 'relative',
zIndex: -1
});
} else {
imgSrc = container.attr('src') || container.attr('data-src');
compareSrc = container.attr('compare-src') || container.attr('data-compare-src');
hiResImg = container.attr('high-res-src') || container.attr('data-high-res-src');
}
var viewerss = new ImageViewerss(container, options);
viewerss._init();
if (imgSrc) viewerss.load(imgSrc, hiResImg, compareSrc, hiResCompare);
return viewerss;
};
}((window.jQuery), window, document));
Here is the error code(The error line is the first line of the code below) :
//calculate base top,left,bottom,right
var containerDim = self.containerDim,
imageDim = self.imageDim;
console.log("self.imageDim: "+self.imageDim);
console.log("self.containerDim 2: "+self.containerDim);
console.log("containerDim 2: "+containerDim);
var baseLeft = (containerDim.w - imageDim.w) / 2,
baseTop = (containerDim.h - imageDim.h) / 2,
baseRight = containerDim.w - baseLeft,
baseBottom = containerDim.h - baseTop;
I'm call it like this:
if (mouseDown) {
ismouse = true
} else {
if (ismouse) {
$('.iv-large-image-ss').css('top', $('.iv-large-image').css('top'));
$('.iv-large-image-ss').css('left', $('.iv-large-image').css('left'));
ismouse = false
}
viewerss.zoom(rate);
}
"rate" is a number that I want to assign to represent the zoom level.
I tried to clear the firefox cache and ran the code above, but every time I open a new tab I have to clear the cache to run. I don't know why! :((

Transforming img - white dots appear on chronium

I am trying to get 3d transform effect of the bacground image on mouse move.
I have checked f.e. jquery.plate tilt.js and many others plugins, BUT, each of them has problem on chronium browsers like Chrome or Opera (it works fine even on IE11 -.-)
See the attachment and please adwise what is that and if it is fixable? The "dots" appear on mouse move (when background moves) randomly but in line within image.
(function($) {
'use strict';
var namespace = 'jquery-plate';
function Plate($element, options) {
this.config(options);
this.$container = $element;
if (this.options.element) {
if (typeof this.options.element === 'string') {
this.$element = this.$container.find(this.options.element);
} else {
this.$element = $(this.options.element);
}
} else {
this.$element = $element;
}
this.originalTransform = this.$element.css('transform');
this.$container
.on('mouseenter.' + namespace, this.onMouseEnter.bind(this))
.on('mouseleave.' + namespace, this.onMouseLeave.bind(this))
.on('mousemove.' + namespace, this.onMouseMove.bind(this));
}
Plate.prototype.config = function(options) {
this.options = $.extend({
inverse: false,
perspective: 500,
maxRotation: 10,
animationDuration: 200
}, this.options, options);
};
Plate.prototype.destroy = function() {
this.$element.css('transform', this.originalTransform);
this.$container.off('.' + namespace);
};
Plate.prototype.update = function(offsetX, offsetY, duration) {
var rotateX;
var rotateY;
if (offsetX || offsetX === 0) {
var height = this.$container.outerHeight();
var py = (offsetY - height / 2) / (height / 2);
rotateX = this.round(this.options.maxRotation * -py);
} else {
rotateY = 0;
}
if (offsetY || offsetY === 0) {
var width = this.$container.outerWidth();
var px = (offsetX - width / 2) / (width / 2);
rotateY = this.round(this.options.maxRotation * px);
} else {
rotateX = 0;
}
if (this.options.inverse) {
rotateX *= -1;
rotateY *= -1;
}
if (duration) {
this.animate(rotateX, rotateY, duration);
} else if (this.animation && this.animation.remaining) {
this.animation.targetX = rotateX;
this.animation.targetY = rotateY;
} else {
this.transform(rotateX, rotateY);
}
};
Plate.prototype.reset = function(duration) {
this.update(null, null, duration);
};
Plate.prototype.transform = function(rotateX, rotateY) {
this.currentX = rotateX;
this.currentY = rotateY;
this.$element.css('transform',
(this.originalTransform && this.originalTransform !== 'none' ? this.originalTransform + ' ' : '') +
'perspective(' + this.options.perspective + 'px) ' +
'rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)'
);
};
Plate.prototype.animate = function(rotateX, rotateY, duration) {
if (duration) {
this.animation = this.animation || {};
var remaining = this.animation.remaining;
this.animation.time = performance.now();
this.animation.remaining = duration || null;
this.animation.targetX = rotateX;
this.animation.targetY = rotateY;
if (!remaining) {
requestAnimationFrame(this.onAnimationFrame.bind(this));
}
} else {
this.transform(rotateX, rotateY);
}
};
Plate.prototype.round = function(number) {
return Math.round(number * 1000) / 1000;
};
Plate.prototype.offsetCoords = function(event) {
var offset = this.$container.offset();
return {
x: event.pageX - offset.left,
y: event.pageY - offset.top
};
};
Plate.prototype.onAnimationFrame = function(timestamp) {
this.animation = this.animation || {};
var delta = timestamp - (this.animation.time || 0);
this.animation.time = timestamp;
var duration = this.animation.remaining || 0;
var percent = Math.min(delta / duration, 1);
var currentX = this.currentX || 0;
var currentY = this.currentY || 0;
var targetX = this.animation.targetX || 0;
var targetY = this.animation.targetY || 0;
var rotateX = this.round(currentX + (targetX - currentX) * percent);
var rotateY = this.round(currentY + (targetY - currentY) * percent);
this.transform(rotateX, rotateY);
var remaining = duration - delta;
this.animation.remaining = remaining > 0 ? remaining : null;
if (remaining > 0) {
requestAnimationFrame(this.onAnimationFrame.bind(this));
}
};
Plate.prototype.onMouseEnter = function(event) {
var offset = this.offsetCoords(event);
this.update(offset.x, offset.y, this.options.animationDuration);
};
Plate.prototype.onMouseLeave = function(event) {
this.reset(this.options.animationDuration);
};
Plate.prototype.onMouseMove = function(event) {
var offset = this.offsetCoords(event);
this.update(offset.x, offset.y);
};
$.fn.plate = function(options) {
return this.each(function() {
var $element = $(this);
var plate = $element.data(namespace);
if (options === 'remove') {
plate.destroy();
$element.data(namespace, null);
} else {
if (!plate) {
plate = new Plate($element, options);
$element.data(namespace, plate);
plate.reset();
} else {
plate.config(options);
}
}
});
};
})(jQuery);
$('#ab12cd').plate()
<div id="ab12cd" styles="width:100%;height:100%">
<img src="http://eskipaper.com/images/dark-background-8.jpg" />
</div>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
// please open in new window, most visible effect you cen see if you move mouse bottom left/right

How do you make JQuery WebTicket full-screen width?

Basically, the webticket only goes to about a little over 2/5ths of the screen, I'm trying to figure out how I can stretch the width out so that it covers the entire screen's width.
Fiddle: http://fiddle.jshell.net/Wf43X/56/light/
Javascript:
/*!
* webTicker 1.3
* Examples and documentation at:
* http://jonmifsud.com
* 2011 Jonathan Mifsud
* Version: 1.2 (26-JUNE-2011)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
* Requires:
* jQuery v1.4.2 or later
*
*/
(function($) {
var globalSettings = new Array();
var methods = {
init: function(settings) { // THIS
settings = jQuery.extend({
travelocity: 0.05,
direction: 1,
moving: true
}, settings);
globalSettings[jQuery(this).attr('id')] = settings;
return this.each(function() {
var $strip = jQuery(this);
$strip.addClass("newsticker")
var stripWidth = 0;
var $mask = $strip.wrap("<div class='mask'></div>");
$mask.after("<span class='tickeroverlay-left'> </span><span class='tickeroverlay-right'> </span>")
var $tickercontainer = $strip.parent().wrap("<div class='tickercontainer'></div>");
$strip.find("li").each(function(i) {
stripWidth += jQuery(this, i).outerWidth(true);
});
$strip.width(stripWidth + 200); //20 used for ie9 fix
function scrollnews(spazio, tempo) {
if (settings.direction == 1) $strip.animate({
left: '-=' + spazio
}, tempo, "linear", function() {
$strip.children().last().after($strip.children().first());
var first = $strip.children().first();
var width = first.outerWidth(true);
var defTiming = width / settings.travelocity;
//$strip.css("left", left);
$strip.css("left", '0');
scrollnews(width, defTiming);
});
else $strip.animate({
right: '-=' + spazio
}, tempo, "linear", function() {
$strip.children().last().after($strip.children().first());
var first = $strip.children().first();
var width = first.outerWidth(true);
var defTiming = width / settings.travelocity;
//$strip.css("left", left);
$strip.css("right", '0');
scrollnews(width, defTiming);
});
}
var first = $strip.children().first();
var travel = first.outerWidth(true);
var timing = travel / settings.travelocity;
scrollnews(travel, timing);
$strip.hover(function() {
jQuery(this).stop();
}, function() {
if (globalSettings[jQuery(this).attr('id')].moving) {
var offset = jQuery(this).offset();
var first = $strip.children().first();
var width = first.outerWidth(true);
var residualSpace;
if (settings.direction == 1) residualSpace = parseInt(jQuery(this).css('left').replace('px', '')) + width;
else residualSpace = parseInt(jQuery(this).css('right').replace('px', '')) + width;
var residualTime = residualSpace / settings.travelocity;
scrollnews(residualSpace, residualTime);
}
});
});
},
stop: function() {
if (globalSettings[jQuery(this).attr('id')].moving) {
globalSettings[jQuery(this).attr('id')].moving = false;
return this.each(function() {
jQuery(this).stop();
});
}
},
cont: function() { // GOOD
if (!(globalSettings[jQuery(this).attr('id')].moving)) {
globalSettings[jQuery(this).attr('id')].moving = true;
var settings = globalSettings[jQuery(this).attr('id')];
return this.each(function() {
var $strip = jQuery(this);
function scrollnews(spazio, tempo) {
if (settings.direction == 1) $strip.animate({
left: '-=' + spazio
}, tempo, "linear", function() {
$strip.children().last().after($strip.children().first());
var first = $strip.children().first();
var width = first.outerWidth(true);
var defTiming = width / settings.travelocity;
//$strip.css("left", left);
$strip.css("left", '0');
scrollnews(width, defTiming);
});
else $strip.animate({
right: '-=' + spazio
}, tempo, "linear", function() {
$strip.children().last().after($strip.children().first());
var first = $strip.children().first();
var width = first.outerWidth(true);
var defTiming = width / settings.travelocity;
//$strip.css("left", left);
$strip.css("right", '0');
scrollnews(width, defTiming);
});
}
var offset = jQuery(this).offset();
var first = $strip.children().first();
var width = first.outerWidth(true);
var residualSpace;
if (settings.direction == 1) residualSpace = parseInt(jQuery(this).css('left').replace('px', '')) + width;
else residualSpace = parseInt(jQuery(this).css('right').replace('px', '')) + width;
var residualTime = residualSpace / settings.travelocity;
scrollnews(residualSpace, residualTime);
});
}
}
};
$.fn.webTicker = function(method) {
// Method calling logic
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.webTicker');
}
};
})(jQuery);
jQuery('#webticker').webTicker()
CSS:
.tickercontainer { /* the outer div with the black border */
width: 500px;
height: 27px;
margin: 0;
padding: 0;
overflow: hidden;
}
.tickercontainer .mask { /* that serves as a mask. so you get a sort of padding both left and right */
position: relative;
top: 8px;
height: 18px;
/*width: 718px;*/
overflow: hidden;
}
ul.newsticker { /* that's your list */
position: relative;
/*left: 750px;*/
font: bold 10px Verdana;
list-style-type: none;
margin: 0;
padding: 0;
}
ul.newsticker li {
float: left; /* important: display inline gives incorrect results when you check for elem's width */
margin: 0;
padding-right: 15px;
/*background: #fff;*/
}
Thanks,
Dan

Javascript Nested Function Call

I am trying to develop a javascript library that makes it easier for me to generate DOM Elements and edit their attributes. The problem I am having is that there is so many attributes for some elements that it is making for messy code. For instance I have to programmatically set the color of border, background, shadow, etc. using a method call before generation.
See setBorder Nested in function Div in jLibrary.php
function Div() {
Div.POSITION = {
STATIC : 'static',
ABSOLUTE : 'absolute',
RELATIVE : 'relative',
FIXED : 'fixed'
}
Div.BORDER = {
SOLID : 'solid',
DOTTED : 'dotted'
}
Div.ALIGN = {
LEFT : 0,
CENTER : 1,
RIGHT : 2,
TOP : 0,
MIDDLE : 1,
BOTTOM : 2
}
var ELEMENT;
var CSS;
var horizontalAlign;
var verticalAlign;
var colorQueue;
(function() {
this.div = document.createElement('div');
ELEMENT = this.div;
CSS = this.div.style;
colorQueue = 'rgb(' + new Array(0, 0, 0) + ')';
document.body.appendChild(this.div);
}());
this.setPosition = function(postype) {
if (!horizontalAlign && !verticalAlign) {
CSS.position = postype;
}
}
this.setBounds = function(x, y, width, height) {
CSS.left = x + 'px';
CSS.top = y + 'px';
CSS.width = width + 'px';
CSS.height = height + 'px';
}
this.setColorQueue = function(r, g, b) {
colorQueue = 'rgb(' + new Array(r, g, b) + ')';
alert(colorQueue);
}
this.setBackgroundColorToQueue = function(){
CSS.backgroundColor = colorQueue;
}
this.createShadow = function(x, y, width, height){
CSS.boxShadow = y + 'px ' + x + 'px ' + width + 'px ' + height + 'px ' + colorQueue;
}
this.createBorder = function(width,style){
CSS.border = width + 'px ' + style + ' ' + colorQueue;
/* Theoretical Method.
this.setColor = function(r,g,b){ //This will not work the way I want it...
CSS.border = 'rgb(' + new Array(r, g, b) + ')';
}
*/
}
this.rotateDiv = function(degrees){
CSS.transform = 'rotate(' + degrees + 'deg)';
}
this.horizontalAlign = function(horiz) {
var freeSpaceX = ((window.innerWidth - ELEMENT.offsetWidth) / 2);
var defPadding = '8px';
var defPaddingCenter;
var defPaddingRight;
var defPaddingLeft;
horizontalAlign = true;
if (CSS.position == 'relative' || CSS.position == 'static' || CSS.position == 'absolute') {
CSS.position = 'absolute';
defPaddingCenter = 4;
defPaddingRight = 4;
defPaddingLeft = 8;
} else if (CSS.position == 'fixed') {
defPaddingCenter = 4;
defPaddingRight = 4;
defPaddingLeft = 8;
}
if (horiz == 0) {
if (!verticalAlign) {
CSS.marginTop = defPadding;
}
CSS.marginLeft = defPaddingLeft + 'px';
} else if (horiz == 1) {
if (!verticalAlign) {
CSS.marginTop = defPadding;
}
CSS.marginLeft = freeSpaceX - defPaddingCenter + 'px';
} else if (horiz == 2) {
if (!verticalAlign) {
CSS.marginTop = defPadding;
}
CSS.marginLeft = (freeSpaceX - defPaddingRight) * 2 + 'px';
}
}
this.verticalAlign = function(vertical) {
var freeSpaceY = ((window.innerHeight - ELEMENT.offsetHeight) / 2);
var defPadding = '8px';
var defPaddingTop;
var defPaddingMid;
var defPaddingBot;
verticalAlign = true;
if (CSS.position == 'relative' || CSS.position == 'static') {
CSS.position = 'absolute';
}
defPaddingTop = 8;
defPaddingMid = 8;
defPaddingBot = 8;
if (vertical == 0) {
if (!horizontalAlign) {
CSS.marginLeft = defPadding;
}
CSS.marginTop = defPadding;
} else if (vertical == 1) {
if (!horizontalAlign) {
CSS.marginLeft = defPadding;
}
CSS.marginTop = freeSpaceY - defPaddingMid + 'px';
} else if (vertical == 2) {
if (!horizontalAlign) {
CSS.marginLeft = defPadding;
}
CSS.marginTop = (freeSpaceY * 2) - defPaddingBot + 'px';
}
}
}
setBorder Example in index.php
var div1 = new Div();
div1.setPosition(Div.POSITION.ABSOLUTE);
div1.setBounds(0,700, 200,200);
div1.setColorQueue(0,0,0); //This method must be called every time a different color is needed for a certain attribute.
div1.createBorder(5, Div.BORDER.SOLID); // I really want something like this --> div1.createBorder(5,Div.BORDER.SOLID).setColor(0,0,0);
You can try using the Builder pattern:
function DivBuilder() {
var color;
var border;
var position;
var bounds;
this.DivBuilder = function() {}
this.color = function(c) {
//set the color
this.color = c;
return this;
}
this.border = function(b) {
//set the border
this.border = b;
return this;
}
this.position = function(p) {
//set position
this.position = p;
return this;
}
this.bounds = function(b) {
//set bounds
this.border = b;
return this;
}
this.build = function () {
//build the new Div object with the properties of the builder
var d = new Div(this);
return d;
}
}
and then:
var divb = new DivBuilder();
divb.position().bounds().border().color();
var div = divb.buid();
Main advantage over the telescopic constructor pattern (well, the adaptation of it to javascript) is that you can choose easier which property you want to initialize without having to create many different constructor cases.
If you want to write this.createBorder(...).setColor(...) It means that createBorder should return an object with the setColor method...
Thanks to Sebas I was able to come up with this... Please vote up Sebas if this helped you.
Nested in this.createBorder()
this.createBorder = function(width) {
CSS.border = width + 'px';
function DivBorderBuilder() {
this.setColor = function(r, b, g) {
alert('color');
CSS.borderColor = 'rgb(' + new Array(r, g, b) + ')';
return this;
}
this.setStyle = function(s){
CSS.borderStyle = s;
return this;
}
}return new DivBorderBuilder();
}
Creating Border in index.php
<script>
var div1 = new Div();
div1.setPosition(Div.POSITION.ABSOLUTE);
div1.setBounds(0,700, 200,200);
div1.createBorder(5).setStyle(Div.BORDER.SOLID).setColor(255,0,0);// Works Perfectly Now !
</script>

Cloudzoom and woocommerce attributes

I cannot get cloudzoom to work with my woocommerce site, every time I choose an attribute ie size the main image disappears, it is like cloudzoom is trying to force an attribute image. I am absolutely pants at javascript and looking through the file I cannot see where I need to edit or delete the code. Any help would be greatly appreciated, I don't need the atribute image function to work at all so just stripping out the code would suit me. Here is the code...
(function ($) {
$(document).ready(function () {
$('.cloud-zoom, .cloud-zoom-gallery').CloudZoom();
});
function format(str) {
for (var i = 1; i < arguments.length; i++) {
str = str.replace('%' + (i - 1), arguments[i]);
}
return str;
}
function CloudZoom(jWin, opts) {
var sImg = $('img', jWin);
var img1;
var img2;
var zoomDiv = null;
var $mouseTrap = null;
var lens = null;
var $tint = null;
var softFocus = null;
var $ie6Fix = null;
var zoomImage;
var controlTimer = 0;
var cw, ch;
var destU = 0;
var destV = 0;
var currV = 0;
var currU = 0;
var filesLoaded = 0;
var mx,
my;
var ctx = this, zw;
// Display an image loading message. This message gets deleted when the images have loaded and the zoom init function is called.
// We add a small delay before the message is displayed to avoid the message flicking on then off again virtually immediately if the
// images load really fast, e.g. from the cache.
//var ctx = this;
setTimeout(function () {
// <img src="/images/loading.gif"/>
if ($mouseTrap === null) {
var w = jWin.width();
jWin.parent().append(format('<div style="width:%0px;position:absolute;top:75%;left:%1px;text-align:center" class="cloud-zoom-loading" >Loading...</div>', w / 3, (w / 2) - (w / 6))).find(':last').css('opacity', 0.5);
}
}, 200);
var ie6FixRemove = function () {
if ($ie6Fix !== null) {
$ie6Fix.remove();
$ie6Fix = null;
}
};
// Removes cursor, tint layer, blur layer etc.
this.removeBits = function () {
//$mouseTrap.unbind();
if (lens) {
lens.remove();
lens = null;
}
if ($tint) {
$tint.remove();
$tint = null;
}
if (softFocus) {
softFocus.remove();
softFocus = null;
}
ie6FixRemove();
$('.cloud-zoom-loading', jWin.parent()).remove();
};
this.destroy = function () {
jWin.data('zoom', null);
if ($mouseTrap) {
$mouseTrap.unbind();
$mouseTrap.remove();
$mouseTrap = null;
}
if (zoomDiv) {
zoomDiv.remove();
zoomDiv = null;
}
//ie6FixRemove();
this.removeBits();
// DON'T FORGET TO REMOVE JQUERY 'DATA' VALUES
};
// This is called when the zoom window has faded out so it can be removed.
this.fadedOut = function () {
if (zoomDiv) {
zoomDiv.remove();
zoomDiv = null;
}
this.removeBits();
//ie6FixRemove();
};
this.controlLoop = function () {
if (lens) {
var x = (mx - sImg.offset().left - (cw * 0.5)) >> 0;
var y = (my - sImg.offset().top - (ch * 0.5)) >> 0;
if (x < 0) {
x = 0;
}
else if (x > (sImg.outerWidth() - cw)) {
x = (sImg.outerWidth() - cw);
}
if (y < 0) {
y = 0;
}
else if (y > (sImg.outerHeight() - ch)) {
y = (sImg.outerHeight() - ch);
}
lens.css({
left: x,
top: y
});
lens.css('background-position', (-x) + 'px ' + (-y) + 'px');
destU = (((x) / sImg.outerWidth()) * zoomImage.width) >> 0;
destV = (((y) / sImg.outerHeight()) * zoomImage.height) >> 0;
currU += (destU - currU) / opts.smoothMove;
currV += (destV - currV) / opts.smoothMove;
zoomDiv.css('background-position', (-(currU >> 0) + 'px ') + (-(currV >> 0) + 'px'));
}
controlTimer = setTimeout(function () {
ctx.controlLoop();
}, 30);
};
this.init2 = function (img, id) {
filesLoaded++;
//console.log(img.src + ' ' + id + ' ' + img.width);
if (id === 1) {
zoomImage = img;
}
//this.images[id] = img;
if (filesLoaded === 2) {
this.init();
}
};
/* Init function start. */
this.init = function () {
// Remove loading message (if present);
$('.cloud-zoom-loading', jWin.parent()).remove();
/* Add a box (mouseTrap) over the small image to trap mouse events.
It has priority over zoom window to avoid issues with inner zoom.
We need the dummy background image as IE does not trap mouse events on
transparent parts of a div.
*/
$mouseTrap = jWin.parent().append(format("<div class='mousetrap' style='background-image:url(\".\");z-index:3;position:absolute;width:%0px;height:%1px;left:%2px;top:%3px;\'></div>", sImg.outerWidth(), sImg.outerHeight(), 0, 0)).find(':last');
//////////////////////////////////////////////////////////////////////
/* Do as little as possible in mousemove event to prevent slowdown. */
$mouseTrap.bind('mousemove', this, function (event) {
// Just update the mouse position
mx = event.pageX;
my = event.pageY;
});
//////////////////////////////////////////////////////////////////////
$mouseTrap.bind('mouseleave', this, function (event) {
clearTimeout(controlTimer);
//event.data.removeBits();
if(lens) { lens.fadeOut(299); }
if($tint) { $tint.fadeOut(299); }
if(softFocus) { softFocus.fadeOut(299); }
zoomDiv.fadeOut(300, function () {
ctx.fadedOut();
});
return false;
});
//////////////////////////////////////////////////////////////////////
$mouseTrap.bind('mouseenter', this, function (event) {
mx = event.pageX;
my = event.pageY;
zw = event.data;
if (zoomDiv) {
zoomDiv.stop(true, false);
zoomDiv.remove();
}
var xPos = opts.adjustX,
yPos = opts.adjustY;
var siw = sImg.outerWidth();
var sih = sImg.outerHeight();
var w = opts.zoomWidth;
var h = opts.zoomHeight;
if (opts.zoomWidth == 'auto') {
w = siw;
}
if (opts.zoomHeight == 'auto') {
h = sih;
}
//$('#info').text( xPos + ' ' + yPos + ' ' + siw + ' ' + sih );
var appendTo = jWin.parent(); // attach to the wrapper
switch (opts.position) {
case 'top':
yPos -= h; // + opts.adjustY;
break;
case 'right':
xPos += siw; // + opts.adjustX;
break;
case 'bottom':
yPos += sih; // + opts.adjustY;
break;
case 'left':
xPos -= w; // + opts.adjustX;
break;
case 'inside':
w = siw;
h = sih;
break;
// All other values, try and find an id in the dom to attach to.
default:
appendTo = $('#' + opts.position);
// If dom element doesn't exit, just use 'right' position as default.
if (!appendTo.length) {
appendTo = jWin;
xPos += siw; //+ opts.adjustX;
yPos += sih; // + opts.adjustY;
} else {
w = appendTo.innerWidth();
h = appendTo.innerHeight();
}
}
zoomDiv = appendTo.append(format('<div id="cloud-zoom-big" class="cloud-zoom-big" style="display:none;position:absolute;left:%0px;top:%1px;width:%2px;height:%3px;background-image:url(\'%4\');z-index:2;"></div>', xPos, yPos, w, h, zoomImage.src)).find(':last');
// Add the title from title tag.
if (sImg.attr('title') && opts.showTitle) {
zoomDiv.append(format('<div class="cloud-zoom-title">%0</div>', sImg.attr('title'))).find(':last').css('opacity', opts.titleOpacity);
}
// Fix ie6 select elements wrong z-index bug. Placing an iFrame over the select element solves the issue...
if ($.browser.msie && $.browser.version < 7) {
$ie6Fix = $('<iframe frameborder="0" src="#"></iframe>').css({
position: "absolute",
left: xPos,
top: yPos,
zIndex: 99,
width: w,
height: h
}).insertBefore(zoomDiv);
}
zoomDiv.fadeIn(500);
if (lens) {
lens.remove();
lens = null;
} /* Work out size of cursor */
cw = (sImg.outerWidth() / zoomImage.width) * zoomDiv.width();
ch = (sImg.outerHeight() / zoomImage.height) * zoomDiv.height();
// Attach mouse, initially invisible to prevent first frame glitch
lens = jWin.append(format("<div class = 'cloud-zoom-lens' style='display:none;z-index:1;position:absolute;width:%0px;height:%1px;opacity:0.4'></div>", cw, ch)).find(':last');
$mouseTrap.css('cursor', lens.css('cursor'));
var noTrans = false;
// Init tint layer if needed. (Not relevant if using inside mode)
if (opts.tint) {
/* lens.css('background', 'url("' + sImg.attr('src') + '")'); */
$tint = jWin.append(format('<div style="display:none;position:absolute; left:0px; top:0px; width:%0px; height:%1px; background-color:%2;" />', sImg.outerWidth(), sImg.outerHeight(), opts.tint)).find(':last');
$tint.css('opacity', opts.tintOpacity);
noTrans = true;
$tint.fadeIn(500);
}
if (opts.softFocus) {
lens.css('background', 'url("' + sImg.attr('src') + '")');
softFocus = jWin.append(format('<div style="position:absolute;display:none;top:2px; left:2px; width:%0px; height:%1px;" />', sImg.outerWidth() - 2, sImg.outerHeight() - 2, opts.tint)).find(':last');
softFocus.css('background', 'url("' + sImg.attr('src') + '")');
softFocus.css('opacity', 0.5);
noTrans = true;
softFocus.fadeIn(500);
}
if (!noTrans) {
lens.css('opacity', opts.lensOpacity);
}
if ( opts.position !== 'inside' ) { lens.fadeIn(500); }
// Start processing.
zw.controlLoop();
return; // Don't return false here otherwise opera will not detect change of the mouse pointer type.
});
};
img1 = new Image();
$(img1).load(function () {
ctx.init2(this, 0);
});
img1.src = sImg.attr('src');
img2 = new Image();
$(img2).load(function () {
ctx.init2(this, 1);
});
img2.src = jWin.attr('href');
}
$.fn.CloudZoom = function (options) {
// IE6 background image flicker fix
try {
document.execCommand("BackgroundImageCache", false, true);
} catch (e) {}
this.each(function () {
var relOpts, opts;
// Hmm...eval...slap on wrist.
eval('var a = {' + $(this).attr('rel') + '}');
relOpts = a;
if ($(this).is('.cloud-zoom')) {
$(this).css({
'position': 'relative',
'display': 'block'
});
$('img', $(this)).css({
'display': 'block'
});
// Wrap an outer div around the link so we can attach things without them becoming part of the link.
// But not if wrap already exists.
if ($(this).parent().attr('id') != 'wrap') {
$(this).wrap('<div id="wrap" style="top:0px;z-index:4;position:relative;"></div>');
}
opts = $.extend({}, $.fn.CloudZoom.defaults, options);
opts = $.extend({}, opts, relOpts);
$(this).data('zoom', new CloudZoom($(this), opts));
} else if ($(this).is('.cloud-zoom-gallery')) {
opts = $.extend({}, relOpts, options);
$(this).data('relOpts', opts);
$(this).bind('click', $(this), function (event) {
var data = event.data.data('relOpts');
// Destroy the previous zoom
$('#' + data.useZoom).data('zoom').destroy();
// Change the biglink to point to the new big image.
$('#' + data.useZoom).attr('href', event.data.attr('href'));
// Change the small image to point to the new small image.
$('#' + data.useZoom + ' img').attr('src', event.data.data('relOpts').smallImage);
// Init a new zoom with the new images.
$('#zoom-cb').attr('href', event.data.attr('href'));
$('#' + event.data.data('relOpts').useZoom).CloudZoom();
return false;
});
}
});
return this;
};
$.fn.CloudZoom.defaults = {
zoomWidth: 'auto',
zoomHeight: 'auto',
position: 'right',
tint: false,
tintOpacity: 0.5,
lensOpacity: 0.5,
softFocus: false,
smoothMove: 3,
showTitle: false,
titleOpacity: 0.5,
adjustX: 0,
adjustY: 0
};
})(jQuery);

Categories