PDA

View Full Version : Javascript array with PHP



Keithb
12-12-2008, 12:23 AM
I'm not sure if this should go in the PHP forum but as the issue concerns Javascript I've put it here. I am experimenting with a script that uses PHP to populate an array with the contents of a directory (a list of image files). This is the PHP:



<?
//PHP SCRIPT: getimages.php
Header("content-type: application/x-javascript");

//This function gets the file names of all images in the current directory
//and ouputs them as a JavaScript array
function returnimages($dirname=".") {
$pattern="(\.jpg$)|(\.png$)|(\.jpeg$)|(\.gif$)"; //valid image extensions
$files = array();
$curimage=0;
if($handle = opendir($dirname)) {
while(false !== ($file = readdir($handle))){
if(eregi($pattern, $file)){ //if this file is a valid image
//Output it as a JavaScript array element
echo 'galleryarray['.$curimage.']="'.$file .'";';
$curimage++;
}
}

closedir($handle);
}
return($files);
}

echo 'var galleryarray=new Array();'; //Define array in JavaScript
returnimages() //Output the array elements containing the image file names
?>

and the javascript:



<HTML>
<HEAD>

<script src="http://www.wthrman.com/maps/surface/200001/getimages.php">
//This is the directory where the images are eg www.wthrman.com/maps/surface/ etc..put the php in there
</script>

<script type="text/javascript">

var curimg=0
function rotateimages(){
document.getElementById("slideshow").setAttribute("src", "http://www.wthrman.com/maps/surface/200001/"+galleryarray[curimg])//Change the directory here too ie "..." + galleryarray[curimg]
curimg=(curimg<galleryarray.length-1)? curimg+1 : 0
}

window.onload=function(){
setInterval("rotateimages()", 2500)
}
</script>
</HEAD>
<BODY>

<div style="width: 680px; height: 400px">
<img id="slideshow" src="2000010100.png"/>
</div>
</BODY>
</HTML>

As it stands, the scripts automatically run a slideshow of all the images in the directory, when the .htm file is opened. However I don't want to automatically see all the files, but only a certain range of them. The images have date formats as in YYYYMMDDHH (HH is for hours at 6-hourly intervals ie 00,06,12,18).

I'm sure this can be done with 2 sets of option boxes that select a first and last date based on the above file format...the idea is to view all the images in between the two dates selected (there will be a box of options for first and last year, month, day and hour..this is the only way I know how to specify the dates).

I've no problem with setting up the option boxes, but apart from having to bypass the automatic 'onload' so the user can access them, I don't know what I then should do to get only the images between the two dates, into the array, assuming it would function as it does with all the images, as outlined above.

The foregoing is all a bit long-winded but I think there's got to be a simple solution.

Could someone please help?

Thank you

jscheuer1
12-12-2008, 04:06 AM
That looks a lot like getpics.php (text version):

http://www.dynamicdrive.com/dynamicindex4/phpgallery/getpics.php.txt

which outputs an array like so (active PHP version):

http://www.dynamicdrive.com/dynamicindex4/phpgallery/getpics.php

As you can see in the active version the date and time are in the second part of each array contained in the main galleryarray entry for each image (galleryarray[#][1]) which could then be parsed for hour, ex:


<script type="text/javascript">
var galleryarray=new Array();
galleryarray[0]=["jag1.jpg", "Aug 11, 2007 17:00:05"];
galleryarray[1]=["jag10.jpg", "Aug 11, 2007 17:00:07"];
galleryarray[2]=["jag11.jpg", "Aug 11, 2007 17:00:08"];
galleryarray[3]=["jag12.jpg", "Aug 11, 2007 17:00:08"];
galleryarray[4]=["jag13.jpg", "Aug 11, 2007 17:00:09"];
galleryarray[5]=["jag14.jpg", "Aug 11, 2007 17:00:10"];
galleryarray[6]=["jag2.jpg", "Aug 11, 2007 17:00:10"];
galleryarray[7]=["jag3.jpg", "Aug 11, 2007 17:00:11"];
galleryarray[8]=["jag4.jpg", "Aug 11, 2007 17:00:12"];
galleryarray[9]=["jag5.jpg", "Aug 11, 2007 17:00:13"];
galleryarray[10]=["jag6.jpg", "Aug 11, 2007 17:00:14"];
galleryarray[11]=["jag7.jpg", "Aug 11, 2007 17:00:17"];
galleryarray[12]=["jag8.jpg", "Aug 11, 2007 17:00:18"];
galleryarray[13]=["jag9.jpg", "Aug 11, 2007 17:00:18"];

alert(galleryarray[0][1].replace(/^[^:]* (\d+):.*$/, '$1'));
</script>

In a similar fashion one could get the year, etc. However, this information is also available on the server side, and it might be better to get at it in that fashion. If so, ask in the PHP forum.

Keithb
12-12-2008, 04:44 AM
Thanks John, I did base it on a similarly-named script from another forum..forget which one now...maybe a modified version of the one you refer to, I don't know.

I've been doing more trawling around and I think I probably need some sort of date script, as the names of the images I want to view are defined by dates (as selected in the option boxes). PHP was the latest option I had tried as I couldn't get anything else to work. But the main issue is really how to populate the array with the image names (eg 2008010112.png) so as to view them in a slideshow.

There are probably better ways of doing all this than what I've posted but the multitude of slideshow programs online so far haven't been of much help, unfortunately.

jscheuer1
12-12-2008, 07:17 AM
Since, as far as I could tell, you currently have only images for January 2000, I only allowed for those values in the month and year selects. I noticed that there were images for hour 3, but since you didn't mention those in your post, I didn't include them in the hour selects. Anything may be added or removed from the selects as long as your image base will support the resulting values. The hour 3 images will show up, if they are in range of the selected values:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<script src="http://www.wthrman.com/maps/surface/200001/getimages.php" type="text/javascript">
//This is the directory where the images are eg www.wthrman.com/maps/surface/ etc..put the php in there
</script>

<script type="text/javascript">
(function(g){
for (var i = g.length - 1; i > -1; --i)
g[i] = g[i].split('.');
g.sort(function(a, b){return b[0] - a[0];});
})(galleryarray);

var galshow = function(f, g){
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = []; var v = function(el){return el.value;};
for (var i = galleryarray.length - 1; i > -1; --i)
if(galleryarray[i][0] >= v(f.by) + v(f.bm) + v(f.bd) + v(f.bh) && galleryarray[i][0] <= v(f.ey) + v(f.em) + v(f.ed) + v(f.eh))
g.gal.push(galleryarray[i].join('.'));
g.rotateimages();
g.timer = setInterval(g.rotateimages, 2500)
};

galshow.rotateimages = function(g){
g = galshow;
document.getElementById("slideshow").src = 'http://www.wthrman.com/maps/surface/200001/' + g.gal[g.curimg];//Change the directory here too ie "..." + galleryarray[curimg]
g.curimg = g.curimg < g.gal.length-1? g.curimg + 1 : 0;
};

galshow.r = new RegExp('(\\d{4})(\\d\\d)(\\d\\d)(\\d\\d)');

onload = function(){
document.getElementById("slideshow").onload = function(){
var g = galshow;
if(g.timer)
document.getElementById('num').firstChild.nodeValue = g.gal[g.curimg].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4');
};
};

</script>
</head>
<body>
<div style="width: 680px;height: 500px;">
<span id="num">Year: 2000 Month: 01 Date: 01 Hour: 00</span><br>
<img id="slideshow" src="http://www.wthrman.com/maps/surface/200001/2000010100.png" alt="Weather Map" title=""><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2000">2000</option>
</select>
End Year: <select name="ey">
<option value="2000">2000</option>
</select>
Begin Month: <select name="bm">
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>
End Hour: <select name="eh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>

<input type="submit" value="Go!">
</div>
</form>
</body>
</html>

jscheuer1
12-12-2008, 07:50 AM
I realized that there were a few minor improvements, most are just efficiencies, but some are required to make it so that it doesn't get out of sync with the image data shown at the top and the image shown:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<script src="http://www.wthrman.com/maps/surface/200001/getimages.php" type="text/javascript">
//This is the directory where the images are eg www.wthrman.com/maps/surface/ etc..put the php in there
</script>

<script type="text/javascript">
(function(g){
for (var i = g.length - 1; i > -1; --i)
g[i] = g[i].split('.');
g.sort(function(a, b){return b[0] - a[0];});
})(galleryarray);

var galshow = function(f, g){
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = []; var v = function(el){return el.value;};
for (var i = galleryarray.length - 1; i > -1; --i)
if(galleryarray[i][0] >= v(f.by) + v(f.bm) + v(f.bd) + v(f.bh) && galleryarray[i][0] <= v(f.ey) + v(f.em) + v(f.ed) + v(f.eh))
g.gal.push(galleryarray[i].join('.'));
g.rotateimages();
};

galshow.rotateimages = function(g){
g = galshow;
document.getElementById("slideshow").src = 'http://www.wthrman.com/maps/surface/200001/' + g.gal[g.curimg];//Change the directory here too ie "..." + galleryarray[curimg]
};

galshow.r = new RegExp('(\\d{4})(\\d{2})(\\d{2})(\\d{2})');

onload = function(){
document.getElementById("slideshow").onload = function(){
var g = galshow;
if(!g.gal) return;
document.getElementById('num').firstChild.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.rotateimages, 2500);
};
};

</script>
</head>
<body>
<div style="width: 680px;height: 500px;">
<span id="num">Year: 2000 Month: 01 Date: 01 Hour: 00</span><br>
<img id="slideshow" src="http://www.wthrman.com/maps/surface/200001/2000010100.png" alt="Weather Map" title=""><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2000">2000</option>
</select>
End Year: <select name="ey">
<option value="2000">2000</option>
</select>
Begin Month: <select name="bm">
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>
End Hour: <select name="eh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>

<input type="submit" value="Go!">
</div>
</form>
</body>
</html>

Keithb
12-12-2008, 07:54 AM
John, I can't thank you enough for the way in which over a few hours you've come up with a solution that I could never have dreamed of despite bashing my head in Javascript etc for several days! No wonder I was struggling!

I will add further years (I have maps going back to 1948) and see how that goes but it's working perfectly at present. I left out other years for the sake of (relative) brevity in the forum. Thanks also for the mention of the hours; I haven't finished tidying that up but the maps only run every 6 hours so I should have deleted the ones that weren't needed.

If I have further issues I hope you will be able to help me further but as it stands, I doubt I will have any further problems.

Thanks again.

jscheuer1
12-12-2008, 08:26 AM
Once I start playing with something, sometimes I get a little carried away. I decided to add a pause onmouseover of the image, and a few more efficiencies:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<script src="http://www.wthrman.com/maps/surface/200001/getimages.php" type="text/javascript">
//This is the directory where the images are eg www.wthrman.com/maps/surface/ etc..put the php in there
</script>

<script type="text/javascript">
(function(g){
for (var i = g.length - 1; i > -1; --i)
g[i] = g[i].split('.');
g.sort(function(a, b){return b[0] - a[0];});
})(galleryarray);

var galshow = function(f, g){
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = [];
var b = [g.v(f.by), g.v(f.bm), g.v(f.bd), g.v(f.bh)].join(''), e = [g.v(f.ey), g.v(f.em), g.v(f.ed), g.v(f.eh)].join('');
for (var i = galleryarray.length - 1; i > -1; --i)
if(galleryarray[i][0] >= b && galleryarray[i][0] <= e)
g.gal.push(galleryarray[i].join('.'));
g.rotateimages();
};

galshow.v = function(el){return el.value;};

galshow.pause = function(){
if(galshow.p){
galshow.timer = setTimeout(galshow.pause, 300);
return;
}
galshow.rotateimages();
};

galshow.rotateimages = function(g){
g = galshow;
document.getElementById("slideshow").src = 'http://www.wthrman.com/maps/surface/200001/' + g.gal[g.curimg];//Change the directory here too ie "..." + galleryarray[curimg]
};

galshow.r = new RegExp('(\\d{4})(\\d{2})(\\d{2})(\\d{2})');

onload = function(){
var im = document.getElementById("slideshow");
im.onload = function(){
var g = galshow;
if(!g.gal) return;
document.getElementById('num').firstChild.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.pause, 2500);
};
im.onmouseover = function(){galshow.p = true;};
im.onmouseout = function(){galshow.p = false;};
};

