Results 1 to 10 of 10

Thread: Swiss Army Image Slideshow

  1. #1
    Join Date
    Mar 2007
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Question Swiss Army Image Slideshow

    1) Script Title: Swiss Army Image Slideshow

    2) Script URL (on DD): http://www.dynamicdrive.com/dynamici...army/index.htm

    3) Describe problem: How can I make the slideshow start at a particular picture?

    Hi, I am using this slideshow in a photoalbum web application. When a user opens an album it is possible to click on a picture to open the slideshow in a new page. I then want the slideshow to start on the selected picture.
    Ex: The user has 22 pictures in his album and clicks on picture 5, the slideshow should open and starting to show with picture 5 of 22.

    I've tried by calling a javascript function on page load, but this does not work (nothing happens, but it works if a have a link on the page that calls this function when i click it manually):

    function initPage() {
    iss[0].jumper(5);
    }

  2. #2
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    The way to do this is to send the value through the URL.

    Using PHP, you can use a "get" variable like:
    http://my.com/page.php?variable=value&var2=val2

    So... you could use php--
    <?php echo $_GET['pic']; ?>
    and if the url was ?pic=3,
    that would output '3' into the html.
    So you could seed the javascript that way.

    However, I am better with PHP than Javascript, and this IS possible with just javascript. I can't tell you exactly how to do it, but I know you can.

    You can use, somehow, the request.uri or something to get the value, then find the pic number. That should work.

    Sorry this isn't a full solution yet, but it should at least give you an idea of what to look for.
    Daniel - Freelance Web Design | <?php?> | <html>| espa˝ol | Deutsch | italiano | portuguŕs | catalÓ | un peu de franšais | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  3. #3
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    29,070
    Thanks
    44
    Thanked 3,216 Times in 3,178 Posts
    Blog Entries
    12

    Default

    I wrote this script and although there may be a way, probably is a way, to code things for what you are asking, I can't find it after quite a bit of educated trial and error. The solution is either so simple that I am missing it or so complex that it would require at least a minor rewrite. In any case, I found a method that works, almost. The catch is that it promotes the desired array entry to the the 0 position and replaces it's original position in the array with the entry from the 0 position. This is different in that the number reported by the counter (if used) will always be:

    Viewing Image: 1 of 22

    If that is acceptable, here is how it works - place this after the array and use the array's name in place of array_name:

    Code:
    function get(key_str) {
    var query = window.location.search.substr(1);
    var pairs = query.split("&");
    for(var i = 0; i < pairs.length; i++) {
    var pair = pairs[i].split("=");
    if(unescape(pair[0]) == key_str)
    return unescape(pair[1]);
    }
    return null;
    }
    
    if(array_name.splice&&get('picnum')){
    array_name.tmp=array_name[get('picnum')];
    array_name.splice(get('picnum'),1,array_name[0]);
    array_name.splice(0,1,array_name.tmp);
    }
    This will allow you to link to the page with the show on it like so:

    Code:
    <a href="swiss_army.htm?picnum=2">Link Text or image tag</a>
    The bright red number is the array entry you want promoted to the first slot. Remember, the entries are numbered from 0 so 2 is actually the third image.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  4. #4
    Join Date
    Mar 2007
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default

    Thanks, for you quick response.

    I've tried your suggestion, but I have found a problem.

    Ex : The album contains 10 pictures in in a particular sort order. If the user clicks picture 5 with your solution, the correct picture is displayed first in the slideshow, but then the next picture displayed is picture 2 instead of picture 6...you see the problem ?

    Also I need the counter to be functional. Is it not possible to adjust the counter so I can say : counter + picnum ??

    One last question: How can I communicate with the slideshow, getting the value (number in array) of the current displayed picture from a javascript function ?

    Kay

  5. #5
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    29,070
    Thanks
    44
    Thanked 3,216 Times in 3,178 Posts
    Blog Entries
    12

    Default

    Well, I realized this wasn't optimal. Then I got to thinking, if I can rearrange the array I ought to be able to put it in any order I like and make adjustments for the image 1 of 22 thing. It turns out to be like I said, a minor modification but, I had all I really needed, just about, from the previous modification. So, start over, remove all that added stuff, add this instead (the get function is the same though):

    Code:
    function get(key_str) {
    var query = window.location.search.substr(1);
    var pairs = query.split("&");
    for(var i = 0; i < pairs.length; i++) {
    var pair = pairs[i].split("=");
    if(unescape(pair[0]) == key_str)
    return unescape(pair[1]);
    }
    return null;
    }
    
    (function(an, num){
    if(an.splice&&num==num&&num){
    an.tmp=an.splice(num,an.length-1*num);
    an.tmp2=an.splice(0,an.length);
    an.splice(0,1,an.tmp[0]);
    for (var i_tem = 1; i_tem < an.tmp.length; i_tem++)
    an.push(an.tmp[i_tem]);
    for (var i_tem = 0; i_tem < an.tmp2.length; i_tem++)
    an.push(an.tmp2[i_tem]);
    an.countf=num;
    }
    })(array_name, 1*get('picnum'));
    Now there is only one place to put the name of your array, replace array_name with it. We also need a modification to swissarmy.js - fairly near the end of the file you will find:

    inter_slide.prototype.rotateimg=function()

    it contains, near its end, these lines:

    Code:
    if(this.counter){
    var padit='';
    for (var p=0; p<this.cpad-(this.nextimgidx+1).toString().length; p++)
    padit+='<span style="visibility:hidden;">0</span>';
    this.go('thecnt'+this.issid).innerHTML = padit+(this.keeptrack()<this.imgs.length? this.keeptrack()+1 : 1);
    }
    Replace them with:

    Code:
    if(this.counter){
    var padit='';
    for (var p=0; p<this.cpad-(this.nextimgidx+1).toString().length; p++)
    padit+='<span style="visibility:hidden;">0</span>';
    this.countf=this.imgs.countf||0;
    this.go('thecnt'+this.issid).innerHTML = padit+(this.keeptrack()+this.countf<this.imgs.length? this.keeptrack()+this.countf+1 : this.keeptrack()+this.countf+1-this.imgs.length);
    }
    That will get the counter reporting the correct number. Your last question (the 'one last question'), retrieving the image number with a function was easy but now, with these modifications, It is a little more complicated, I will make that up and post it next in this thread.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  6. #6
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    29,070
    Thanks
    44
    Thanked 3,216 Times in 3,178 Posts
    Blog Entries
    12

    Default

    If you missed it, the main answer to your question is in my previous post in this thread. Here is the bit about getting the current image number. Place this new function at the end of swissarmy.js:

    Code:
    inter_slide.prototype.getimagenum=function(){
    this.countf=this.imgs.countf||0;
    return this.keeptrack()+this.countf<this.imgs.length? this.keeptrack()+this.countf+1 : this.keeptrack()+this.countf+1-this.imgs.length;
    }
    Now you can retrieve the current image number like so:

    Code:
    iss[0].getimagenum()
    where 0 refers to the slide show instance on the page. The first is 0, then comes 1, then 2, etc. If you have only one slide show on the page, it is always 0.

    Example usage:

    Code:
    alert(iss[0].getimagenum())
    Edit/Added Later:

    Looking back over your requirement for this feature:

    How can I communicate with the slideshow, getting the value (number in array) of the current displayed picture
    That number would actually be:

    Code:
    iss[0].getimagenum()-1
    And, although it won't matter in most cases, it will be the array number of the image in the original array, not the modified one used to get things to work for these modifications we've been using to load the page at a certain image. If you want the array number of the currently showing image in the new modified array, it would be:

    Code:
    iss[0].keeptrack()<iss[0].imgs.length? iss[0].keeptrack() : 0;
    Last edited by jscheuer1; 03-27-2007 at 12:16 AM. Reason: Add info
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  7. #7
    Join Date
    Mar 2007
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default

    Thank you so much for all your help, this works excelent.

    One more question: For each picture in the slideshow I need to show or hide a "Add to cart" button via my own javascript function. What can I do to call this function on each picture change? Where should I put my code?

    Kay

  8. #8
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    29,070
    Thanks
    44
    Thanked 3,216 Times in 3,178 Posts
    Blog Entries
    12

    Default

    You should be able to put your call(s) in with the counter code (or just before it, if you aren't using the counter) -

    If using the counter:

    Code:
    if(this.counter){
    your call(s) to show and/or hide some things
    var padit='';
    for (var p=0; p<this.cpad-(this.nextimgidx+1).toString().length; p++)
    padit+='<span style="visibility:hidden;">0</span>';
    this.countf=this.imgs.countf||0;
    this.go('thecnt'+this.issid).innerHTML = padit+(this.keeptrack()+this.countf<this.imgs.length? this.keeptrack()+this.countf+1 : this.keeptrack()+this.countf+1-this.imgs.length);
    }
    or if not using the counter:

    Code:
    your call(s) to show and/or hide some things
    if(this.counter){
    var padit='';
    for (var p=0; p<this.cpad-(this.nextimgidx+1).toString().length; p++)
    padit+='<span style="visibility:hidden;">0</span>';
    this.countf=this.imgs.countf||0;
    this.go('thecnt'+this.issid).innerHTML = padit+(this.keeptrack()+this.countf<this.imgs.length? this.keeptrack()+this.countf+1 : this.keeptrack()+this.countf+1-this.imgs.length);
    }
    Your added code can use the getimagenum() function. And, when used inside the main script, it can be used with the 'this' keyword:

    Code:
    this.getimagenum()
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  9. #9
    Join Date
    Mar 2007
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default

    Hi again

    I se that there must be some functionality that stops/pauses the slideshow if the next picture is unavailable. Either if it is not loaded yet because of slow connection(which is quite cool) or does not exist.

    Can you explain how this works. Is it possible to turn it of?

    My "problem" is that I may have a customer with 50 pictures in an album and maybe picture 25 is something wrong with, then the slideshow will not continue from picture 24, even if the user tries to click Next.

    Thanks in advance.

    Kay

  10. #10
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    29,070
    Thanks
    44
    Thanked 3,216 Times in 3,178 Posts
    Blog Entries
    12

    Default

    The best idea is to not have a problem with image 25. Like, when setting up any slide show, it is a really good idea to ensure that all images are present and accounted for.

    As for the mechanism that does this, it (or at least part of it) is here:

    Code:
    inter_slide.prototype.rotateimg=function(){
    if(this.dom){
    var cimg=this.go('theimg'+this.nextimgidx+'_'+this.issid)? this.go('theimg'+this.nextimgidx+'_'+this.issid) : null;
    if(cimg&&typeof cimg.complete=='boolean'&&!cimg.complete){
    var cacheobj=this
    clearTimeout(this.loading)
    this.loading=setTimeout(function(){cacheobj.rotateimg()}, 300)
    return;
    }
    if (this.mouseovercheck==1){
    var cache . . .
    Now, the test of an image's complete status is performed in one other spot so, removing the above red section may not stop the behavior that breaks the script when images are missing or broken but, it probably will. It certainly will prevent the script from ensuring an image is loaded before attempting to display it.

    Here's the other spot:

    Code:
    slideHTML+='<img id="theimg'+picidx+'_'+this.issid+'" src="'+(this.loadimgidx[picidx]&&typeof this.loadimgidx[picidx].complete=='boolean'&&this.loadimgidx[picidx].complete? this.loadimgidx[picidx].src : this.imgs[picidx][0])+'" alt="'+(this.ualt? this.imgs[picidx][1] : 'Slide Show Image')+'" title="'+(this.utit? this.imgs[picidx][1] : '')+'" '+(this.imbcolor&&!this.imgs[picidx].noborder? 'style="border:'+this.imgborder+'px '+(this.imbstyle? this.imbstyle : 'solid')+' '+this.imbcolor+';"' : 'border="'+(this.imgs[picidx].noborder? '0' : this.imgborder)+'"')+(!this.width||!this.height? ' onload="iss['+this.issid+'].imgload(this);"' : '')+'>'
    But, I think it needs no change for what you are talking about as, it already falls back to the unloaded version of the image if a preloaded version isn't available.

    You might also try replacing the red section with:

    Code:
    if(cimg&&typeof cimg.complete=='boolean'&&!cimg.complete){
    this.attempt=this.attempt? this.attempt+1 : 1;
    clearTimeout(this.loading)
    if(this.attempt<12){
    var cacheobj=this
    this.loading=setTimeout(function(){cacheobj.rotateimg()}, 300)
    return;
    }
    else
    this.attempt=0;
    }
    This will give the script a certain number of tries at preloading the image. You may need to adjust the 12. At 12 it represents about 3 seconds worth of attempting to complete loading the image (in 300 millisecond intervals).
    Last edited by jscheuer1; 04-10-2007 at 03:21 PM. Reason: add info
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •