0

I want to display several pictures for a specific amount of time. When the time runs out go to the next picture, and this cycle loops until there are no more pictures.

I've tried for and while loop's but they don't work with my implementation.

Here is what I have:

JavaScript

/*
*   Set's a timer for the image that's going to be displayed
*
*   @param plan contains the array with the objects that contain the picture path and time
*   @param index index of array
*   @version 1.0
*/
function display(plan, index){
    var exercises = plan.getExercises(); // array

    //  60*1000 -> 1 minute 

    //Displays the image for a 'exercises[index].getDuration() * 1000' period of time
    image(exercises[index].getURL());

    setTimeout(function() {

            //Removes the image when time is up
            var el = document.getElementById("myDiv");
            el.parentNode.removeChild(el);
            gif_acabou = true;

    }, exercises[index].getDuration() * 1000);

}

/*
*   Creates an element and adds it to the HTML <div>
*   
*   @param img_URL - image path
*   @version 1.0
*/
function image(img_URL) {
    var img = document.createElement("IMG");
    img.src = img_URL;
    document.getElementById('myDiv').appendChild(img);

}
Filipe Nóbrega
  • 564
  • 4
  • 18
  • Why do you have one `setTimeout` with an immediate callback (`}, 0);`) wrapping another one? Is the setTimeout-0 trick fixing some buggy behaviour? – msanford Apr 20 '18 at 19:21
  • 1
    @msanford no, my mistake, it was for a previous task that I was trying to do. I've edited it now – Filipe Nóbrega Apr 20 '18 at 19:31
  • No problem, it can [sometimes serve a function,](https://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful) which is why I asked. – msanford Apr 20 '18 at 19:34
  • @FilipeNóbrega I think there's a typo in your code: It's not `exercicios` but `exercises`. – amedina Apr 20 '18 at 19:48
  • @amedina I translate my code so it's easier for stack users to read it. It does not change the outcome. Thx! – Filipe Nóbrega Apr 20 '18 at 19:58

2 Answers2

0

I can't test your code, but this is how I would correct it:

function display(plan, index) {
  var exercises = plan.getExercises(); // array

  // Displays the image for a 'exercises[index].getDuration() * 1000'
  // period of time
  image(exercises[index].getURL(), function(){
    setTimeout(function() {
      //Removes the image when time is up
      var el = document.getElementById("myDiv");
      el.parentNode.removeChild(el);
      gif_acabou = true;
    }, exercises[index].getDuration() * 1000); //  60*1000 -> 1 minute
  });
}

function image(img_URL, executeAfterLoad) {
  var img = document.createElement("IMG");
  img.addEventListener('load', executeAfterLoad, false);
  img.src = img_URL;
  document.getElementById("myDiv").appendChild(img);  
}

The idea is that the load of the image is an async opperation, so you need to pass it a function in order to be notified when it finishes, and then, start counting the time.

amedina
  • 2,838
  • 3
  • 19
  • 40
0

Here's one way to do it, Using Custom Element (webcomponents).

    class ExerciseDisplay extends HTMLElement {
        constructor() {
            super();       

            this.imageEl = document.createElement("img");
            this.imageEl.setAttribute("width", "350px");
            this.appendChild(this.imageEl);

            this.getWorkout("someurl")
                // this becomes undefined if methods are called from promises,
                // https://stackoverflow.com/questions/34930771/why-is-this-undefined-inside-class-method-when-using-promises/34930859
                .then((workout) => this.showWorkout(workout))
                .catch((err) => { /* show error */ });            
        }        

        getWorkout(url) {
            return new Promise((resolve, reject) => {
                // XMLHttpRequest?
                resolve([
                    {name: "Bharadvajasana I", imageUrl: "https://www.thefitglobal.com/wp-content/uploads/2017/06/Bharadwajasana.jpg", time: "5"},
                    {name: "Padangusthasana", imageUrl: "https://previews.123rf.com/images/giggsy25/giggsy251711/giggsy25171100023/89035549-young-asian-woman-doing-yoga-in-hasta-padangusthasana-or-standing-hand-to-toe-yoga-pose-on-the-mat-i.jpg", time: "15"}
                    // NOTE: last excercise's time is not relevant.
                ]);
            });
        }

        showWorkout(workout) {
            let totalTime = 0;

            for (let i = 0; i < workout.length; ++i) {
                let exercise = workout[i];
                window.setTimeout(() => {this.setImage(exercise.imageUrl);}, totalTime * 1000);                
                totalTime += exercise.time;
            }
        }

        setImage(url) {
            this.imageEl.src = "";
            this.imageEl.src = url;
        }
    };

    window.customElements.define("exercise-display", ExerciseDisplay);
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Excercises</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="import" href="components/excercise-display.html">
</head>
<body>
    <h1>Excercise helper application</h1>

    <exercise-display>
    </exercise-display>

    <script>        
    </script>
</body>
</html> 

Hope this helps!

hungryWolf
  • 391
  • 1
  • 3
  • 15