I am creating a 650 X 610 px historical railway map and would like to start with a blank map, then fade in transparent .png layers containing just a fragment of the railway, one on top of the other, building up to an image of the whole network.
There would be a list of the dates the network was extended to click and make that bit of line appear. Easily done using solid images, but very slow and there are 31 images.
I couldn't find any forum queries about this anywhere. Please could anyone help?
Try this simple example (tested in Opera 10 and Firefox 2). Each image must be of the same dimension. Meaning that each layer is placed at the same location.
What you should change are:
All width
and height
values (in pixels) within <style>
block to match your complete map.
The layerdata
array, which contains an object for each layer's date selection text (date
) and the URL of the image (url
).
animdelay
. Delay in millisecond (1/1000 second) unit per opacity level for fade in/out. The default is 100ms. There's a total of 10 opacity levels. Decrease the delay to speed up the animation.
sample.html
:
<html>
<head>
<style>
#dates label { display:block; }
#frame { border:1px solid black; width:500px; height:500px; }
.layer {
"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter:alpha(opacity=0);
opacity:0; position:absolute; width:500px; height:500px;
}
</style>
</head>
<body>
Date:
<div id="dates">
</div>
<div id="frame">
</div>
<script>
//get element opacity for Internet Explorer
function getOpacityIE(ele) { //returns level: 0-100
return ele.filters[0].opacity;
}
//set element opacity for Internet Explorer
function setOpacityIE(ele,level) { //level: 0-100
ele.filters[0].opacity=level;
}
//get element opacity for web-standard browsers
function getOpacityStd(ele) { //returns level: 0-100
return (ele.style.opacity!=''?ele.style.opacity*100:0);
}
//set element opacity for web-standard browsers
function setOpacityStd(ele,level) { //level: 0-100
ele.style.opacity=(level/100).toFixed(1);
}
//fade in/out each layers based on target date index
function animate() {
var done=true;
for (var i=0; i<layers.length; i++) {
var adjust=i<=dateidx?10:-10;
var level=getOpacity(layers[i]);
if (((adjust>0)&&(level<100)) || ((adjust<0)&&(level>0))) {
setOpacity(layers[i],level+adjust);
done=false;
}
}
if (!done) animtimer=window.setTimeout(animate,animdelay);
}
//set/update layer index to show/hide and animate it
function setdate(ele) {
window.clearTimeout(animtimer);
dateidx=ele.attributes['index'].value*1;
animate();
}
//add date selection, below any existing one
function addselection(idx,date) {
var a=document.createElement('LABEL');
a.htmlFor='date'+idx;
a.innerHTML='<input id="date'+idx+'" index="'+idx+'" name="date" type="radio" onclick="setdate(this)" /> '+date;
dates.appendChild(a);
}
//add layer (image) into frame, on top of any existing one
function addlayer(idx,url) {
var a=document.createElement('IMG');
a.className='layer';
a.src=url;
layers.push(a);
frame.appendChild(a);
}
//layerdata: from bottom to top
var layerdata=[
{date:'2000-01-01', url:'image1.png'},
{date:'2000-01-08', url:'image2.png'},
{date:'2000-01-15', url:'image3.png'},
{date:'2000-01-22', url:'image4.png'}
];
//animation delay in 1/1000 second unit per opacity level
var animdelay=100;
//runtime variables
var dateidx=-1;
var layers=[];
var animtimer=0;
if (typeof(frame.style.opacity)!='undefined') {
var getOpacity=getOpacityStd;
var setOpacity=setOpacityStd;
} else {
var getOpacity=getOpacityIE;
var setOpacity=setOpacityIE;
}
//generate date selections and layers
for (var i=0; i<layerdata.length; i++) {
addselection(i,layerdata[i].date);
addlayer(i,layerdata[i].url);
}
</script>
</body>
</html>