0

I have build an animation with canvas, following some code and tips from others anwers:
-Draw HTML5/Javascript Canvas Path in Time
-Animate a Fill Circle using Canvas

Here is a fiddle

canvasHolder = document.getElementById( 'canvas' );
context = canvasHolder.getContext('2d');

context.fillStyle = 'white';
var w = canvasHolder.width, h = canvasHolder.height;
context.fillRect( 0, 0, w, h);
context.scale(2, 2);

//set the direction the line draws in
//1->ltr | -1->rtl
var dir = -1;
//IMPORTANT: this must be set to greater than the length of the line
var length = 350;
//the speed of the line draw
var speed = 1;

var progress = 0;
var lineInterval;

var full = 1;
var amount = 0;
var amountToIncrease = 5;

context.globalCompositeOperation='copy';
drawLine();

function drawLine() {
    //this clears itself once the line is drawn
    lineInterval = setInterval(updateLine, 1);
}

function updateLine() {
    //define the line
    defineLine(5);

  if(progress<length) {

      progress+=speed;
      moveDash(progress, dir);
      /**/
      document.getElementById("log").innerHTML = progress;
      /**/
  } else {

      clearInterval(lineInterval);
      progress = 0;
      context.clearRect(0, 0, 300, 300);
      fillInterval = setInterval(fillHeart, 100);
  }  
}

function fillHeart() {
  
  amount += amountToIncrease;
  /**/
  document.getElementById("log").innerHTML = amount;
  /**/
  if ((amount/100) < full) {
  
      defineLine(15);
      
  } else {

   clearInterval(fillInterval);
      amount = 0; // restart
      context.clearRect(0, 0, 300, 300);
      lineInterval = setInterval(updateLine, 1);
  }
}

function defineLine(b) {
    context.beginPath();
    
    if (b < 10) {
     context.moveTo(75,40);
    }
    
    context.bezierCurveTo(75,37,70,25,50,25);
    context.bezierCurveTo(15,25,20,62.5,20,62.5);
    context.bezierCurveTo(20,80,40,102,75,120);
    context.bezierCurveTo(110,102,130,80,130,62.5);
    context.bezierCurveTo(130,62.5,135,25,100,25);
    context.bezierCurveTo(85,25,75,37,75,40);
    context.lineWidth = 3;
    context.lineCap = "round";
    context.strokeStyle = 'red';
    
    if (b > 10) {
      context.clip(); 
      context.fillStyle = 'rgba(255, 0, 0, '+(amount/100)+')';
      context.fillRect(0,0,300,300);
      context.restore(); 
    }
}

function moveDash(frac, dir) {
    //default direction right->left
    var dir = dir || -1 
    context.setLineDash([length]);
    context.lineDashOffset = dir*(frac+length);
    context.stroke();
}
<canvas id="canvas" width="300" height="300"></canvas>
<span id="log"></span>

But there are 3 problem that i'm not capable to solve:
-there is a thin red line staying in the canvas.
-The path from first animation doesn't disappear.
-The animations get slower each time they finish.

Can you help me figure it out, i have try but i just make it worst.
And if you can explain why is not working properly how the code is

Community
  • 1
  • 1
Jherson
  • 1
  • 1
  • 1
    For your thin red line, it's because of `clip` which doesn't really clip antialiasing artifacts... You should prefer a globalCompositeOperation method instead. For the previous path, I don't get what you mean... For the slowering, don't use setInterval with such a small amount interval (actually don't use setInterval at all for animations. Prefer the requestAnimationFrame method. – Kaiido Feb 22 '17 at 02:00
  • And actually you don't even need the clip nor gCO, since `fill()` will do the same in your case. Also, you are calling `restore()` without ever calling `save()`which won't have any effect, but you'll stack more and more clipping areas.. Still dirty and not recommended but it may give you an hint : https://jsfiddle.net/bndsxrs2/16/ – Kaiido Feb 22 '17 at 02:07
  • Thx Kaiido for the explaining and the modifications, i didn't know about requestAnimationFrame, i will look and learn more to it and try clean the code. – Jherson Feb 23 '17 at 00:29

0 Answers0