2016-05-25 4 views
0

Die in diesem JSFiddle verknüpfte Animation sollte eine EKG-Stilmaschine mit einer Reihe von über den Bildschirm laufenden Zeilen anzeigen, die nach einem kurzen Zurückkehren zu einem leeren Bildschirm wiederholt werden .So löschen Sie nur den animierten Abschnitt der Leinwand zwischen den Loops

Es ist eine Modifikation eines großen HTML5 Canvas eines Clipping-Animation Beispielcode (http://tajvirani.com/2012/03/30/html5-canvas-animating-a-clip-mask-path/)

Erste Schleife einen Zauber wirkt, aber es gibt einige flackernden Artefakte von da an.

Wie kann ich vor jeder Iteration zum ursprünglichen Aussehen (Maschinenbild mit leerem, schwarzem Bildschirm) zurückkehren?

Ich dachte c1.clearRect (0, 0, 386, 380); - Zeile 42 der JSFiddle - tat das, aber keine Freude.

setInterval(animateManaging,6000); 

function animateManaging() { 
    // Grabs the canvas element we made above 
    var ca1=document.getElementById("cvs3"); 

    // Defines the 2d thing, standard for making a canvas 
    var c1=ca1.getContext("2d"); 

    // Creates an image variable to hold and preload our image (can't do animations on an image unless its fully loaded) 
    var img1 = document.createElement('IMG'); 

    // Loads image link into the img element we created above 
    img1.src = "http://s33.postimg.org/3pk551xcv/managing_values.png"; 

    // Creates the first save event, this gives us a base to clear our clipping/mask to since you can't just delete elements. 
    c1.save(); 

    // Our function for when the image loads 
    img1.onload = function() { 
     // clear off the canvas 


     // First call to our canvas drawing function, the thing that is going to do all the work for us. 
      drawc1r(0); 

     // The function that is doing all the heavy lifting. The reason we are doing a function is because 
     // to make an animation we have to draw the circle (or element) frame by frame, to do this manually would be to time 
     // intensive so we are just going to create a loop to do it. 'i' stands for the radius of our border 
     // so over time our radius is going to get bigger and bigger. 
     function drawc1r(i) { 
      // Creates a save state. Imagine a save state like an array, when you clear one it pops last element in the array off the stack 
      // When you save, it creates an element at the top of the stack. So if we cleared without making new ones, we would end up with nothing on our stage. 

      c1.save(); 

      // This clears everything off the stage, I do this because our image has transparency, and restore() (the thing that pops one off the stack) 
      // Doesn't clear off images, and so if we stick an image on the stage over and over, the transparency will stack on top of each other and 
      // That isn't quite what we want. 

      c1.clearRect(0, 0, 386, 380); 

      // Adds one to the interval count 
      i++; 

      // Tells canvas we are going to start creating an item on the stage - it can be a line, a rectangle or any shape you draw, but whatever 
      // after this path will be added to the clip when its called. I can have 3 rectangles drawn and that would make a clip. 
      c1.beginPath(); 

      // make the clipping rectangle, using i to make it grow on each interval 
      c1.rect(0,0,i*13,380); 

      // After everything is defined, we make a clip area out of it. 
      c1.clip(); 

      // Now that we have the clip added to it, we are going to add the image to the clip area. 
      c1.drawImage(img1, 0, 0); 

      // This pops one off the stack which gets rid of the clip so we can enlarge it and make it again on the next pass 
      c1.restore(); 

      // Here is the final size of the rectangle, I want it to grow until it hits 380 so we set a timeout to run this function again 
      // until we get the size we want. The time in milliseconds pretty much defines your framerate 


      if (i < 380) { 
       setTimeout(function() { 
        drawc1r(i); 
       }, 100); 
      } 
     } 
    } 
} 

https://jsfiddle.net/0o1x1ryp/#&togetherjs=nftC29hATf

Antwort

1

hier größte Problem ist, dass Sie animateManaging alle sechs Sekunden anrufen, so dass Sie viele ‚Instanzen‘ einer Schublade schaffen, die dieses Flackern zugleich und erstellen ziehen wird.

Eher als animateManaging einmal, und behandeln Sie die Schleife selbst: was Sie wollen, ist, wenn die rechte Seite erreicht ist, Dinge zu löschen und auf der linken Seite neu zu starten: entfernen Sie Ihre clearRect und ändern Sie Ihre letzte if zu:

if (i * moveSpeed < viewWidth) { 
    // just resume if right side not reach 
    setTimeout(function() { 
     drawc1r(i); 
    }, animInterval); 
    } else { 
    // clear and restart from 0 when right side reached. 
    setTimeout(function() { 
     c1.clearRect(0, 0, viewWidth, viewHeight); 
     drawc1r(0); 
    }, animInterval); 
    } 

Außerdem fügte ich einige Vars hart codierten Konstanten zu vermeiden (moveSpeed, viewWidth, viewHeight, animInterval) und ich die Quelle des Bildes nach die onload handler Einstellung.

https://jsfiddle.net/gamealchemist/0o1x1ryp/5/

+0

Das ist unglaublich hilfreiche Ratschläge:

Nach Geige sollte auf Ihre Bedürfnisse nahe sein. Ich habe mit der Zeit im SetInterval gespielt, aber es hat das Problem nicht konsequent behoben. Dieser Fix scheint den Job zu machen. Ich schätze den allgemeineren JS-Rat auch - fest kodierte Konstanten und Reihenfolge des Geschäftes (img, onload) Rat bemerkt. – CaraGee

Verwandte Themen