</script>
</head>
<body>
<div style="width: 680px;height: 500px;">
<span id="num">Year: 2000 Month: 01 Date: 01 Hour: 00</span><br>
<img id="slideshow" src="http://www.wthrman.com/maps/surface/200001/2000010100.png" alt="Weather Map" title="Paused"><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2000">2000</option>
</select>
End Year: <select name="ey">
<option value="2000">2000</option>
</select>
Begin Month: <select name="bm">
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>
End Hour: <select name="eh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>

<input type="submit" value="Go!">
<input type="button" value="Stop" onclick="clearTimeout(galshow.timer);">
</div>
</form>
</body>
</html>

Keithb
12-12-2008, 08:39 AM
John that's fantastic! I was just about to ask about pausing and stopping the sequence. How would I add buttons for stopping, restarting or pausing?

jscheuer1
12-12-2008, 09:52 AM
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<script src="http://www.wthrman.com/maps/surface/200001/getimages.php" type="text/javascript">
//This is the directory where the images are eg www.wthrman.com/maps/surface/ etc..put the php in there
</script>

<script type="text/javascript">
(function(g){
for (var i = g.length - 1; i > -1; --i)
g[i] = g[i].split('.');
g.sort(function(a, b){return b[0] - a[0];});
})(galleryarray);

var galshow = function(f, g){
g.im.title = 'Paused';
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = []; f.stop.disabled = false;
var b = [g.v(f.by), g.v(f.bm), g.v(f.bd), g.v(f.bh)].join(''), e = [g.v(f.ey), g.v(f.em), g.v(f.ed), g.v(f.eh)].join('');
for (var i = galleryarray.length - 1; i > -1; --i)
if(galleryarray[i][0] >= b && galleryarray[i][0] <= e)
g.gal.push(galleryarray[i].join('.'));
g.rotateimages();
};

galshow.v = function(el){return el.value;};

galshow.pause = function(){
if(galshow.p){
galshow.timer = setTimeout(galshow.pause, 300);
return;
}
galshow.rotateimages();
};

galshow.rotateimages = function(g){
g = galshow;
g.im.src = 'http://www.wthrman.com/maps/surface/200001/' + g.gal[g.curimg];//Change the directory here too ie "..." + galleryarray[curimg]
};

galshow.r = new RegExp('(\\d{4})(\\d{2})(\\d{2})(\\d{2})');

onload = function(){
var g = galshow; g.im = document.getElementById('slideshow');
g.im.onload = function(){
if(!g.gal) return;
document.getElementById('num').firstChild.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.pause, 2500);
};
g.im.onmouseover = function(){g.p = true;};
g.im.onmouseout = function(){g.p = false;};
};

</script>
</head>
<body>
<div style="width: 680px;height: 500px;">
<span id="num">Year: 2000 Month: 01 Date: 01 Hour: 00</span><br>
<img id="slideshow" src="http://www.wthrman.com/maps/surface/200001/2000010100.png" alt="Weather Map" title=""><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2000">2000</option>
</select>
End Year: <select name="ey">
<option value="2000">2000</option>
</select>
Begin Month: <select name="bm">
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>
End Hour: <select name="eh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>

<input type="submit" value="Go!">
<input type="button" name="stop" disabled value="Stop" onclick="clearTimeout(galshow.timer);galshow.im.title='Stopped';this.form.elements.resume.disabled=false;">
<input type="button" name="resume" disabled value="Resume" onclick="this.disabled=true;galshow.rotateimages();galshow.im.title='Paused';">
</div>
</form>
</body>
</html>

Keithb
12-12-2008, 11:47 AM
Thanks again John.

As a bit of a refinement I tried to put in an option to change the speed:


<INPUT TYPE="radio" onclick="galshow.timer = setTimeout(galshow.pause, 1000);"checked>1 sec (default)


This appeared to make the sequence timing uneven. The reason I want to vary the speed is that I will later on use satellite animations at different speeds, with a button for each (I hadn't mentioned this before as I was so preoccupied in getting the basic operation right).

Can I push my luck here and ask where the above snippet is wrong?

Thanks

jscheuer1
12-12-2008, 05:23 PM
That will introduce a new series of iterations with only the first having the 1000 millisecond delay. As a result, there will be two series of iterations operating at once, making things choppy. Here's my latest version, I've included your new idea:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<script src="http://www.wthrman.com/maps/surface/200001/getimages.php" type="text/javascript">
//This is the directory where the images are eg www.wthrman.com/maps/surface/ etc..put the php in there
</script>

<script type="text/javascript">
var galshow = function(){alert('Sorry, your browser doesn\'t support this page.');};

if(document.getElementById && document.images){

(function(g, f, d, i){
i = g.length - 1;
for (i; i > -1; --i)
g[i] = g[i].split('.');
g.sort(f);
g.dir = d[d.length -2].src.replace(/getimages.php$/, '');
})(galleryarray, function(a, b){return b[0] - a[0];}, document.getElementsByTagName('script'));

galshow = function(f, g){
g.im.title = 'Paused';
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = []; g.s = false; g.im.title = 'Paused';
var b = [g.v(f.by), g.v(f.bm), g.v(f.bd), g.v(f.bh)].join('') - 0,
e = [g.v(f.ey), g.v(f.em), g.v(f.ed), g.v(f.eh)].join('') - 0,
i = galleryarray.length - 1;
for (i; i > -1; --i)
if(galleryarray[i][0] >= b && galleryarray[i][0] <= e)
g.gal.push(galleryarray[i].join('.'));
g.rotateimages();
};

galshow.v = function(el){return el.value;};

galshow.pause = function(){
if(galshow.p || galshow.s){
galshow.timer = setTimeout(galshow.pause, 300);
return;
}
galshow.rotateimages();
};

galshow.rotateimages = function(g){
g = galshow;
g.im.src = galleryarray.dir + g.gal[g.curimg];
};

galshow.onload = function(){
var g = galshow, num = document.getElementById('num').firstChild,
r = new RegExp('(....)(..)(..)(..)');
g.im = document.getElementById('slideshow');
g.im.onload = function(){
if(!g.gal) return;
num.nodeValue = g.gal[g.curimg++].split('.')[0].replace(r, 'Year: $1 Month: $2 Date: $3 Hour: $4');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.pause, g.delay || 1000);
};
g.im.onmouseover = function(){g.p = true;};
g.im.onmouseout = function(){g.p = false;};
document.getElementsByName('speed')[0].checked = true;
};

if (window.addEventListener)
window.addEventListener('load', galshow.onload, false);
else if (window.attachEvent)
window.attachEvent('onload', galshow.onload);

}

