/*
this object shows a transform from one image to another
within a canvas. If images are of different size
the canvas shows the smaller dimensions
*/
function transformer(imSelector,canvasId){
// all images, assume at least two
this.imageList=document.querySelectorAll(imSelector);
// determine dimensions
this.W=1000;
this.H=1000;
for(var ix=0;ix <this.imageList.length;ix++){
this.W=Math.min(this.W,this.imageList[ix].width);
this.H=Math.min(this.H,this.imageList[ix].height);
}
// prepare canvas
this.canShow=document.getElementById(canvasId);
this.canShow.width=this.W;
this.canShow.height=this.H;
// assume this is supported
this.canShowDC=this.canShow.getContext('2d');
// fill with first image
this.currentIndex=0;
this.canShowDC.drawImage(this.imageList[0],0,0,this.W,this.H) ;
// initiate change in color components pr frame
// and time between frames
this.stepLength=4;
this.wait=50;
// flag activity is on
this.isTransforming=false;
// set up canvas to store coming image
this.canFrom=document.createElement("canvas");
this.canFrom.width=this.W;
this.canFrom.height=this.H;
// put it somewhere ?, not necessary
this.dcFrom=this.canFrom.getContext('2d');
this.dcFrom.drawImage(this.imageList[0],0,0,this.W,this.H);
// when wepic up data
this.fromData=this.dcFrom.getImageData(0,0,this.W,this.H);
this.showData=this.canShowDC.getImageData(0,0,this.W,this.H);
//how far are we from solved
this.maxDiff=0;
// calculate one color component
this.calcOne=function (v1,v2){
var diff=v2-v1;
this.maxDiff=Math.max(this.maxDiff,Math.abs(diff));
if(diff >= 0)
return v2-Math.min(this.stepLength,diff);
return v2+Math.min(this.stepLength,-diff);
}
// do one frame
this.oneStep=function(){
// manipulate all pixels
// bring fromData closer to toData
// display it in tocanvas
// assume dimensions are same
this.maxDiff=0;
for (var i=0; i < this.W*this.H*4; i+=4)
{
this.showData.data[i] =
this.calcOne(this.fromData.data[i],this.showData.data[i]);
this.showData.data[i+1] =
this.calcOne(this.fromData.data[i+1],this.showData.data[i+1]);
this.showData.data[i+2] =
this.calcOne(this.fromData.data[i+2],this.showData.data[i+2]);
this.showData.data[i+3] =
this.calcOne(this.fromData.data[i+3],this.showData.data[i+3]);
}
// put it into the other canvas
this.canShow.getContext('2d').putImageData(this.showData,0,0);
if(this.maxDiff >this.stepLength)
setTimeout(this.oneStep.bind(this),this.wait);
else{
this.isTransforming=false;
this.canShow.classList.remove("atwork");
}
}
// forward, ie next in imagelist
this.transForward=function (){
if(this.isTransforming)
return;
this.isTransforming=true;
this.canShow.classList.add("atwork");
this.currentIndex++;
if(this.currentIndex >= this.imageList.length)
this.currentIndex=0;
this.dcFrom.drawImage(this.imageList[this.currentIndex],0,0,this.W,this.H);
this.fromData=this.dcFrom.getImageData(0,0,this.W,this.H);
this.oneStep();
}
// back, previous in image lsit
this.transBack=function (){
if(this.isTransforming)
return;
this.isTransforming=true;
this.canShow.classList.add("atwork");
this.currentIndex--;
if(this.currentIndex <0 )
this.currentIndex=this.imageList.length-1;
this.dcFrom.drawImage(this.imageList[this.currentIndex],0,0,this.W,this.H);
this.fromData=this.dcFrom.getImageData(0,0,this.W,this.H);
this.oneStep();
}
// speed is difference in change of one color component
// n is difference in change of one color component
// t is millisec between each update
this.setSpeed=function(n){
if((n >0) && (n<255))
this.stepLength=n;
if((n >10) && (n<1000))
this.wait=t;
}
}