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 // ======================================================================== */