</script>
</head>
<body>
<div style="width: 680px;height: 500px;">
<span id="num">Year: 2000 Month: 01 Date: 01 Hour: 00</span><br>
<img id="slideshow" src="http://www.wthrman.com/maps/surface/200001/2000010100.png" alt="Weather Map" title=""><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2000">2000</option>
</select>
End Year: <select name="ey">
<option value="2000">2000</option>
</select>
Begin Month: <select name="bm">
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>
End Hour: <select name="eh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>

<input type="submit" value="Go!">
<input type="button" value="Stop" onclick="galshow.s = true;galshow.im.title = 'Stopped';">
<input type="button" value="Resume" onclick="galshow.s = false;galshow.im.title = 'Paused';">
</div>
<div>Delay:
<input type="radio" name="speed" onclick="galshow.delay = 1000;" checked> 1 sec (default)
<input type="radio" name="speed" onclick="galshow.delay = 2000;"> 2 sec
<input type="radio" name="speed" onclick="galshow.delay = 3000;"> 3 sec
<input type="radio" name="speed" onclick="galshow.delay = 4000;"> 4 sec
</div>
</form>
</body>
</html>

Keithb
12-12-2008, 07:47 PM
Thanks again John, it's working great!

Keithb
12-12-2008, 11:00 PM
Hi John again,

Very sorry about this, but after all of the foregoing I now find that the image hosting service I wanted to use, won't allow the hosting of PHP or JS files. :eek:It will allow everything else. I had no idea this would be the case.:(
The one we have been working with is a link to my website however because I only have 1Gb of space I had intended to load all the images to the other one (MyBloop.com) which has unlimited storage. The PHP only runs in the directory the files are in. I did try putting the other directory path in the php but as I expected, that didn't work..but I thought it'd be worth a try.

I used to have heaps more space but I changed providers recently due to problems with the previous one and also I wanted a local host (previously it was in Canada).

