Kawasaki Yusuke - Animation.Raster-0.02
NAME
Animation.Raster -- Virtual Raster Scrolling Animation
SYNOPSIS
var ras = new Animation.Raster( id_or_elem, image_url );
ras.lineHeight = 6; // scroll line's height
ras.clip = true; // clip animation area (default: true)
ras.background = "#000000"; // animation area's background
ras.downSeconds = 1.0; // falling down animation
ras.fadeSeconds = 4.0; // fading wave animation
ras.waveSpeed = 0.5; // wave's speed
ras.onComplete = function () { ... }; // callback function
ras.scroll();
DESCRIPTION
This library provides a animation effect of virtual raster scrolling for images and block elements.
METHODS
ras = new Animation.Raster( id_or_elem, image_url );
This constructor method returns a new Animation.Raster object. The first argument is the animation's container element or its id string. The second argument is the target image's URL for raster scrolling. If URL is not defined, container element itself is animated.
ras.scroll();
This method starts a animation effect.
ras.finish();
This method forces to stop a animation effect if it's running.
AUTHOR
Yusuke Kawasaki http://www.kawa.net/
COPYRIGHT AND LICENSE
Copyright (c) 2005-2006 Yusuke Kawasaki. All rights reserved. This program is free software; you can redistribute it and/or modify it under the Artistic license. Or whatever license I choose, which I will do instead of keeping this documentation like it is.
// Animation.Raster
if ( typeof(Animation) == "undefined" ) Animation = function () {};
Animation.Raster = function (container,imgsrc) {
if ( ! container ) return;
this.initialized = false; // canvas size is known or not
this.startOnLoad = false; // start commanded received
this.started = false; // start flag
this.finished = false; // all done flag
this.linebuf = []; // rect lines buffer
this.trush = [];
this.onComplete = null; // call back function
this.initialize(container,imgsrc);
return this;
};
Animation.Raster.VERSION = "0.02";
Animation.Raster.prototype.waveSpeed = 0.5;
Animation.Raster.prototype.waveHeight = 0.5;
Animation.Raster.prototype.lineHeight = 6;
Animation.Raster.prototype.downSeconds = 1.0;
Animation.Raster.prototype.fadeSeconds = 4.0;
Animation.Raster.prototype.clip = true;
Animation.Raster.prototype.background = null;
Animation.Raster.prototype.initialize = function( container,imgsrc ) {
if ( typeof container == "string" ) {
container = document.getElementById(container);
}
if ( ! container ) return;
this.outer = document.createElement( "div" );
this.outer.style.position = "relative";
this.canvas = document.createElement( "div" );
this.canvas.style.position = "absolute";
this.outer.appendChild( this.canvas );
if ( imgsrc ) {
container.appendChild( this.outer );
this.original = document.createElement( "img" ); // source image
this.original.src = imgsrc;
this.original.style.visibility = "hidden";
this.outer.appendChild( this.original );
this.getImageSize( this.original );
} else {
container.parentNode.insertBefore( this.outer, container );
this.original = container; // original
this.original.style.visibility = "hidden";
this.canvasWidth = this.original.offsetWidth;
this.canvasHeight = this.original.offsetHeight;
this.initialized = true; //
}
};
Animation.Raster.prototype.getImageSize = function( orig ) {
var loadmess = this.message( "Now loading..." );
var checksize = orig.cloneNode(true); // image for checking
checksize.style.position = "absolute";
var __this = this;
var ldfunc = function(e){
if ( ! e && window.event ) e = window.event; // IE
__this.canvasWidth = checksize.offsetWidth;
__this.canvasHeight = checksize.offsetHeight;
__this.initialized = true;
checksize.parentNode.removeChild( checksize );
loadmess.parentNode.removeChild( loadmess );
if ( __this.startOnLoad ) {
__this.beginAnimation();
}
};
this.appendEvent( checksize, "load", ldfunc ); // onload image
this.outer.appendChild( checksize );
};
Animation.Raster.prototype.clipCanvas = function() {
if ( ! this.canvasWidth || ! this.canvasHeight ) return;
this.canvas.style.width = this.canvasWidth+"px";
this.canvas.style.height = this.canvasHeight+"px";
if ( this.clip ) {
this.canvas.style.clip = "rect(0px,"+(this.canvasWidth)+"px,"+(this.canvasHeight)+"px,0px)";
}
}
Animation.Raster.prototype.clickToFinish = function() {
var __this = this;
var clfunc = function(e){
if ( ! e && window.event ) e = window.event; // IE
if ( ! __this.initialized ) return; // not loaded yet
if ( ! __this.started ) return; // not started yet
if ( __this.finished ) return; // already done
__this.finish();
};
this.appendEvent( this.canvas, "click", clfunc ); // onclick canvas
}
Animation.Raster.prototype.message = function( mess ) {
var tload = document.createTextNode( mess );
elem = document.createElement( "span" );
elem.appendChild( tload );
elem.style.color = "#FFFFFF";
elem.style.background = "#FF3333";
elem.style.position = "absolute";
elem.style.fontSize = "12px";
elem.style.fontFamily = "Helvetica";
elem.style.fontWeight = "bold";
elem.style.width = "14em";
elem.style.padding = "4px";
if ( this.outer.firstChild ) {
this.outer.insertBefore( elem, this.outer.firstChild );
} else {
this.outer.appendChild( elem );
}
return elem;
}
Animation.Raster.prototype.appendEvent = function( elem, type, func ) {
if ( elem.addEventListener ) {
return elem.addEventListener( type, func, false );
} else if ( elem.attachEvent ) {
return elem.attachEvent( "on"+type, func );
}
};
Animation.Raster.SinCache = [];
Animation.Raster.prototype.get_sin_table = function(intrv) {
if ( Animation.Raster.SinCache[intrv] ) return Animation.Raster.SinCache[intrv];
var sintable = [];
for( var i=0; i<intrv; i++ ) {
sintable[i] = Math.sin(2.0 * Math.PI * i / intrv);
}
Animation.Raster.SinCache[intrv] = sintable;
return sintable;
};
Animation.Raster.prototype.beginAnimation = function() {
if ( this.background ) this.canvas.style.background = this.background;
var sinsize = Math.floor( this.canvasHeight / this.lineHeight );
this.sinTable = this.get_sin_table(sinsize);
this.clipCanvas();
this.clickToFinish();
var lines = Math.floor(this.canvasHeight/this.lineHeight);
for( var i=lines; i>=0; i-- ) {
this.cloneLine(i,this.lineHeight)
}
this.timer = new Animation.Raster.Timer(this); // timer object
this.timer.start();
};
Animation.Raster.prototype.scroll = function() {
this.started = true;
if ( this.initialized ) {
this.beginAnimation();
} else {
this.startOnLoad = true; // wait until image loaded
}
};
Animation.Raster.prototype.cloneLine = function(top,lines) {
if ( this.linebuf[top] ) return this.linebuf[top];
var newline = this.original.cloneNode(true);
newline.style.position = "absolute";
newline.style.visibility = "hidden";
newline.style.clip = "rect("+(top*lines)+"px,"+(this.canvasWidth)+"px,"+((top+1)*lines)+"px,0px)";
this.canvas.appendChild( newline );
this.linebuf[top] = newline;
return newline;
};
Animation.Raster.prototype.loop = function(secs,count) {
var lines = Math.floor(this.canvasHeight/this.lineHeight);
secs *= 0.001; // millisec to second
var wavy = this.canvasHeight*this.waveHeight;
var y = 0;
var top = 0;
if ( secs < this.downSeconds ) {
var prog1 = secs/this.downSeconds;
y = Math.floor(prog1*this.canvasHeight) - this.canvasHeight;
y -= y % this.lineHeight;
top = Math.floor( lines*(1.0-prog1) );
} else if ( secs < this.downSeconds + this.fadeSeconds ) {
var prog3 = (secs-this.downSeconds)/this.fadeSeconds;
wavy *= (1.0-prog3);
} else {
this.finish();
return false;
}
var wavecnt = Math.floor(secs*this.sinTable.length*this.waveSpeed);
for( var i=top; i<=lines; i++ ) {
var x = Math.floor( wavy * this.sinTable[(i-top+wavecnt)%this.sinTable.length] );
this.linebuf[i].style.left = x+"px";
this.linebuf[i].style.top = y+"px";
this.linebuf[i].style.visibility = "visible";
}
return true;
};
Animation.Raster.prototype.finish = function() {
if ( this.timer ) {
if ( this.timer.is_running() ) this.timer.stop();
this.timer = null;
}
if ( this.finished ) return;
this.original.style.visibility = "visible";
this.canvas.style.background = "";
for( var i=0; i<this.linebuf.length; i++ ) {
if ( ! this.linebuf[i] ) continue;
if ( ! this.linebuf[i].parentNode ) continue;
this.linebuf[i].parentNode.removeChild( this.linebuf[i] );
this.linebuf[i] = null;
}
for( var i=0; i<this.trush.length; i++ ) {
if ( ! this.trush[i] ) continue;
if ( ! this.trush[i].parentNode ) continue;
this.trush[i].parentNode.removeChild( this.trush[i] );
this.trush[i] = null;
}
this.finished = true;
if ( this.onComplete ) this.onComplete( this.original );
};
// Animation.Raster.Timer class
Animation.Raster.Timer = function (target) {
this.target = target;
this.started = false;
this.stoped = false;
this.count = 0;
var __this = this;
this.next = function(){
if ( __this.stoped ) return;
var now_time = (new Date()).getTime();
if ( ! __this.begin_time ) __this.begin_time = now_time;
var spent_time = now_time-__this.begin_time;
var flag = __this.target.loop(spent_time,__this.count++);
if ( flag ) {
setTimeout( __this.next, 1 );
} else {
__this.stop();
}
};
return this;
};
Animation.Raster.Timer.prototype.start = function () {
this.started = true;
this.stoped = false;
this.next();
};
Animation.Raster.Timer.prototype.stop = function () {
this.stoped = true;
};
Animation.Raster.Timer.prototype.is_running = function () {
return ( this.started && ! this.stoped );
};
/*
// ========================================================================
=head1 NAME
Animation.Raster -- Virtual Raster Scrolling Animation
=head1 SYNOPSIS
var ras = new Animation.Raster( id_or_elem, image_url );
ras.lineHeight = 6; // scroll line's height
ras.clip = true; // clip animation area (default: true)
ras.background = "#000000"; // animation area's background
ras.downSeconds = 1.0; // falling down animation
ras.fadeSeconds = 4.0; // fading wave animation
ras.waveSpeed = 0.5; // wave's speed
ras.onComplete = function () { ... }; // callback function
ras.scroll();
=head1 DESCRIPTION
This library provides a animation effect of virtual raster scrolling
for images and block elements.
=head1 METHODS
=head2 ras = new Animation.Raster( id_or_elem, image_url );
This constructor method returns a new Animation.Raster object.
The first argument is the animation's container element or its id string.
The second argument is the target image's URL for raster scrolling.
If URL is not defined, container element itself is animated.
=head2 ras.scroll();
This method starts a animation effect.
=head2 ras.finish();
This method forces to stop a animation effect if it's running.
=head1 AUTHOR
Yusuke Kawasaki http://www.kawa.net/
=head1 COPYRIGHT AND LICENSE
Copyright (c) 2005-2006 Yusuke Kawasaki. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the Artistic license. Or whatever license I choose,
which I will do instead of keeping this documentation like it is.
=cut
// ========================================================================
*/