(function (document, window){
var juxtapose={
sliders: [],
OPTIMIZATION_ACCEPTED: 1,
OPTIMIZATION_WAS_CONSTRAINED: 2
};
var flickr_key="d90fc2d1f4acc584e08b8eaea5bf4d6c";
var FLICKR_SIZE_PREFERENCES=['Large', 'Medium'];
function Graphic(properties, slider){
var self=this;
this.image=new Image();
this.loaded=false;
this.image.onload=function(){
self.loaded=true;
slider._onLoaded();
};
this.image.src=properties.src;
this.image.alt=properties.alt||'';
this.label=properties.label||false;
this.credit=properties.credit||false;
}
function FlickrGraphic(properties, slider){
var self=this;
this.image=new Image();
this.loaded=false;
this.image.onload=function(){
self.loaded=true;
slider._onLoaded();
};
this.flickrID=this.getFlickrID(properties.src);
this.callFlickrAPI(this.flickrID, self);
this.label=properties.label||false;
this.credit=properties.credit||false;
}
FlickrGraphic.prototype={
getFlickrID: function(url){
if(url.match(/flic.kr\/.+/i)){
var encoded=url.split('/').slice(-1)[0];
return base58Decode(encoded);
}
var idx=url.indexOf("flickr.com/photos/");
var pos=idx + "flickr.com/photos/".length;
var photo_info=url.substr(pos);
if(photo_info.indexOf('/')==-1) return null;
if(photo_info.indexOf('/')===0) photo_info=photo_info.substr(1);
id=photo_info.split("/")[1];
return id;
},
callFlickrAPI: function(id, self){
var url='https://api.flickr.com/services/rest/?method=flickr.photos.getSizes' +
'&api_key=' + flickr_key +
'&photo_id=' + id + '&format=json&nojsoncallback=1';
var request=new XMLHttpRequest();
request.open('GET', url, true);
request.onload=function(){
if(request.status >=200&&request.status < 400){
data=JSON.parse(request.responseText);
var flickr_url=self.bestFlickrUrl(data.sizes.size);
self.setFlickrImage(flickr_url);
}else{
console.error("There was an error getting the picture from Flickr");
}};
request.onerror=function(){
console.error("There was an error getting the picture from Flickr");
};
request.send();
},
setFlickrImage: function(src){
this.image.src=src;
},
bestFlickrUrl: function(ary){
var dict={};
for (var i=0; i < ary.length; i++){
dict[ary[i].label]=ary[i].source;
}
for (var j=0; j < FLICKR_SIZE_PREFERENCES.length; j++){
if(FLICKR_SIZE_PREFERENCES[j] in dict){
return dict[FLICKR_SIZE_PREFERENCES[j]];
}}
return ary[0].source;
}};
function getNaturalDimensions(DOMelement){
if(DOMelement.naturalWidth&&DOMelement.naturalHeight){
return {width: DOMelement.naturalWidth, height: DOMelement.naturalHeight};}
var img=new Image();
img.src=DOMelement.src;
return {width: img.width, height: img.height};}
function getImageDimensions(img){
var dimensions={
width: getNaturalDimensions(img).width,
height: getNaturalDimensions(img).height,
aspect: function(){ return (this.width / this.height); }};
return dimensions;
}
function addClass(element, c){
if(element.classList){
element.classList.add(c);
}else{
element.className +=" " + c;
}}
function removeClass(element, c){
element.className=element.className.replace(/(\S+)\s*/g, function (w, match){
if(match===c){
return '';
}
return w;
}).replace(/^\s+/, '');
}
function setText(element, text){
if(document.body.textContent){
element.textContent=text;
}else{
element.innerText=text;
}}
function getComputedWidthAndHeight(element){
if(window.getComputedStyle){
return {
width: parseInt(getComputedStyle(element).width, 10),
height: parseInt(getComputedStyle(element).height, 10)
};}else{
w=element.getBoundingClientRect().right - element.getBoundingClientRect().left;
h=element.getBoundingClientRect().bottom - element.getBoundingClientRect().top;
return {
width: parseInt(w, 10)||0,
height: parseInt(h, 10)||0
};}}
function viewport(){
var e=window, a='inner';
if(!('innerWidth' in window) ){
a='client';
e=document.documentElement||document.body;
}
return { width:e[ a+'Width' ] , height:e[ a+'Height' ] }}
function getPageX(e){
var pageX;
if(e.pageX){
pageX=e.pageX;
}else if(e.touches){
pageX=e.touches[0].pageX;
}else{
pageX=e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
}
return pageX;
}
function getPageY(e){
var pageY;
if(e.pageY){
pageY=e.pageY;
}else if(e.touches){
pageY=e.touches[0].pageY;
}else{
pageY=e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return pageY;
}
function checkFlickr(url){
if(url.match(/flic.kr\/.+/i)){
return true;
}
var idx=url.indexOf("flickr.com/photos/");
if(idx==-1){
return false;
}else{
return true;
}}
function base58Decode(encoded){
var alphabet='123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ',
base=alphabet.length;
if(typeof encoded!=='string'){
throw '"base58Decode" only accepts strings.';
}
var decoded=0;
while (encoded){
var alphabetPosition=alphabet.indexOf(encoded[0]);
if(alphabetPosition < 0){
throw '"base58Decode" can\'t find "' + encoded[0] + '" in the alphabet: "' + alphabet + '"';
}
var powerOf=encoded.length - 1;
decoded +=alphabetPosition * (Math.pow(base, powerOf));
encoded=encoded.substring(1);
}
return decoded.toString();
}
function getLeftPercent(slider, input){
if(typeof(input)==="string"||typeof(input)==="number"){
leftPercent=parseInt(input, 10);
}else{
var sliderRect=slider.getBoundingClientRect();
var offset={
top: sliderRect.top + document.body.scrollTop + document.documentElement.scrollTop,
left: sliderRect.left + document.body.scrollLeft + document.documentElement.scrollLeft
};
var width=slider.offsetWidth;
var pageX=getPageX(input);
var relativeX=pageX - offset.left;
leftPercent=(relativeX / width) * 100;
}
return leftPercent;
}
function getTopPercent(slider, input){
if(typeof(input)==="string"||typeof(input)==="number"){
topPercent=parseInt(input, 10);
}else{
var sliderRect=slider.getBoundingClientRect();
var offset={
top: sliderRect.top + document.body.scrollTop + document.documentElement.scrollTop,
left: sliderRect.left + document.body.scrollLeft + document.documentElement.scrollLeft
};
var width=slider.offsetHeight;
var pageY=getPageY(input);
var relativeY=pageY - offset.top;
topPercent=(relativeY / width) * 100;
}
return topPercent;
}
var BOOLEAN_OPTIONS={'animate': true, 'showLabels': true, 'showCredits': true, 'makeResponsive': true };
function interpret_boolean(x){
if(typeof(x)!='string'){
return Boolean(x);
}
return !(x==='false'||x==='');
}
function JXSlider(selector, images, options){
this.selector=selector;
var i;
this.options={
animate: true,
showLabels: true,
showCredits: true,
makeResponsive: true,
startingPosition: "50%",
mode: 'horizontal',
callback: null
};
for (i in this.options){
if(i in options){
if(i in BOOLEAN_OPTIONS){
this.options[i]=interpret_boolean(options[i]);
}else{
this.options[i]=options[i];
}}
}
if(images.length==2){
if(checkFlickr(images[0].src)){
this.imgBefore=new FlickrGraphic(images[0], this);
}else{
this.imgBefore=new Graphic(images[0], this);
}
if(checkFlickr(images[1].src)){
this.imgAfter=new FlickrGraphic(images[1], this);
}else{
this.imgAfter=new Graphic(images[1], this);
}}else{
console.warn("The images parameter takes two Image objects.");
}
if(this.imgBefore.credit||this.imgAfter.credit){
this.options.showCredits=true;
}else{
this.options.showCredits=false;
}}
JXSlider.prototype={
updateSlider: function(input, animate){
var leftPercent, rightPercent;
if(this.options.mode==="vertical"){
leftPercent=getTopPercent(this.slider, input);
}else{
leftPercent=getLeftPercent(this.slider, input);
}
leftPercent=leftPercent.toFixed(2) + "%";
leftPercentNum=parseFloat(leftPercent);
rightPercent=(100 - leftPercentNum) + "%";
if(leftPercentNum > 0&&leftPercentNum < 100){
removeClass(this.handle, 'transition');
removeClass(this.rightImage, 'transition');
removeClass(this.leftImage, 'transition');
if(this.options.animate&&animate){
addClass(this.handle, 'transition');
addClass(this.leftImage, 'transition');
addClass(this.rightImage, 'transition');
}
if(this.options.mode==="vertical"){
this.handle.style.top=leftPercent;
this.leftImage.style.height=leftPercent;
this.rightImage.style.height=rightPercent;
}else{
this.handle.style.left=leftPercent;
this.leftImage.style.width=leftPercent;
this.rightImage.style.width=rightPercent;
}
this.sliderPosition=leftPercent;
}},
getPosition: function(){
return this.sliderPosition;
},
displayLabel: function(element, labelText){
label=document.createElement("div");
label.className='jx-label';
label.setAttribute('tabindex', 0);
setText(label, labelText);
element.appendChild(label);
},
displayCredits: function(){
credit=document.createElement("div");
credit.className="jx-credit";
text="<em>Photo Credits:</em>";
if(this.imgBefore.credit){ text +=" <em>Before</em> " + this.imgBefore.credit; }
if(this.imgAfter.credit){ text +=" <em>After</em> " + this.imgAfter.credit; }
credit.innerHTML=text;
this.wrapper.appendChild(credit);
},
setStartingPosition: function(s){
this.options.startingPosition=s;
},
checkImages: function(){
if(getImageDimensions(this.imgBefore.image).aspect()==getImageDimensions(this.imgAfter.image).aspect()){
return true;
}else{
return false;
}},
calculateDims: function(width, height){
var ratio=getImageDimensions(this.imgBefore.image).aspect();
if(width){
height=width / ratio;
}else if(height){
width=height * ratio;
}
return {
width: width,
height: height,
ratio: ratio
};},
responsivizeIframe: function(dims){
if(dims.height < window.innerHeight){
if(dims.ratio >=1){
this.wrapper.style.paddingTop=parseInt((window.innerHeight - dims.height) / 2) + "px";
}}else if(dims.height > window.innerHeight){
dims=this.calculateDims(0, window.innerHeight);
this.wrapper.style.paddingLeft=parseInt((window.innerWidth - dims.width) / 2) + "px";
}
if(this.options.showCredits){
dims.height -=13;
}
return dims;
},
setWrapperDimensions: function(){
var wrapperWidth=getComputedWidthAndHeight(this.wrapper).width;
var wrapperHeight=getComputedWidthAndHeight(this.wrapper).height;
var dims=this.calculateDims(wrapperWidth, wrapperHeight);
if(window.location!==window.parent.location&&!this.options.makeResponsive){
dims=this.responsivizeIframe(dims);
}
this.wrapper.style.height=parseInt(dims.height) + "px";
this.wrapper.style.width=parseInt(dims.width) + "px";
},
optimizeWrapper: function(maxWidth){
var result=juxtapose.OPTIMIZATION_ACCEPTED;
if((this.imgBefore.image.naturalWidth >=maxWidth)&&(this.imgAfter.image.naturalWidth >=maxWidth)){
this.wrapper.style.width=maxWidth + "px";
result=juxtapose.OPTIMIZATION_WAS_CONSTRAINED;
}else if(this.imgAfter.image.naturalWidth < maxWidth){
this.wrapper.style.width=this.imgAfter.image.naturalWidth + "px";
}else{
this.wrapper.style.width=this.imgBefore.image.naturalWidth + "px";
}
this.setWrapperDimensions();
return result;
},
_onLoaded: function(){
if(this.imgBefore&&this.imgBefore.loaded===true &&
this.imgAfter&&this.imgAfter.loaded===true){
this.wrapper=document.querySelector(this.selector);
addClass(this.wrapper, 'juxtapose');
this.wrapper.style.width=getNaturalDimensions(this.imgBefore.image).width;
this.setWrapperDimensions();
this.slider=document.createElement("div");
this.slider.className='jx-slider';
this.wrapper.appendChild(this.slider);
if(this.options.mode!="horizontal"){
addClass(this.slider, this.options.mode);
}
this.handle=document.createElement("div");
this.handle.className='jx-handle';
this.rightImage=document.createElement("div");
this.rightImage.className='jx-image jx-right';
this.rightImage.appendChild(this.imgAfter.image);
this.leftImage=document.createElement("div");
this.leftImage.className='jx-image jx-left';
this.leftImage.appendChild(this.imgBefore.image);
this.slider.appendChild(this.handle);
this.slider.appendChild(this.leftImage);
this.slider.appendChild(this.rightImage);
this.leftArrow=document.createElement("div");
this.rightArrow=document.createElement("div");
this.control=document.createElement("div");
this.controller=document.createElement("div");
this.leftArrow.className='jx-arrow jx-left';
this.rightArrow.className='jx-arrow jx-right';
this.control.className='jx-control';
this.controller.className='jx-controller';
this.controller.setAttribute('tabindex', 0);
this.controller.setAttribute('role', 'slider');
this.controller.setAttribute('aria-valuenow', 50);
this.controller.setAttribute('aria-valuemin', 0);
this.controller.setAttribute('aria-valuemax', 100);
this.handle.appendChild(this.leftArrow);
this.handle.appendChild(this.control);
this.handle.appendChild(this.rightArrow);
this.control.appendChild(this.controller);
this._init();
}},
_init: function(){
if(this.checkImages()===false){
console.warn(this, "Check that the two images have the same aspect ratio for the slider to work correctly.");
}
this.updateSlider(this.options.startingPosition, false);
if(this.options.showLabels===true){
if(this.imgBefore.label){ this.displayLabel(this.leftImage, this.imgBefore.label); }
if(this.imgAfter.label){ this.displayLabel(this.rightImage, this.imgAfter.label); }}
if(this.options.showCredits===true){
this.displayCredits();
}
var self=this;
window.addEventListener("resize", function(){
self.setWrapperDimensions();
});
this.slider.addEventListener("mousedown", function(e){
e=e||window.event;
e.preventDefault();
self.updateSlider(e, true);
animate=true;
this.addEventListener("mousemove", function(e){
e=e||window.event;
e.preventDefault();
if(animate){ self.updateSlider(e, false); }});
this.addEventListener('mouseup', function(e){
e=e||window.event;
e.preventDefault();
e.stopPropagation();
this.removeEventListener('mouseup', arguments.callee);
animate=false;
});
});
this.slider.addEventListener("touchstart", function(e){
e=e||window.event;
e.preventDefault();
e.stopPropagation();
self.updateSlider(e, true);
this.addEventListener("touchmove", function(e){
e=e||window.event;
e.preventDefault();
e.stopPropagation();
self.updateSlider(event, false);
});
});
this.handle.addEventListener("keydown", function (e){
e=e||window.event;
var key=e.which||e.keyCode;
var ariaValue=parseFloat(this.style.left);
if(key==37){
ariaValue=ariaValue - 1;
var leftStart=parseFloat(this.style.left) - 1;
self.updateSlider(leftStart, false);
self.controller.setAttribute('aria-valuenow', ariaValue);
}
if(key==39){
ariaValue=ariaValue + 1;
var rightStart=parseFloat(this.style.left) + 1;
self.updateSlider(rightStart, false);
self.controller.setAttribute('aria-valuenow', ariaValue);
}});
this.leftImage.addEventListener("keydown", function (event){
var key=event.which||event.keyCode;
if((key==13)||(key==32)){
self.updateSlider("90%", true);
self.controller.setAttribute('aria-valuenow', 90);
}});
this.rightImage.addEventListener("keydown", function (event){
var key=event.which||event.keyCode;
if((key==13)||(key==32)){
self.updateSlider("10%", true);
self.controller.setAttribute('aria-valuenow', 10);
}});
juxtapose.sliders.push(this);
if(this.options.callback&&typeof(this.options.callback)=='function'){
this.options.callback(this);
}}
};
juxtapose.makeSlider=function (element, idx){
if(typeof idx=='undefined'){
idx=juxtapose.sliders.length;
}
var w=element;
var images=w.querySelectorAll('img');
var options={};
if(w.getAttribute('data-animate')){
options.animate=w.getAttribute('data-animate');
}
if(w.getAttribute('data-showlabels')){
options.showLabels=w.getAttribute('data-showlabels');
}
if(w.getAttribute('data-showcredits')){
options.showCredits=w.getAttribute('data-showcredits');
}
if(w.getAttribute('data-startingposition')){
options.startingPosition=w.getAttribute('data-startingposition');
}
if(w.getAttribute('data-mode')){
options.mode=w.getAttribute('data-mode');
}
if(w.getAttribute('data-makeresponsive')){
options.mode=w.getAttribute('data-makeresponsive');
}
specificClass='juxtapose-' + idx;
addClass(element, specificClass);
selector='.' + specificClass;
if(w.innerHTML){
w.innerHTML='';
}else{
w.innerText='';
}
slider=new juxtapose.JXSlider(selector,
[
{
src: images[0].src,
label: images[0].getAttribute('data-label'),
credit: images[0].getAttribute('data-credit'),
alt: images[0].alt
},
{
src: images[1].src,
label: images[1].getAttribute('data-label'),
credit: images[1].getAttribute('data-credit'),
alt: images[1].alt
}
],
options
);
};
juxtapose.scanPage=function(){
var elements=document.querySelectorAll('.juxtapose');
for (var i=0; i < elements.length; i++){
juxtapose.makeSlider(elements[i], i);
}};
juxtapose.JXSlider=JXSlider;
window.juxtapose=juxtapose;
juxtapose.scanPage();
}(document, window));
!window.addEventListener&&(function (WindowPrototype, DocumentPrototype, ElementPrototype, addEventListener, removeEventListener, dispatchEvent, registry){
WindowPrototype[addEventListener]=DocumentPrototype[addEventListener]=ElementPrototype[addEventListener]=function (type, listener){
var target=this;
registry.unshift([target, type, listener, function (event){
event.currentTarget=target;
event.preventDefault=function (){ event.returnValue=false };
event.stopPropagation=function (){ event.cancelBubble=true };
event.target=event.srcElement||target;
listener.call(target, event);
}]);
this.attachEvent("on" + type, registry[0][3]);
};
WindowPrototype[removeEventListener]=DocumentPrototype[removeEventListener]=ElementPrototype[removeEventListener]=function (type, listener){
for (var index=0, register; register=registry[index]; ++index){
if(register[0]==this&&register[1]==type&&register[2]==listener){
return this.detachEvent("on" + type, registry.splice(index, 1)[0][3]);
}}
};
WindowPrototype[dispatchEvent]=DocumentPrototype[dispatchEvent]=ElementPrototype[dispatchEvent]=function (eventObject){
return this.fireEvent("on" + eventObject.type, eventObject);
};})(Window.prototype, HTMLDocument.prototype, Element.prototype, "addEventListener", "removeEventListener", "dispatchEvent", []);