PICTURE JavaScript is designed as a recursive HTML page that displays a picture to be viewed, and provides means (thumbnails, buttons, and keys) for proximity navigation through the picture album.
Click this link to have a look at simple example of picture album. Click [Help] button in thumbnail window, and press [H] key in full-size picture display window (generated by PICTURE JavaScript) to get navigation help. Here is picture album proximity navigation help:
A single copy of PICTURE.HTM can work with all picture albums; it makes sense to keep it either at the root of directory structure, or in a separate directory (I keep it at the root of my web site).
Initial references to PICTURE JavaScript get imbedded by THUMBLST JavaScript into thumbnail list table. Successive references to PICTURE.HTM get generated recursively by PICTURE itself (imbedded into full size picture view table).
The latest modifications of PICTURE JavaScript (12/2007) provided for picture centering (both horizontally and vertically) to make it look better on the newer bigger, and especially wider screens.
<!-- Picture Display with Proximity Navigation 08/24/2001–12/23/2007 --> <!-- ---------------------------------------------------------- 10/03/2007 --> <!-- www.davar.net/PICTURE.HTM --> <!-- Copyright (C) 2001–2007 by Vladimir Veytsel --> <!-- Spaces in picture description are substituted for %20 to please the --> <!-- Apache server that doesn't tolerate spaces in the URL. URL is used --> <!-- here to pass parameters to PICTURE.HTM from THUMBLST.JS (initially) --> <!-- and from itself (recursively for proximity navigation). --> <!-- Vertical split bar "|" is used as parameter delimiter for referencing --> <!-- PICTURE.HTM that displays the full-size picture. To avoid possible --> <!-- problems "|" is substituted for "!" in every picture description. --> <!-- To check URL parameter structure do [View]-[Show]-[Location Toolbar] --> <HTML> <HEAD> <LINK REL="shortcut icon" HREF="favicon.ico" TYPE="image/vnd.microsoft.icon"> <META HTTP-EQUIV="Content-Type" CONTENT="Text/HTML; CharSet=ISO-8859-1"> <META NAME = Description CONTENT ="Page: Picture Display Window. Site: Davar Web Site, Computer Science, Programming, Mainframe, UNIX, PC, Internet, Mathematics, Go, Zen, Quotations, Extracts, Humor, Russian."> <META NAME = Keywords CONTENT ="Davar Web Site, Picture display, Picture album, Picture gallery"> <META NAME = Author CONTENT="Vladimir Veytsel"> <SCRIPT LANGUAGE=JavaScript> <!-- Parm=location.search.substr(1) // Get URL parameters Parameter=Parm.split("|") // Parse parameters into an array Pict_Ind=Number(Parameter[0]) // Picture index within picture list Dn_Dir = Parameter[1] // Down direct (relative to PICTURE.HTM) // that contains *.JS file, thumbnail dir // and picture dir (empty - current dir; // when specified should end with "/") Pict_Lst= Parameter[2] // *.JS file with picture list (in Dn_Dir) Thum_Dir= Parameter[3] // Direct with thumbnail JPGs (in Dn_Dir) Pict_Dir= Parameter[4] // Direct with picture JPGs (in Dn_Dir) Title = Parameter[5].replace(/%20/g," ") // Restore spaces document.write("<TITLE>#"+Pict_Ind+" - "+Title.replace(/\/'/g,"'").replace(/ /g," ")+"</TITLE>") // Preload images to the page - this turns out to be essential // for setting Status value along with highlighting buttons // with onMouseOver/onMouseOut event handlers that swap images. // (Names are insignificant - choose any descriptive enough) But_Fst_Act = new Image(13,13); But_Fst_Act.src="BUT-FSTA.GIF" But_Fst_Sel = new Image(13,13); But_Fst_Sel.src="BUT-FSTS.GIF" But_2Bk_Act = new Image(13,13); But_2Bk_Act.src="BUT-2BKA.GIF" But_2Bk_Sel = new Image(13,13); But_2Bk_Sel.src="BUT-2BKS.GIF" But_1Bk_Act = new Image(13,13); But_1Bk_Act.src="BUT-1BKA.GIF" But_1Bk_Sel = new Image(13,13); But_1Bk_Sel.src="BUT-1BKS.GIF" But_Stp_Act = new Image(13,13); But_Stp_Act.src="BUT-STPA.GIF" But_Stp_Sel = new Image(13,13); But_Stp_Sel.src="BUT-STPS.GIF" But_1Ah_Act = new Image(13,13); But_1Ah_Act.src="BUT-1AHA.GIF" But_1Ah_Sel = new Image(13,13); But_1Ah_Sel.src="BUT-1AHS.GIF" But_2Ah_Act = new Image(13,13); But_2Ah_Act.src="BUT-2AHA.GIF" But_2Ah_Sel = new Image(13,13); But_2Ah_Sel.src="BUT-2AHS.GIF" But_Lst_Act = new Image(13,13); But_Lst_Act.src="BUT-LSTA.GIF" But_Lst_Sel = new Image(13,13); But_Lst_Sel.src="BUT-LSTS.GIF" function Proc_Key(ev) {if (ev) // Netscape Key=ev.which else Key=window.event.keyCode if (Key!=0) // Keys with zero ASCII value are ignored this is // (essential to keep standard window functionality) if (Key==13) // [Enter] key was pressed javascript:window.location.href=One_Ahead_HREF else switch (String.fromCharCode(Key)) {case "F": // Move to the First picture in the picture list case "f": case "{": case "[": javascript:window.location.href=First_HREF break; case "B": // Move two pictures Back case "b": case "<": case ",": javascript:window.location.href=Two_Back_HREF break; case "P": // Move to the Previous picture case "p": case "_": case "-": javascript:window.location.href=One_Back_HREF break; case "R": // Return to the picture list (thumbnails) case "r": case ":": case ";": javascript:void(window.close()); break; case "N": // Move to the Next picture case "n": case "+": case "=": javascript:window.location.href=One_Ahead_HREF break; case "A": // Move two pictures Ahead case "a": case ">": case ".": javascript:window.location.href=Two_Ahead_HREF break; case "L": // Move to the Last picture in the picture list case "l": case "}": case "]": javascript:window.location.href=Last_HREF break; default: alert(// Comment out next two lines after debugging // "*** Key pressed - ASCII: "+Key // +" Character: \""+String.fromCharCode(Key)+"\" ***\n\n"+ "Click the big picture to return to picture list, or click one of the thumbnails " +"\n(or buttons) for circular proximity navigation. As you move mouse cursor," +"\nwatch the Status Bar at the bottom of the window - text in it depends on" +"\nthe cursor position, and either describes selected object, or prompts for" +"\na possible action." +"\n\nTo avoid confusion don't use Windows Task Bar to switch between" +"\nthumbnail list and full-size picture windows." +"\n\nYou may press the following keys for proximity navigation in this window" +"\n(values shown below label keys to be pressed; entry is case-insensitive):" +"\n\n'F' or '['\t- Move to the First picture in the picture list" +"\n'B' or '<'\t- Move two pictures Back" +"\n'P' or '-'\t- Move to the Previous picture" +"\n'R' or ':'\t- Return to the picture list (thumbnails)" +"\n'N' or '+'\t- Move to the Next picture (or press [Enter] key)" +"\n'A' or '>'\t- Move two pictures Ahead" +"\n'L' or ']'\t- Move to the Last picture in the picture list" +"\n\n'H' or '?'\t- Display navigation help (this window)" +"\n\nBlinking of thumbnail number indicates that this picture is beyond upper" +"\nor lower list border (circular navigation is invoked)." +"\n\nTo save the picture point to it with the mouse cursor, click right mouse" +"\nbutton, and then proceed with 'Save Image As' from the pop-up menu." +"\n\nPress any other symbolic key (character, digit or symbol) to display help." ); } } // Needed only for Microsoft IE and Netscape 4.x; // Causes event duplication in Netscape 7.x and Mozilla. if (( navigator.appName=="Microsoft Internet Explorer")|| ((navigator.appName=="Netscape")&& (Number(navigator.appVersion.substr(0,1))<5))) document.onkeypress=Proc_Key // Needed for Netscape 4.8; maybe for some other older browsers too... if ((navigator.appName=="Netscape")&& (Number(navigator.appVersion.substr(0,1))<5)&& (document.captureEvents)) document.captureEvents(Event.KEYPRESS) // For new browsers - checked with Firefox 2.0, Netscape 7.2, IE 6.0 if (document.addEventListener) document.addEventListener("keypress",Proc_Key,true) //--> </SCRIPT> <STYLE TYPE="Text/CSS"> A:HOVER {COLOR:Red; BACKGROUND:#FFFF66} </STYLE> </HEAD> <NOSCRIPT> <BODY BACKGROUND="PAPER001.JPG" BGCOLOR=White TEXT=Black LINK=Blue ALINK=Fuchsia VLINK=Purple> </NOSCRIPT> <SCRIPT LANGUAGE=JavaScript> <!-- if (sessionStorage.getItem("BG")=="On") {N=Math.floor(Math.random()*9)%9+1 document.write("<BODY BACKGROUND='PAPER00",N,".JPG' BGCOLOR=White TEXT=Black LINK=Black ALINK=Black VLINK=Black>") document.write("<SCRIPT LANGUAGE=JavaScript SRC='",Dn_Dir,Pict_Lst,".JS'></SCRIPT>") //--> </SCRIPT> <FONT FACE="Times New Roman" SIZE=3> <NOSCRIPT> <TABLE ALIGN=CENTER CELLPADDING=10 BORDER=2> <TR> <TD ALIGN=Center> Sorry,<BR> Essential functionality of this page<BR> depends on availability of JavaScript.<BR> Your JavaScript is either disabled,<BR> or not supported by your browser.</TD> </TR> <TR> <TD ALIGN=Center> Please <A HREF="../../ABOUT.HTM#JavaScript"><FONT COLOR=Red><BLINK><B>enable</B></BLINK></FONT></A> JavaScript<BR> and [<FONT COLOR=Red>Reload</FONT>] this page,<BR> or use [<FONT COLOR=Red>Back</FONT>] to <FONT COLOR=Red>exit</FONT>.</TD> </TR> </TABLE> </NOSCRIPT> <SCRIPT LANGUAGE=JavaScript> <!-- Ind = new Array(4) // Index meaning: Numb = new Array(4) // 0 - Two back Pict = new Array(4) // 1 - One back Descr = new Array(4) // 2 - One ahead Target = new Array(4) // 3 - Two ahead Button = new Array(7) // Full button image description (IMG tag) Pas_But = new Array(7) // "xxxx" part of BUT-xxxx.GIF file name Pas_But[0]="FSTP" // Passive buttons' "xxxx" values Pas_But[1]="2BKP" // of the "BUT-xxxx.GIG" file name Pas_But[2]="1BKP" Pas_But[3]="STPA" Pas_But[4]="1AHP" Pas_But[5]="2AHP" Pas_But[6]="LSTP" for (i=0;i<7;i++) // Initialize button bar with passive button values Button[i]="<IMG SRC='BUT-"+Pas_But[i]+".GIF' TITLE='Passive button'>" Curr_Pict =Picture[Pict_Ind].substr(0,8)+" " Curr_Pict =Curr_Pict.substr(0,Curr_Pict.indexOf(" ")) Pict_Descr=Picture[Pict_Ind].substr(9).replace(/\\\'/g,"'").replace(/\|/g,"!") Pict_Total=Picture.length-1 Ind[0]=Pict_Ind-2 Numb[0]=Ind[0] if (Ind[0]<1) {Ind[0]=Pict_Total+Ind[0] Numb[0]="<BLINK>"+Ind[0]+"</BLINK>" } Target[0]="previous to the previous picture" Ind[1]=Pict_Ind-1 Numb[1]=Ind[1] if (Ind[1]<1) {Ind[1]=Pict_Total Numb[1]="<BLINK>"+Ind[1]+"</BLINK>" } Target[1]="previous picture from the picture list" Ind[2]=Pict_Ind+1 Numb[2]=Ind[2] if (Ind[2]>Pict_Total) {Ind[2]=Ind[2]%Pict_Total Numb[2]="<BLINK>"+Ind[2]+"</BLINK>" } Target[2]="next picture from the picture list" Ind[3]=Pict_Ind+2 Numb[3]=Ind[3] if (Ind[3]>Pict_Total) {Ind[3]=Ind[3]%Pict_Total Numb[3]="<BLINK>"+Ind[3]+"</BLINK>" } Target[3]="next to the next picture" Descr_First=Picture[1].substr(9).replace(/\\\'/g,"'").replace(/\|/g,"!") Descr_Last =Picture[Pict_Total].substr(9).replace(/\\\'/g,"'").replace(/\|/g,"!") for (i=0;i<4;i++) {Descr[i]=Picture[Ind[i]].substr(9).replace(/\\\'/g,"'").replace(/\|/g,"!") Pict[i]=Picture[Ind[i]].substr(0,8)+" " Pict[i]=Pict[i].substr(0,Pict[i].indexOf(" ")) if (Ind[i]==1) Target[i]="first picture from the picture list" if (Ind[i]==2) Target[i]="second picture from the picture list" if (Ind[i]==Pict_Total) Target[i]="last picture from the picture list" if (Ind[i]==Pict_Total-1) Target[i]="second last picture from picture list" } defaultStatus="Click left mouse button on the big picture to return to picture list (or click [x] at top-right)" // HREF values for PICTURE.HTM navigational recursive self-calls First_HREF ="PICTURE.HTM?"+1+"|"+Dn_Dir+"|"+Pict_Lst+"|"+Thum_Dir+"|"+Pict_Dir+"|"+Descr_First.replace(/ /g,"%20") Two_Back_HREF ="PICTURE.HTM?"+Ind[0]+"|"+Dn_Dir+"|"+Pict_Lst+"|"+Thum_Dir+"|"+Pict_Dir+"|"+Descr[0].replace(/ /g,"%20") One_Back_HREF ="PICTURE.HTM?"+Ind[1]+"|"+Dn_Dir+"|"+Pict_Lst+"|"+Thum_Dir+"|"+Pict_Dir+"|"+Descr[1].replace(/ /g,"%20") One_Ahead_HREF="PICTURE.HTM?"+Ind[2]+"|"+Dn_Dir+"|"+Pict_Lst+"|"+Thum_Dir+"|"+Pict_Dir+"|"+Descr[2].replace(/ /g,"%20") Two_Ahead_HREF="PICTURE.HTM?"+Ind[3]+"|"+Dn_Dir+"|"+Pict_Lst+"|"+Thum_Dir+"|"+Pict_Dir+"|"+Descr[3].replace(/ /g,"%20") Last_HREF ="PICTURE.HTM?"+Pict_Total+"|"+Dn_Dir+"|"+Pict_Lst+"|"+Thum_Dir+"|"+Pict_Dir+"|"+Descr_Last.replace(/ /g,"%20") if (Pict_Ind==1) // "First" full button image description (IMG tag) Button[0]="<IMG SRC='BUT-FSTP.GIF' WIDTH=13 HEIGHT=13 BORDER=0'></A>" else Button[0]="<A HREF="+First_HREF+" " +"onMouseOver=\"document.But_Fst.src='BUT-FSTS.GIF'; window.status='Click left mouse button here to move to the first picture (on picture list)'; return true\"" +" onMouseOut=\"document.But_Fst.src='BUT-FSTA.GIF'; window.status=''; return true\">" +"<IMG NAME='But_Fst' SRC='BUT-FSTA.GIF' WIDTH=13 HEIGHT=13 BORDER=0 TITLE='Move to the first picture'></A>" if (Pict_Ind==Pict_Total) // "Last" full button image description (IMG tag) Button[6]="<IMG SRC='BUT-LSTP.GIF' WIDTH=13 HEIGHT=13 BORDER=0'></A>" else Button[6]="<A HREF="+Last_HREF+" " +"onMouseOver=\"document.But_Lst.src='BUT-LSTS.GIF'; window.status='Click left mouse button here to move to the last picture (on picture list)'; return true\"" +" onMouseOut=\"document.But_Lst.src='BUT-LSTA.GIF'; window.status=''; return true\">" +"<IMG NAME='But_Lst' SRC='BUT-LSTA.GIF' WIDTH=13 HEIGHT=13 BORDER=0 NAME='But_Lst' TITLE='Move to the last picture'></A>" // Standard description heads for proximity navigation thumbnails and buttons Two_Back ="<A HREF="+Two_Back_HREF+" " +"onMouseOver=\"document.But_2Bk.src='BUT-2BKS.GIF'; window.status='Click left mouse button here to move two pictures back ("+Target[0]+")'; return true\"" +" onMouseOut=\"document.But_2Bk.src='BUT-2BKA.GIF'; window.status=''; return true\">" One_Back ="<A HREF="+One_Back_HREF+" " +"onMouseOver=\"document.But_1Bk.src='BUT-1BKS.GIF'; window.status='Click left mouse button here to move one picture back ("+Target[1]+")'; return true\"" +" onMouseOut=\"document.But_1Bk.src='BUT-1BKA.GIF'; window.status=''; return true\">" Return ="<A HREF='javascript:void(window.close())' " +"onMouseOver=\"document.But_Stp.src='BUT-STPS.GIF'; window.status='Click left mouse button here to return to picture list (or click [x] at window top-right corner)'; return true\"" +" onMouseOut=\"document.But_Stp.src='BUT-STPA.GIF'; window.status=''; return true\">" One_Ahead="<A HREF="+One_Ahead_HREF+" " +"onMouseOver=\"document.But_1Ah.src='BUT-1AHS.GIF'; window.status='Click left mouse button here to move one picture ahead ("+Target[2]+")'; return true\"" +" onMouseOut=\"document.But_1Ah.src='BUT-1AHA.GIF'; window.status=''; return true\">" Two_Ahead="<A HREF="+Two_Ahead_HREF+" " +"onMouseOver=\"document.But_2Ah.src='BUT-2AHS.GIF'; window.status='Click left mouse button here to move two pictures ahead ("+Target[3]+")'; return true\"" +" onMouseOut=\"document.But_2Ah.src='BUT-2AHA.GIF'; window.status=''; return true\">" // Adjusted description tails for proximity navigation thumbnails and buttons Thumb_Two_Back ="" Thumb_One_Back ="" Thumb_One_Ahead="" Thumb_Two_Ahead="" if ((Pict_Total >4)|| // Move two pictures back (Pict_Total==4)&&(Pict_Ind >2)|| (Pict_Total==3)&&(Pict_Ind==3)) {Thumb_Two_Back=Two_Back +"<IMG SRC='"+Dn_Dir+Thum_Dir+"/"+Pict[0]+".JPG' TITLE=\"#"+Ind[0]+"("+Pict_Total+") - "+Descr[0]+"\" BORDER=1></A><BR>" +"<FONT SIZE=2><FONT COLOR=Purple>Two</FONT> <FONT COLOR=Red>back</FONT> to #"+Numb[0]+"</FONT>" Button[1]=Two_Back +"<IMG NAME='But_2Bk' SRC='BUT-2BKA.GIF' WIDTH=13 HEIGHT=13 BORDER=0 TITLE='Move two pictures back'></A>" } if ((Pict_Total >3)|| // Move one picture back (Pict_Total==3)&&(Pict_Ind==3)|| (Pict_Total==3)&&(Pict_Ind==2)|| (Pict_Total==2)&&(Pict_Ind==2)) {Thumb_One_Back=One_Back +"<IMG SRC='"+Dn_Dir+Thum_Dir+"/"+Pict[1]+".JPG' TITLE=\"#"+Ind[1]+"("+Pict_Total+") - "+Descr[1]+"\" BORDER=1></A><BR>" +"<FONT SIZE=2><FONT COLOR=Green>One</FONT> <FONT COLOR=Red>back</FONT> to #"+Numb[1]+"</FONT>" Button[2]=One_Back +"<IMG NAME='But_1Bk' SRC='BUT-1BKA.GIF' WIDTH=13 HEIGHT=13 BORDER=0 TITLE='Move one picture back'></A>" } Button[3]=Return // Always present when button bar is shown +"<IMG NAME='But_Stp' SRC='BUT-STPA.GIF' WIDTH=13 HEIGHT=13 BORDER=0 TITLE='Return to the picture list'></A>" if ((Pict_Total >3)|| // Move one picture ahead (Pict_Total==3)&&(Pict_Ind==2)|| (Pict_Total==3)&&(Pict_Ind==1)|| (Pict_Total==2)&&(Pict_Ind==1)) {Thumb_One_Ahead="<FONT SIZE=2><FONT COLOR=Green>One</FONT> <FONT COLOR=Blue>ahead</FONT> to #"+Numb[2]+"</FONT><BR>" +One_Ahead +"<IMG SRC='"+Dn_Dir+Thum_Dir+"/"+Pict[2]+".JPG' TITLE=\"#"+Ind[2]+"("+Pict_Total+") - "+Descr[2]+"\" BORDER=1></A>" Button[4]=One_Ahead +"<IMG NAME='But_1Ah' SRC='BUT-1AHA.GIF' WIDTH=13 HEIGHT=13 BORDER=0 TITLE='Move one picture ahead'></A>" } if ((Pict_Total >4)|| // Move two pictures ahead (Pict_Total==4)&&(Pict_Ind <3)|| (Pict_Total==3)&&(Pict_Ind==1)) {Thumb_Two_Ahead="<FONT SIZE=2><FONT COLOR=Purple>Two</FONT> <FONT COLOR=Blue>ahead</FONT> to #"+Numb[3]+"</FONT><BR>" +Two_Ahead +"<IMG SRC='"+Dn_Dir+Thum_Dir+"/"+Pict[3]+".JPG' TITLE=\"#"+Ind[3]+"("+Pict_Total+") - "+Descr[3]+"\" BORDER=1></A>" Button[5]=Two_Ahead +"<IMG NAME='But_2Ah' SRC='BUT-2AHA.GIF' WIDTH=13 HEIGHT=13 BORDER=0 TITLE='Move two pictures ahead'></A>" } // Generate image presentation page with proximity navigation (as a table) // For debugging set BORDER=1 to see table structure T="<TABLE ALIGN=Center BORDER=0 CELLPADDING=0 CELLSPACING=0>" // Vertical centering for a big screen (moved a bit up to offset visual disbalance between bottm bar and top bars) if (window.innerHeight>600) T=T+"<TR><TD HEIGHT="+(window.innerHeight-500)/2+"></TD></TR>" else // Vertical centering for regular screen - for Netscape only // if (navigator.appName=="Netscape") // Doesn't distinguish Firefox from Netscape if ((navigator.userAgent.indexOf("MSIE" )==-1)&& (navigator.userAgent.indexOf("Firefox")==-1)) T=T+"<TR><TD HEIGHT=7></TD></TR>" T=T+"<TR><TD ROWSPAN=6 WIDTH=640 HEIGHT=480 ALIGN=Center VALIGN=Center>" +Return +"<IMG SRC='"+Dn_Dir+Pict_Dir+"/"+Curr_Pict+".JPG' TITLE=\"#"+Pict_Ind+"("+Pict_Total+") - "+Pict_Descr+"\" BORDER=1></A></TD>" // Generate thumbnails for proximity navigation T=T+"<TD ROWSPAN=6> </TD>" +"<TR><TD COLSPAN=8 WIDTH=120 HEIGHT=116 ALIGN=Center VALIGN=Top>" +Thumb_Two_Back +"</TD></TR>" +"<TR><TD COLSPAN=8 WIDTH=120 HEIGHT=116 ALIGN=Center VALIGN=Top>" +Thumb_One_Back +"</TD></TR><TR>" for (i=0;i<7;i++) T=T+"<TD WIDTH=17 HEIGHT=17 ALIGN=Center VALIGN=Center>"+Button[i]+"</TD>" T=T+"<TD WIDTH=1 HEIGHT=16></TD></TR>" // Extra pixel for adjustment +"<TR><TD COLSPAN=8 WIDTH=120 HEIGHT=116 ALIGN=Center VALIGN=Bottom>" +Thumb_One_Ahead +"</TD></TR>" +"<TR><TD COLSPAN=8 WIDTH=120 HEIGHT=116 ALIGN=Center VALIGN=Bottom>" +Thumb_Two_Ahead +"</TD></TR>" T=T+"</TABLE>" document.write(T) //--> </SCRIPT> </FONT> </BODY> </HTML>
Below there's a table of navigation buttons (designed for me by my daughter Natalia). Navigation buttons' *.GIF files should be in the same directory with PICTURE.HTM.
File Name | Button | Button Action | Button State |
BUT-FSTA | FirST picture | Active – can be selected | |
BUT-FSTS | FirST picture | Selected by mouse | |
BUT-FSTP | FirST picture | Passive – can't be selected | |
BUT-2BKA | 2 pictures BacK | Active – can be selected | |
BUT-2BKS | 2 pictures BacK | Selected by mouse | |
BUT-2BKP | 2 pictures BacK | Passive – can't be selected | |
BUT-1BKA | 1 picture BacK | Active – can be selected | |
BUT-1BKS | 1 picture BacK | Selected by mouse | |
BUT-1BKP | 1 picture BacK | Passive – can't be selected | |
BUT-STPA | SToP – return to thumbnails | Active – can be selected | |
BUT-STPS | SToP – return to thumbnails | Selected by mouse | |
BUT-1AHA | 1 picture AHead | Active – can be selected | |
BUT-1AHS | 1 picture AHead | Selected by mouse | |
BUT-1AHP | 1 picture AHead | Passive – can't be selected | |
BUT-2AHA | 2 pictures AHead | Active – can be selected | |
BUT-2AHS | 2 pictures AHead | Selected by mouse | |
BUT-2AHP | 1 pictures AHead | Passive – can't be selected | |
BUT-LSTA | LaST picture | Active – can be selected | |
BUT-LSTS | LaST picture | Selected by mouse | |
BUT-LSTP | LaST picture | Passive – can't be selected |
Note: Stop button can never be "Passive" – it's always possible to return back from picture display to thumbnail list.
A comment concerning the choice of the proximity navigation keys is required as an answer to an inevitable question: why letters and symbols have been chosen for that instead of standard navigation keys? The answer is that in fact I couldn't withstand a temptation to give standard navigation keys a try (an unsuccessful one), and I had even have saved an image of it.
There were, however, serious technical difficulties with this approach. After spending some time in attempts to resolve them I've realized that my application, which was entirely dependent on a browser for its functioning shouldn't try to compete with browser for the keys that browser uses itself as control keys. Such application won't be stable across different browsers, and even across different versions of the same browser. With this in mind I've chosen letters and symbols that are still mnemonic, while not interfering in any way with a browser controls.
Usage of PICTURE JavaScript is described separately in the Picture Album Support System presentation page. You'll find there several representative examples of picture albums along with detailed instructions how to use this system for your own picture albums.