Is there an easy way for the PHP to read the image files on the other host (the online link is http://www.wthrman.com/maps/surface/200001/getimages.php) , without putting you to a whole lot more effort?

Thanks

jscheuer1
12-13-2008, 04:14 AM
You want the PHP file on wthrman.com to read a directory on MyBloop.com?

That might be able to be done, provided both hosts will allow it. But my PHP is limited, best to ask in the PHP forum about that.

If it works, a change would be required to my latest version, as I made the javascript take the path from the directory where getimages.php file resides, and that would no longer be valid.

However, another approach might work as well/instead. If the list of image file names in some directory on another host may be intuited from the current date, javascript may be able to be used to construct the array. But if some images guessed at in this manner could be missing (I'm thinking the most recent possible images, but this could include other oversights in setting this up) care would need to be taken to deal with missing images, and/or occasional glitches in performance would simply have to be accepted.

Keithb
12-13-2008, 05:17 AM
I think we will have to give up getting PHP to run on wthrman to get images from MyBloop. It runs perfectly on wthrman with the images there. I just checked MyBloop and it won't even allow HTML files to be uploaded. Of course I realise that MyBloop is not a 'host' in the broader web hosting sense but I really didn't know there would be these restrictions..put that down to my ignorance! Apparently it's because of security concerns. One learns something all the time, so now I know.

So I think I will run with what we have at present; your script works really well, nothing has been in vain and I am very very appreciative of your help. It wouldn't be an issue but for the fact that I have a huge number of images which consume 10Gb of disk space so I will have to compromise one way or another...fewer images or go for a higher storage capacity.

Thanks again & cheers...Keith

jscheuer1
12-13-2008, 05:52 AM
There are a number of possibilities. If I knew more about just how the directory on MyBloop was populated, I could be of more help. Also, perhaps another host would serve your needs better.

But pretty much from the beginning with this project I've been thinking that there has to be a better/faster way to get the directory/list of images. Since you basically know the parameters that determine the filenames available, perhaps we don't even need a master listing (galleryarray in our current code). And since all you are after is a list of filenames determined by how they fall within a given date/time range, we could just generate that list visa vis the path to the files. You would just have to state that if maps aren't available for the date/time range selected, that some or all of the images will not be displayed. If possible, you could even validate the date/time range against what is available, or give an advisory as to the parameters that must be respected when selecting a range.

The changes to the code would probably not be too extensive.

Keithb
12-13-2008, 06:13 AM
The directory on MyBloop works a bit like Windows Explorer and one can create an identical directory structure. The files are uploaded from the desktop/folder etc on the PC using MyBloop's uploader which has to be downloaded and installed first.

It should be possible to create an HTML file on wthrman which would read the directory/files on MyBloop, having first called up the opening and end dates as we are doing at present. The stored images on these image hosting sites actually have URLs and links that can be embedded in web pages or sent via email..this is why I'm sure it would work from wthrman. As far as I can see, the directory name on MyBloop remains unchanged with different files but it would be necessary to make the javascript file refer to the image URL (a direct link..it's called some other name I can't remember), which will be something like eg MyBloop/maps/2008010100.png..there are all sort of different URLs depending on whether they are for emails, viewing etc.

I hope this clarifies things.

jscheuer1
12-13-2008, 02:50 PM
OK, I've done a major overhaul of the code. It no longer needs any PHP. It will create an array of filenames based upon the range chosen in the form of:

YYYYMMDDHH.png

each incremented by 6 hours. These filenames and the range begin and end values are validated against the Date Object, so that even if a user selects - say Feb 31st, it will convert it to the actual date that would be in the given year. There could be problems with DST, I have added a fix for that, it will need real time testing though.

The directory and file extension must be hard coded into the script. I'm assuming .png for the file extension, and currently have it looking in the 200001 directory on wthrman. I'll highlight where this is done (it's near the end of the script):


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

</script>

<script type="text/javascript">
var galshow = function(){alert('Sorry, your browser doesn\'t support this page.');};

if(document.getElementById && document.images){

galshow = function(f, g){
g.im.title = 'Paused';
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = []; g.s = false;
var b = g.dinc([g.v(f.by), g.v(f.bm), g.v(f.bd), g.v(f.bh)].join(''), 1),
e = g.dinc([g.v(f.ey), g.v(f.em), g.v(f.ed), g.v(f.eh)].join(''), 1) - 0;
while (b <= e){
g.gal.push([b, g.ext].join(''));
b = g.dinc(b);
}
g.rotateimages();
};

galshow.pad = function(v){return v < 10? '0' + v : v;};

galshow.dstBust = function(v){return v - v%6 + (v%6 < 3? 0 : 6);};

galshow.dinc = function(n, i){
var g = galshow;
n = n.replace(g.r, '$1,$2,$3,$4').split(',');
n = new Date(n[0] - 0, n[1] - 1, n[2] - 0, n[3] - 0 + (i? 0 : 6));
n.setHours(g.dstBust(n.getHours()));
return [n.getFullYear(), g.pad(n.getMonth()+1), g.pad(n.getDate()), g.pad(n.getHours())].join('');
};

galshow.v = function(el){return el.value;};

galshow.pause = function(){
if(galshow.p || galshow.s){
galshow.timer = setTimeout(galshow.pause, 300);
return;
}
galshow.rotateimages();
};

galshow.rotateimages = function(g){
g = galshow;
g.im.src = g.dir + g.gal[g.curimg];
};

galshow.onload = function(){
var g = galshow, num = document.getElementById('num').firstChild;
g.r = new RegExp('(....)(..)(..)(..)');
g.im = document.getElementById('slideshow');
g.im.onload = function(){
if(!g.gal) return;
num.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.pause, g.delay || 1000);
};
g.im.onmouseover = function(){g.p = true;};
g.im.onmouseout = function(){g.p = false;};
document.getElementsByName('speed')[0].checked = true;
g.dir = 'http://www.wthrman.com/maps/surface/200001/';
g.ext = '.png';
};

if (window.addEventListener)
window.addEventListener('load', galshow.onload, false);
else if (window.attachEvent)
window.attachEvent('onload', galshow.onload);

}

</script>
</head>
<body>
<div style="width: 680px;height: 500px;">
<span id="num">Year: 2000 Month: 01 Date: 01 Hour: 00</span><br>
<img id="slideshow" src="http://www.wthrman.com/maps/surface/200001/2000010100.png" alt="Weather Map" title=""><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2000">2000</option>
</select>
End Year: <select name="ey">
<option value="2000">2000</option>
</select>
Begin Month: <select name="bm">
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>
End Hour: <select name="eh">
<option value="00">0</option>
<option value="06">6</option>
<option value="12">12</option>
<option value="18">18</option>
</select>

<input type="submit" value="Go!">
<input type="button" value="Stop" onclick="galshow.s = true;galshow.im.title = 'Stopped';">
<input type="button" value="Resume" onclick="galshow.s = false;galshow.im.title = 'Paused';">
</div>
<div>Delay:
<input type="radio" name="speed" onclick="galshow.delay = 1000;" checked> 1 sec (default)
<input type="radio" name="speed" onclick="galshow.delay = 2000;"> 2 sec
<input type="radio" name="speed" onclick="galshow.delay = 3000;"> 3 sec
<input type="radio" name="speed" onclick="galshow.delay = 4000;"> 4 sec
</div>
</form>
</body>
</html>

If the images are in the same directory as the default image that shows on page load, you may use:


g.dir = g.im.src.replace(/[^\/]+$/, '');

in the script instead of setting the explicit path.

Similarly, if the extension matches the default image's extension, you may use:


g.ext = g.im.src.replace(/^.*(\.[^\.]+)$/, '$1');

in the script instead of setting the explicit file extension.

Keithb
12-14-2008, 12:23 AM
Thanks John, the DST shouldn't be a problem as the times of the images are in Greenwich Mean Time.

jscheuer1
12-14-2008, 01:10 AM
Well, regardless, the correction will not be applied unless DST (aka: summertime) or double summertime (jumps two hours ahead) interferes with the local user's Date Object.

In other words, the correction isn't for the names of the files, I assumed they were all in UT or GMT, which doesn't have any Daylight or Summer Time (aka: by other names around the globe). It is for the calculation of the array which will be based upon the local time convention in effect on the user's machine. If a date range selected by the user crosses over into their local DST (or double DST) from their local ST or visa versa, the bustDST function's correction should avoid generating incorrect filenames. But, as I say, this would have to be borne out in a real life situation, though I'm fairly confident that it will work.

To test it, we would need files from the months when typically there is a boundary between ST and DST on the local machine, March and November, currently in the USA I think. But the location doesn't matter, whatever the changeover months are in a given location, and regardless if it advances in the Spring or Autumn (hemispheric differences), the correction should be seamless if it works as intended.

Keithb
12-17-2008, 06:10 AM
Hi John, I want to make a small change (for a series of 1-hourly images) so that it displays images for every hour (should mean 24 a day).

I tried changing a few numbers but the best I could do resulted in it skipping the 5th,11th,17th and 23rd hours.

[EDIT] Very minor point..in the radio buttons at the foot of the script the first value shows as checked and putting 'checked' after the 1 sec default didn't make any difference...so it would be nice if we could get the 1 sec button to default to a 'checked' status.

Could you please advise on these?

Thanks..Keith

jscheuer1
12-17-2008, 08:08 AM
The DST busting routine will prevent it from displaying certain times. And using maps more frequently will make it impossible to correct the Date Object in the manner I was using. The first radio button in the group will be checked as long as you followed the code I laid out for that portion of the script and markup. I'm no longer clear on what you are using exactly:

Please post a link to the page on your site that contains the problematic code so we can check it out.

Keithb
12-17-2008, 08:23 AM
Thanks John, the link is http://www.wthrman.com/satpics/satpics.htm . I've made a few cosmetic changes to the layout but none that affect the script's running except of course the things I mentioned before regarding hours.

You'll notice that this series has slightly different file names ie with a '30' added at the end before the '.png', however I can easily rename them if that addition is making things harder...it's the way our Bureau of Meteorology manages things. The image files are in the same directory as the htm file.

Hope I haven't made things worse, if so I apologise, but I've meant well and have been really trying to help myself before contacting you.

Cheers..Keith

jscheuer1
12-17-2008, 08:56 AM
That's not even the latest version I published, and I have a slightly improved version, but it was for the old arrangement of every 6 hours. What you have will do for now. To go every hour, just get rid of:

n.setHours(g.dstBust(n.getHours()));

I will need to come up with another way of dealing with those times when the sequence causes the Date Object to cross the ST/DST and the DST/ST boundaries though.

As to the other matter, this line (in addition to setting one of the radio buttons as checked in the markup) sets the default delay:


document.getElementsByName('speed')[0].checked = true;

That was proper when the default was also the first one. For what you have now, change it to:


document.getElementsByName('speed')[6].checked = true;

Now, I notice that some of the image files in that folder are 0 bytes, and that some are missing altogether. Either case could cause problems. Also, it appears that whole date ranges for which there are no images may be selected.

jscheuer1
12-17-2008, 09:35 AM
I changed the DST solution to simply convert into UT. That way it should always be accurate. Give this version a shot:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

</script>

<script type="text/javascript">
var galshow = function(){alert('Sorry, your browser doesn\'t support this page.');};
galshow.datetest = new Date();

if(galshow.datetest.getUTCFullYear && document.getElementById && document.images && Array.prototype.push){

galshow = function(f, g){
g.im.title = 'Paused';
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = []; g.s = false;
var b = g.dinc([g.v(f.by), g.v(f.bm), g.v(f.bd), g.v(f.bh)].join(''), 1),
e = g.dinc([g.v(f.ey), g.v(f.em), g.v(f.ed), g.v(f.eh)].join(''), 1) - 0;
while (b <= e){
g.gal.push([b, g.ext].join(''));
b = g.dinc(b);
}
g.rotateimages();
};

galshow.pad = function(v){return v < 10? '0' + v : v;};

galshow.dinc = function(n, i){
var g = galshow;
n = n.replace(g.r, '$1,$2,$3,$4').split(',');
nn = new Date();
nn.setUTCMinutes(30)
nn.setUTCFullYear(n[0] - 0);
nn.setUTCMonth(n[1] - 1);
nn.setUTCDate(n[2] - 0);
nn.setUTCHours(n[3] - 0 + (i? 0 : 1));
return [nn.getUTCFullYear(), g.pad(nn.getUTCMonth() + 1), g.pad(nn.getUTCDate()), g.pad(nn.getUTCHours()), '30'].join('');
};

galshow.v = function(el){return el.value;};

galshow.pause = function(){
if(galshow.p || galshow.s){
galshow.timer = setTimeout(galshow.pause, 300);
return;
}
galshow.rotateimages();
};

galshow.rotateimages = function(g){
g = galshow;
g.im.src = g.dir + g.gal[g.curimg];
};

galshow.onload = galshow.onerror = function(){
var g = galshow, num = document.getElementById('num').firstChild;
g.r = new RegExp('(....)(..)(..)(..).*');
g.im = document.getElementById('slideshow');
g.im.onload = g.im.onerror = function(){
if(!g.gal) return;
num.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4:30');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.pause, g.delay || 1000);
};
g.im.onmouseover = function(){g.p = true;};
g.im.onmouseout = function(){g.p = false;};
document.getElementsByName('speed')[6].checked = true;
g.dir = g.im.src.replace(/[^\/]+$/, '');
g.ext = g.im.src.replace(/^.*(\.[^\.]+)$/, '$1').toLowerCase();
};

if (window.addEventListener)
window.addEventListener('load', galshow.onload, false);
else if (window.attachEvent)
window.attachEvent('onload', galshow.onload);

}

</script>
</head>
<body>
<div style="width: 680px;height: 560px;">
<span id="num">Year: 0000 Month: 00 Date: 00 Hour: 00:30</span><br>
<img id="slideshow" src="http://www.wthrman.com/satpics/blank.PNG" alt="Weather Map" title=""><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2008">2008</option>
</select>
End Year: <select name="ey">
<option value="2008">2008</option>
</select>
Begin Month: <select name="bm">
<option value="11">November</option>
<option value="12">December</option>
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="11">November</option>
<option value="12">December</option>
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">00:30</option>
<option value="01">01:30</option>
<option value="02">02:30</option>
<option value="03">03:30</option>
<option value="04">04:30</option>
<option value="05">05:30</option>
<option value="06">06:30</option>
<option value="07">07:30</option>
<option value="08">08:30</option>
<option value="09">09:30</option>
<option value="10">10:30</option>
<option value="11">11:30</option>
<option value="12">12:30</option>
<option value="13">13:30</option>
<option value="14">14:30</option>
<option value="15">15:30</option>
<option value="16">16:30</option>
<option value="17">17:30</option>
<option value="18">18:30</option>
<option value="19">19:30</option>
<option value="20">20:30</option>
<option value="21">21:30</option>
<option value="22">22:30</option>
<option value="23">23:30</option>
</select>
End Hour: <select name="eh">
<option value="00">00:30</option>
<option value="01">01:30</option>
<option value="02">02:30</option>
<option value="03">03:30</option>
<option value="04">04:30</option>
<option value="05">05:30</option>
<option value="06">06:30</option>
<option value="07">07:30</option>
<option value="08">08:30</option>
<option value="09">09:30</option>
<option value="10">10:30</option>
<option value="11">11:30</option>
<option value="12">12:30</option>
<option value="13">13:30</option>
<option value="14">14:30</option>
<option value="15">15:30</option>
<option value="16">16:30</option>
<option value="17">17:30</option>
<option value="18">18:30</option>
<option value="19">19:30</option>
<option value="20">20:30</option>
<option value="21">21:30</option>
<option value="22">22:30</option>
<option value="23">23:30</option>
</select>
<input style="margin-left:1ex;" type="submit" value="Go!">
<input type="button" value="Stop" onclick="galshow.s = true;galshow.im.title = 'Stopped';">
<input type="button" value="Resume" onclick="galshow.s = false;galshow.im.title = galshow.timer? 'Paused' : '';">
</div>
<div>Delay:
<input type="radio" name="speed" onclick="galshow.delay = 10;"> 10 msec
<input type="radio" name="speed" onclick="galshow.delay = 25;"> 25 msec
<input type="radio" name="speed" onclick="galshow.delay = 50;"> 50 msec
<input type="radio" name="speed" onclick="galshow.delay = 100;"> 100 msec
<input type="radio" name="speed" onclick="galshow.delay = 250;"> 250 msec
<input type="radio" name="speed" onclick="galshow.delay = 500;"> 500 msec
<input type="radio" name="speed" checked onclick="galshow.delay = 1000;"> 1 sec (default)
<input type="radio" name="speed" onclick="galshow.delay = 2000;"> 2 sec
<input type="radio" name="speed" onclick="galshow.delay = 3000;"> 3 sec
<input type="radio" name="speed" onclick="galshow.delay = 4000;"> 4 sec
</div>
</form>
</body>
</html>

Keithb
12-17-2008, 10:02 AM
Thanks John,

There are the odd ones that are missing due to satellite transmission problems that occurred at the time. The ones with 0 bytes must have arisen from upload problems I was having..the uploads simply stalled but I didn't know that's what had happened in the directory. So I will replace those.

Anyway I've run it over the first 7 days where there appears to be nothing missing and it seems to be working perfectly. I guess we are left with the problem of whether it's feasible to skip past missing items. One way that occurs to me would be for me to simply create a blank image with the missing date as its filename and put that in place of the one that would have been there had the 'eye in the sky' not been a problem.

jscheuer1
12-17-2008, 10:14 AM
Yeah, a blank would be good, but we could also use the browser's image.onerror, like so (very important in IE, which will otherwise hang on a single missing image):


galshow.onload = function(){
var g = galshow, num = document.getElementById('num').firstChild;
g.r = new RegExp('(....)(..)(..)(..).*');
g.im = document.getElementById('slideshow');
g.im.onload = g.im.onerror = function(){
if(!g.gal) return;
num.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4:30');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.pause, g.delay || 1000);
};
g.im.onmouseover = function(){g.p = true;};
g.im.onmouseout = function(){g.p = false;};
document.getElementsByName('speed')[6].checked = true;
g.dir = g.im.src.replace(/[^\/]+$/, '');
g.ext = g.im.src.replace(/^.*(\.[^\.]+)$/, '$1').toLowerCase();
};

That will allow it to skip over any that are missing. But if you supply blanks for those, the user interface will be better. Another thing to consider is preloading. Once the array is composed, it could be preloaded. This would prevent the delay (and some other unpleasant effects in some browsers) which occurs during the rotation when the images selected aren't already cached on the user's end. But with such large images, there will be significant delay to the start of the rotation. We could try an incremental preload of some sort, but while we are preloading, however we do it, there are bound to be some performance consequences. So it would be a matter of deciding the optimal way to get the images loaded.

You should consider optimizing the images and interlacing them. Those two steps might be better than any preloading scheme.

jscheuer1
12-17-2008, 10:26 AM
I had a typo, I forgot to close the end hour select. I'll correct it in my previous post of the full code and add the onerror thing to.

Keithb
12-17-2008, 11:08 AM
OK, looks to be working well, eg it handled the missing image for 9.30 on the 8th. The sequence in general appears to be a little jerky at times but I realise that's probably a combination of caching and browser issues.

Have to look further at the interlacing thingy; of all the image processing software I have here only IrfanView appears to have anything like it (it calls it saving as a 'progressive jpg' or something). When I tried that, it seemed to degrade the quality a little, compared to the .png format.

Maybe another solution to the aesthetics of the display for a missing image would be to just get rid of the red cross in the box? Trouble is that might still leave a surrounding frame and so wouldn't look much better.Otherwise, I can fall back on the blank idea but there are probably quite a few that will be needed...perhaps call up 'blank.png' whenever the real image isn't available?..so, to use Visual Basic parlance, 'if image.exists = false then image.src=blank.png'..pretty crude I know, but you get the idea.

jscheuer1
12-17-2008, 04:10 PM
We can minimize the exposure of missing images with:


galshow.onload = function(){
var g = galshow, num = document.getElementById('num').firstChild;
g.r = new RegExp('(....)(..)(..)(..).*');
g.im = document.getElementById('slideshow');
g.im.onload = g.im.onerror = function(e){
if(!g.gal) return;
e = e || window.event;
e = e.type;
num.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4:30');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.pause, e == 'error'? 30 : (g.delay || 1000));
};
g.im.onmouseover = function(){g.p = true;};
g.im.onmouseout = function(){g.p = false;};
document.getElementsByName('speed')[6].checked = true;
g.dir = g.im.src.replace(/[^\/]+$/, '');
g.ext = g.im.src.replace(/^.*(\.[^\.]+)$/, '$1').toLowerCase();
};

You may want to get a decent image optimization program. For instance, using xat.com's Optimizer Pro, I was able to turn 200812091830.png (which incidentally is actually a GIF image with the wrong file extension) at 105,891 bytes, into 200812091830.jpg - a progressive, grayscale, 70% quality image at 36,626 bytes with no apparent loss in visual quality. If I had applied a little resizing (shrinking the size of the image by - say 10px in each dimension, the savings would have been even more.

All of these settings could be applied to an entire directory of images in one pass.

Here's 200812091830.jpg:

2330

Click it to see full size.

Keithb
12-17-2008, 08:38 PM
Hi John, I've downloaded the xat software on a trial basis (30 days); there's certainly a lot to be said for reducing the file sizes. It cut the file sizes by about 2/3rds with very little loss of quality (on the default settings). I can't recall now why I changed the file extensions, anyway I renamed as jpg, optimised and uploaded some of the png images. When running these, the slideshow speed slowed after it ran into a missing date. After restarting a couple of times this problem seemed to go away, so I presume it's a caching issue? If so, would a preload routine help? And to change speed in the middle of the sequence, is it better to stop first and restart after changing?

Thanks again..Keith

jscheuer1
12-18-2008, 04:54 AM
About the optimizer - you should play around with the options quite a bit to see what each can do alone and in combination with an exemplar image from your set. That should allow you to determine the optimal settings, which then can be applied to the entire set using batch mode. In my version (it's a little old) of optimizer, you can enter into batch mode simply by dragging a folder or list of images to the program. Once in batch mode, various panels may be used to set options for the batch. Once you've configured those, the batch may be run, converting all of the images. I'm always careful to keep the originals, just in case. One of the optimizer's options is to save to a different directory, generally a good idea.

Interlacing a gif or png image (or with jpg, making it progressive), allows the image to load in evenly distributed bands or pixels, rather than from the top down, so should make preloading unnecessary. Sometimes doing this adds a few bytes to the total, sometimes it requires less bytes, but the advantages in this situation outweigh any added bytes. However, in my test, making the exemplar progressive actually required a few less bytes.

About missing images. If you've upgraded to the code in post 30 of this thread, they should be barely noticeable. I think that this shouldn't be made completely unnoticeable though, because otherwise the user may have no clue that data is missing. Rather, I would favor mention be made on the page of the possibility of missing images and that a brief flash will be observed in their place should they occur.

Preloading would help with the initial run through. However, since preloading takes at least as long as loading, and cannot be counted upon to efficiently run while the show is going on, it would introduce front end delay in at least some browsers, and depending upon the connect rate, could significantly reduce how well the show performs. Consider that, should any given image be requested by the show before its preloading is complete, it would have to start loading all over again, all the while the background preloading degrading the speed of the overall process. That's why I prefer progressive images to handle this aspect of it.

As for when it is best to change the delay rate of the show, I've seen no indication that it makes any difference whether the show is running or not.

Keithb
12-18-2008, 05:20 AM
OK thanks for that, I'll play with the optimiser as you suggest. I suspected that the delay you mention with preloading might be an issue..now I know why it offsets any other gains that might accrue otherwise. Thanks also for the explanation of what happens with the optimising. The version I'm trialling is 5.1...seems to have quite a lot of bells and whistles.

As to missing images, yes I upgraded with the new code and had already planned to put an explanation in of the 'flicker', especially as missing images are always going to be part of this, due to the technology that generates them. The flicker however is really quite momentary...not enough to worry about.

So I'll see how it all goes.

Many thanks & cheers for now..Keith

jscheuer1
12-18-2008, 05:35 AM
One other thing I thought to add. From what you wrote, it sounds like you think you need to rename the images before converting. However, optimizer will automatically change the file extension to the correct one during the conversion process.

Keithb
12-18-2008, 05:45 AM
Yes that's what I was thinking..I'll check it out..that would save a fair bit of processing.

jscheuer1
12-18-2008, 07:24 AM
I have yet another version. It uses preloading - incrementally, right as each image is called for the first time. This allows individual images to appear all at once (rather than loading visually on the page), though may slow things just slightly the first run through. It also gives a visual . . . Loading indicator while the image is being downloaded. Missed images are now skipped, but I think you should still have some language on the page explaining that if an image isn't available it will be skipped, and that the only obvious indication of this will be that its date/time will not be displayed.


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

</script>

<script type="text/javascript">
var galshow = function(){alert('Sorry, your browser doesn\'t support this page.');};
galshow.datetest = new Date();

if(galshow.datetest.getUTCFullYear && document.getElementById && document.images && Array.prototype.push && Array.prototype.splice){

galshow = function(f, g){
g.im.title = 'Paused';
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = []; g.s = false;
var b = g.dinc([g.v(f.by), g.v(f.bm), g.v(f.bd), g.v(f.bh)].join(''), 1),
e = g.dinc([g.v(f.ey), g.v(f.em), g.v(f.ed), g.v(f.eh)].join(''), 1) - 0;
while (b <= e){
g.gal.push([b, g.ext].join(''));
b = g.dinc(b);
}
g.rotateimages();
};

galshow.pad = function(v){return v < 10? '0' + v : v;};

galshow.dinc = function(n, i){
var g = galshow;
n = n.replace(g.r, '$1,$2,$3,$4').split(',');
nn = new Date();
nn.setUTCMinutes(30)
nn.setUTCFullYear(n[0] - 0);
nn.setUTCMonth(n[1] - 1);
nn.setUTCDate(n[2] - 0);
nn.setUTCHours(n[3] - 0 + (i? 0 : 1));
return [nn.getUTCFullYear(), g.pad(nn.getUTCMonth() + 1), g.pad(nn.getUTCDate()), g.pad(nn.getUTCHours()), '30'].join('');
};

galshow.v = function(el){return el.value;};

galshow.pause = function(){
if(galshow.p || galshow.s){
galshow.timer = setTimeout(galshow.pause, 300);
return;
}
galshow.rotateimages();
};

galshow.rotateimages = function(g){
g = galshow;
g.num.nodeValue += ' . . . Loading';
var i = new Image();
i.onload = function(){
g.im.src = i.src;
};
i.onerror = function(){
g.num.nodeValue = g.num.nodeValue.replace(/ . . . Loading/, '');
g.gal.splice(g.curimg, 1);
g.pause();
};
i.src = g.dir + g.gal[g.curimg];
};

galshow.onload = function(){
var g = galshow; g.num = document.getElementById('num').firstChild;
g.r = new RegExp('(....)(..)(..)(..).*');
g.im = document.getElementById('slideshow');
g.im.onload = function(){
g.num.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4:30');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
g.timer = setTimeout(g.pause, g.delay || 1000);
};
g.im.onmouseover = function(){g.p = true;};
g.im.onmouseout = function(){g.p = false;};
document.getElementsByName('speed')[6].checked = true;
g.dir = g.im.src.replace(/[^\/]+$/, '');
g.ext = g.im.src.replace(/^.*(\.[^\.]+)$/, '$1').toLowerCase();
};

if (window.addEventListener)
window.addEventListener('load', galshow.onload, false);
else if (window.attachEvent)
window.attachEvent('onload', galshow.onload);

}

</script>
</head>
<body>
<div style="width: 680px;height: 560px;">
<span id="num">Year: 0000 Month: 00 Date: 00 Hour: 00:30</span><br>
<img id="slideshow" src="http://www.wthrman.com/satpics/blank.PNG" alt="Weather Map" title="" width=640 height=521><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2008">2008</option>
</select>
End Year: <select name="ey">
<option value="2008">2008</option>
</select>
Begin Month: <select name="bm">
<option value="11">November</option>
<option value="12">December</option>
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="11">November</option>
<option value="12">December</option>
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">00:30</option>
<option value="01">01:30</option>
<option value="02">02:30</option>
<option value="03">03:30</option>
<option value="04">04:30</option>
<option value="05">05:30</option>
<option value="06">06:30</option>
<option value="07">07:30</option>
<option value="08">08:30</option>
<option value="09">09:30</option>
<option value="10">10:30</option>
<option value="11">11:30</option>
<option value="12">12:30</option>
<option value="13">13:30</option>
<option value="14">14:30</option>
<option value="15">15:30</option>
<option value="16">16:30</option>
<option value="17">17:30</option>
<option value="18">18:30</option>
<option value="19">19:30</option>
<option value="20">20:30</option>
<option value="21">21:30</option>
<option value="22">22:30</option>
<option value="23">23:30</option>
</select>
End Hour: <select name="eh">
<option value="00">00:30</option>
<option value="01">01:30</option>
<option value="02">02:30</option>
<option value="03">03:30</option>
<option value="04">04:30</option>
<option value="05">05:30</option>
<option value="06">06:30</option>
<option value="07">07:30</option>
<option value="08">08:30</option>
<option value="09">09:30</option>
<option value="10">10:30</option>
<option value="11">11:30</option>
<option value="12">12:30</option>
<option value="13">13:30</option>
<option value="14">14:30</option>
<option value="15">15:30</option>
<option value="16">16:30</option>
<option value="17">17:30</option>
<option value="18">18:30</option>
<option value="19">19:30</option>
<option value="20">20:30</option>
<option value="21">21:30</option>
<option value="22">22:30</option>
<option value="23">23:30</option>
</select>
<input style="margin-left:1ex;" type="submit" value="Go!">
<input type="button" value="Stop" onclick="galshow.s = true;galshow.im.title = 'Stopped';">
<input type="button" value="Resume" onclick="galshow.s = false;galshow.im.title = galshow.timer? 'Paused' : '';">
</div>
<div>Delay:
<input type="radio" name="speed" onclick="galshow.delay = 10;"> 10 msec
<input type="radio" name="speed" onclick="galshow.delay = 25;"> 25 msec
<input type="radio" name="speed" onclick="galshow.delay = 50;"> 50 msec
<input type="radio" name="speed" onclick="galshow.delay = 100;"> 100 msec
<input type="radio" name="speed" onclick="galshow.delay = 250;"> 250 msec
<input type="radio" name="speed" onclick="galshow.delay = 500;"> 500 msec
<input type="radio" name="speed" checked onclick="galshow.delay = 1000;"> 1 sec (default)
<input type="radio" name="speed" onclick="galshow.delay = 2000;"> 2 sec
<input type="radio" name="speed" onclick="galshow.delay = 3000;"> 3 sec
<input type="radio" name="speed" onclick="galshow.delay = 4000;"> 4 sec
</div>
</form>
</body>
</html>

Keithb
12-18-2008, 08:11 AM
Depending on the speed, on the first run it's quite jerky after the first few images, though this is understandable as the previous image hasn't fully loaded into the cache..so if it's set too fast that problem is greater. However once fully loaded, it runs like a dream.

My knowledge of these things is vastly inferior but I wonder how a full preload before starting the show, would go..with perhaps a short 'loading' message while the user waits. In the usual course of events people probably wouldn't view more than a few days' (or even hours') images at a time as they would be interested in particular weather events (severe thunderstorms, for example). So unless one selects a lengthy range of dates, a full preload of all the images selected shouldn't be too much of a worry..but of course I am ignorant of any other trade-offs that there might be.

If doing this would detract from the overall presentation etc then I guess I could fall back on the image resizing etc..probably do that anyway.

jscheuer1
12-18-2008, 08:25 AM
Optimizing images for web presentation is always a good idea. I think the issue of preloading would best be left to the user, but it would need to be explained on the page. One could have two radio buttons:


Incremental Preload (default) - Preloads each image before it is displayed. There may be some delay between each update until the images have cycled through one round.

Batch Preload - All images preloaded in advance of the images being shown. Will delay the start of the show, but displays all images in a smooth train. If a large number of images is selected, the delay could be quite significant.


In any case, optimizing the images will make either approach more efficient - having less delay where it is prone to delay.

jscheuer1
12-19-2008, 05:59 AM
Latest version. Both the script code and the HTML have changed:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<script type="text/javascript">
var galshow = function(){alert('Sorry, your browser doesn\'t support this page.');};
galshow.datetest = new Date();

if(galshow.datetest.getUTCFullYear && document.getElementById && document.images && Array.prototype.push && Array.prototype.splice){

galshow = function(f, g){
g.im.title = 'Paused';
if(g.timer)
clearInterval(g.timer);
f = f.elements; g.curimg = 0; g.gal = []; g.pgal = []; g.s = false;
var b = g.dinc([g.v(f.by), g.v(f.bm), g.v(f.bd), g.v(f.bh)].join(''), 1),
e = g.dinc([g.v(f.ey), g.v(f.em), g.v(f.ed), g.v(f.eh)].join(''), 1) - 0;
while (b <= e){
g.gal.push([b, g.ext].join(''));
g.pgal.push([[g.dir, b, g.ext].join('')]);
b = g.dinc(b);
}
g.pi = g.pgal.length - 1;
if(g.batch == 1)
for (g.pi; g.pi > -1; --g.pi)
g.loadim(g.pgal[g.pi]);
g.rotateimages();
};

galshow.loadim = function(p){
p.push(new Image());
p[1].src = p[0];
};

galshow.pad = function(v){return v < 10? '0' + v : v;};

galshow.dinc = function(n, i){
var g = galshow, nn = new Date();
n = n.replace(g.r, '$1,$2,$3,$4').split(',');
nn.setUTCMinutes(30)
nn.setUTCFullYear(n[0] - 0);
nn.setUTCMonth(n[1] - 1);
nn.setUTCDate(n[2] - 0);
nn.setUTCHours(n[3] - 0 + (i? 0 : 1));
return [nn.getUTCFullYear(), g.pad(nn.getUTCMonth() + 1), g.pad(nn.getUTCDate()), g.pad(nn.getUTCHours()), '30'].join('');
};

galshow.v = function(el){return el.value;};

galshow.pause = function(){
if(galshow.p || galshow.s){
galshow.timer = setTimeout(galshow.pause, 300);
return;
}
galshow.rotateimages();
};

galshow.rotateimages = function(g){
g = galshow;
g.num.nodeValue += ' . . . Loading';
var i = new Image();
i.onload = function(){
g.im.src = i.src;
};
i.onerror = function(){
g.num.nodeValue = g.num.nodeValue.replace(/ . . . Loading/, '');
g.gal.splice(g.curimg, 1);
g.pause();
};
if(typeof g.curimg == 'number' && g.gal[g.curimg])
i.src = [g.dir, g.gal[g.curimg]].join('');
};

galshow.onload = function(){
var g = galshow; g.num = document.getElementById('num').firstChild;
g.r = new RegExp('(....)(..)(..)(..).*');
g.im = document.getElementById('slideshow');
g.im.onload = function(){
g.num.nodeValue = g.gal[g.curimg++].split('.')[0].replace(g.r, 'Year: $1 Month: $2 Date: $3 Hour: $4:30');
g.curimg = g.curimg < g.gal.length? g.curimg : 0;
if(!g.batch && g.pi > g.curimg)
g.loadim(g.pgal[g.pi--]);
g.timer = setTimeout(g.pause, g.delay || 1000);
};
g.im.onmouseover = function(){g.p = true;};
g.im.onmouseout = function(){g.p = false;};
document.getElementsByName('speed')[6].checked = true;
document.getElementsByName('batch')[0].checked = true;
g.dir = g.im.src.replace(/[^\/]+$/, '');
g.ext = g.im.src.replace(/^.*(\.[^\.]+)$/, '$1').toLowerCase();
};

if (window.addEventListener)
window.addEventListener('load', galshow.onload, false);
else if (window.attachEvent)
window.attachEvent('onload', galshow.onload);

}

</script>
</head>
<body>
<div style="width: 680px;height: 545px;">
<span id="num">Year: 0000 Month: 00 Date: 00 Hour: 00:30</span><br>
<img id="slideshow" src="http://www.wthrman.com/satpics/blank.jpg" alt="Weather Map" title="" width=640 height=521><br>
</div>
<form action="#" onsubmit="galshow(this, galshow);return false;">
<div>
Begin Year: <select name="by">
<option value="2008">2008</option>
</select>
End Year: <select name="ey">
<option value="2008">2008</option>
</select>
Begin Month: <select name="bm">
<option value="11">November</option>
<option value="12">December</option>
<option value="01">January</option>
</select>
End Month: <select name="em">
<option value="11">November</option>
<option value="12">December</option>
<option value="01">January</option>
</select>
Begin Day: <select name="bd">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
End Day: <select name="ed">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
Begin Hour: <select name="bh">
<option value="00">00:30</option>
<option value="01">01:30</option>
<option value="02">02:30</option>
<option value="03">03:30</option>
<option value="04">04:30</option>
<option value="05">05:30</option>
<option value="06">06:30</option>
<option value="07">07:30</option>
<option value="08">08:30</option>
<option value="09">09:30</option>
<option value="10">10:30</option>
<option value="11">11:30</option>
<option value="12">12:30</option>
<option value="13">13:30</option>
<option value="14">14:30</option>
<option value="15">15:30</option>
<option value="16">16:30</option>
<option value="17">17:30</option>
<option value="18">18:30</option>
<option value="19">19:30</option>
<option value="20">20:30</option>
<option value="21">21:30</option>
<option value="22">22:30</option>
<option value="23">23:30</option>
</select>
End Hour: <select name="eh">
<option value="00">00:30</option>
<option value="01">01:30</option>
<option value="02">02:30</option>
<option value="03">03:30</option>
<option value="04">04:30</option>
<option value="05">05:30</option>
<option value="06">06:30</option>
<option value="07">07:30</option>
<option value="08">08:30</option>
<option value="09">09:30</option>
<option value="10">10:30</option>
<option value="11">11:30</option>
<option value="12">12:30</option>
<option value="13">13:30</option>
<option value="14">14:30</option>
<option value="15">15:30</option>
<option value="16">16:30</option>
<option value="17">17:30</option>
<option value="18">18:30</option>
<option value="19">19:30</option>
<option value="20">20:30</option>
<option value="21">21:30</option>
<option value="22">22:30</option>
<option value="23">23:30</option>
</select>
<input style="margin-left:1ex;" type="submit" value="Go!">
<input type="button" value="Stop" onclick="galshow.s = true;galshow.im.title = 'Stopped';">
<input type="button" value="Resume" onclick="galshow.s = false;galshow.im.title = galshow.timer? 'Paused' : '';">
</div>
<div>Delay: (amount of time + any needed for loading between images - may be changed at any time)<br>
<input type="radio" name="speed" onclick="galshow.delay = 10;"> 10 msec
<input type="radio" name="speed" onclick="galshow.delay = 25;"> 25 msec
<input type="radio" name="speed" onclick="galshow.delay = 50;"> 50 msec
<input type="radio" name="speed" onclick="galshow.delay = 100;"> 100 msec
<input type="radio" name="speed" onclick="galshow.delay = 250;"> 250 msec
<input type="radio" name="speed" onclick="galshow.delay = 500;"> 500 msec
<input type="radio" name="speed" checked onclick="galshow.delay = 1000;"> 1 sec (default)
<input type="radio" name="speed" onclick="galshow.delay = 2000;"> 2 sec
<input type="radio" name="speed" onclick="galshow.delay = 3000;"> 3 sec
<input type="radio" name="speed" onclick="galshow.delay = 4000;"> 4 sec
</div>
<div>Preload: (ONLY VALID EACH TIME JUST BEFORE 'Go!' BUTTON IS ACTIVATED -<br>&nbsp;changing during a run or when stopping and resuming may yield odd results)<br>
<input type="radio" name="batch" checked onclick="galshow.batch = 0;"> Front/Back Incremental (default) - may delay transitions until cache catches up, caches from both ends of the array, two images per transition<br>
<input type="radio" name="batch" onclick="galshow.batch = 1;"> Batch - will result in lengthy initial delay for large date ranges, caches all images before any are shown, smoothest once display starts<br>
<input type="radio" name="batch" onclick="galshow.batch = 2;"> Front Incremental - best for slow connections, will delay transitions, but less than Front/Back, images must cycle through one complete run before they will be cached
</div>
</form>
</body>
</html>

Keithb
12-20-2008, 02:47 AM
Thanks John, although I need to do some further testing this looks excellent, as always!

Could I suggest adding forward and reverse buttons as enhancements?

Also, what part of the code refers to the year and month..I did try g.getFullYear etc but that choice was incorrect. The reason for asking is that I may have to create seperate directories on the website for each year/month eg 200812, as I think there's a problem (with the host, not the code), having all the files in one single directory (as there are so many of them)...meaning that I need to tell the program what directory to load each month's files into.

jscheuer1
12-21-2008, 05:28 PM
I had thought about backward and forward buttons. But that will take some time when I get it to focus on that. I'll get there. Right now I'm thinking perhaps, if the show is running, they could change the direction of flow of the images, if the show is stopped, they could step in the forward or backward direction, that would be cool.

The part of the code that determines the path used for the images is:


g.dir = g.im.src.replace(/[^\/]+$/, '');

Which basically strips the filename from the blank image and uses its path.

You could set it to an actual path (notice the trailing /), ex:


g.dir = 'http://www.whatever.com/some_folder/';

To change it on the fly, depending upon the month and year, would be pretty easy, but once again I'd have to write that out, and I would want to first know the exact naming conventions for these various folders. The mechanism (if done from outside of one of the functions where g = galshow, it could be done with g if done inside one of those) would be:


galshow.dir = whatever;

where whatever would be the new quoted path or a concatenation of values that forms the new path with the trailing slash (/) character.

Keithb
12-21-2008, 09:22 PM
Yes..at present one really can't go backward or forward one at a time even by stopping the show then clicking on the earlier/later day..of course they can pause on any day but it would be good to have the buttons such that they cycle back or forth one at a time when pressed.

The folder naming will follow the format of YYYYMM eg 200812...so we have to join up the year and the month, ensuring single-digit months have a '0' in them. Having folders isn't absolutely essential but I think it makes for easier online file searching and better organisation...might even help the program as it wouldn't have to search through the whole lot, only the images between the two dates. Where the first and last dates are in different months (folders) we would need to ensure that we can change folders as needed.

jscheuer1
12-22-2008, 07:08 AM
OK, I think we've got it. The code is now just a little too long to post, so I'm attaching an archive:

2356

jscheuer1
12-22-2008, 10:17 AM
I made a refinement on preloading. The three choices are now:


Background Incremental (default) - may delay transitions until cache catches up, caches one image ahead of current image displayed
Batch - will result in lengthy initial delay for large date ranges, caches all images before any are shown, smoothest once display starts
No Preload - on slow connections this will delay transitions less, images must cycle through one complete run before they will be cached

The incremental actually will cache behind if the images are showing in reverse direction. But that seemed like a lot to explain on the page, and most folks will just be happy to see things working fairly smoothly, they don't need to know all the details.

Oh, and I've finally included a script credit, you should display it in your source code, as shown in the new demo:

2357

The archive and page name are the same as the last one, so be careful not to mix them up.

Keithb
12-22-2008, 08:02 PM
John, this is fantastic!

One thing I have been trying is to get the code to retrieve an image identically named in another directory. I had thought of using something like


<input type="button" value="Upper maps" onClick="window.open('http://www.wthrman.com/uppermaps/YYYYMMDDHH.jpg')">

where the directory is shown followed by the image name which is the same as the current image but relates to observations in the upper air (hence the 'uppermaps' directory). The 'philosophy' behind this is to allow the viewer to see a plot of the upper air chart for the same date and time as the surface one (no slideshow needed).

There's no doubt a better way but I am mainly stuck on getting the onClick code to refer to the current image...eg if the current image is 2008122200.jpg, how to get the same image name in the upper directory to show when the button is clicked, then when clicked again, to revert back to the surface image.

jscheuer1
12-23-2008, 06:02 AM
Well, when a given image is showing, the galshow.curimg value has already advanced to prepare for the next image. But the src attribute of the galshow.im is the visible image. Also, from what you say, you would want to pause the show at the same time, and since this is a toggle, resume afterwards. But since the show may already be stopped, we will need a new pause property just for this, and since the blank image may be showing, we need to make sure that's not the case.

Also, though you give:



http://www.wthrman.com/uppermaps/YYYYMMDDHH.jpg

as the path, I just looked and it appears to be more like:


http://www.wthrman.com/uppermaps/YYYYMM/YYYYMMDDHH.jpg

That all being the case we can add to the script a function:


galshow.uppermaps = function(){
var g = galshow;
if(/blank/.test(g.im.src))
return;
g.u = !g.u;
if(g.u)
g.im.src = g.im.src.replace(/satpics/, 'uppermaps');
else
g.im.src = g.im.src.replace(/uppermaps/, 'satpics');
};

And add the g.u to the pause worthy properties (addition highlighted):


galshow.pause = function(){
if(galshow.p || galshow.s || galshow.u){
galshow.timer = setTimeout(galshow.pause, 300);
return;
}
galshow.rotateimages();
};

The button would look like so:


<input type="button" value="Upper Maps" onclick="galshow.uppermaps();">

Keithb
12-23-2008, 06:23 AM
OK, thanks John, sorry about the surprise directory change, I've been busy reorganising the files since I last posted. And yes it was indeed the plan to pause the image before the 'switch'. So now I'll insert the various changes and post further when I've tried it all out...I did get surprisingly close to some of your code in my experimenting but as usual I came off the rails. Not to worry, excellent learning experience all along but I've got a long way to go...would have to spend 6 hours a day for 12 months in my great big thick Javascript book!

Thanks again for your perseverance and enthusiasm in all this coding.

Keithb
12-23-2008, 07:12 AM
I think my earlier post was confusing. The new directory structures for the surface charts will be ../maps with each month's images in a subdirectory of that styled /YYYYMM, and for the upper charts ../uppermaps then /YYYYMM.
It was confusing because the toggle will operate between ../maps and ../uppermaps..there won't be anything happening with the satpics especially as they are at all sorts of different time intervals.

Keithb
12-25-2008, 07:13 AM
Getting one of those 'error in script' messages from Windows telling me 'object doesn't support this property or method', when clicking the new button..but I suspect it's to do with directory or filenames.

jscheuer1
12-25-2008, 02:03 PM
Now I'm confused. ../ from where? And as for the script error, it is possible I made a typo in my latest suggested update, or that you put it somewhere that caused the problem. Of course, it could be something else. In any case, to help me to see the current directory structure, and to diagnose the script error, please post a link to the current live page.

Keithb
12-25-2008, 07:46 PM
Sorry, I was trying to use a crude shorthand to point to the directory names in



galshow.uppermaps = function(){
var g = galshow;
if(/blank/.test(g.im.src))
return;
g.u = !g.u;
if(g.u)
g.im.src = g.im.src.replace(/maps/,'uppermaps');
else
g.im.src = g.im.src.replace(/uppermaps/,'maps');
};


The file link is
http://www.wthrman.com/Surface.htm (the maps version).

jscheuer1
12-26-2008, 04:17 PM
OK, you did put the new function in the wrong place, but that's probably just as well. Once I put it in the right place, though it 'worked' and there was no error, I realized that I hadn't thought through all of the ramifications of loading an image out of sequence. I think there may be a better way than what I currently have, but at least it works. I changed Upper Maps to Upper Map, as it really is a singular map you get with that button. And because all of the other form input functions will do unexpected/undesirable things if activated while the upper map is displayed, I've disabled them during it. I also validated the page - mostly because I have trouble working with invalid markup, and it can sometimes mess up scripts. It wasn't displaying properly in FF anyway.

2373

Keithb
12-26-2008, 10:32 PM
Yes I wondered about the placement of the function.

Just by way of suggestion (and it's purely cosmetic I guess), would it cause things to go awry if we had the 'Upper map' button text change from 'Upper map' to 'Return to surface map' (or something like that), when the upper map is being viewed, then back to 'Upper map' when the surface map is redisplayed?

If not workable, no worries, it's all working perfectly well.

Thanks again

jscheuer1
12-27-2008, 01:40 AM
Just for your information, anything defined as galshow.whatever that also will be used once these tests:


if(galshow.datetest.getUTCFullYear && document.getElementById && document.images && Array.prototype.push && Array.prototype.splice){


are passed, must come after the redefinition of the galshow function here:


galshow = function(f, g){
g.im.title = 'Paused';
if(g.timer)
clearInterval(g.timer);
g.sdir = t . . .

Otherwise it will be overwritten as an object of the first galshow function which is there to provide info for folks with legacy browsers that cannot run the other code, setup a Date Object for one of those tests, and to place galshow in the global scope, so that if the tests are passed, it can be accessed from the events in the form.

As to your question. I've worked out something like that as well as made some other minor improvements, most notably for proper reload behavior in some browsers, but also to give more info on the Upper Map button in the form of a toggling title attribute which will appear as a tool tip when that button is hovered.

The latest code:

2375

Keithb
12-27-2008, 03:29 AM
Thanks John for the information and updates. I think we have 'mission accomplished'.