简体   繁体   中英

Javascript canvas animated arc

I've been learning some javascript/canvas animation, I'm having trouble getting this animation to work correctly.

My goal is that the animation will start drawing at the top, then as it gets back to the top it will stop progressing and the start position will progress around the arc making it look as though it is erasing itself and once at the top (1.5 * PI) will starting drawing again.

Here is a fiddle: https://jsfiddle.net/kg1fmsjj/

Here is my code:

function f(element, colour, thickness, elapsedTime) {

  // Create Element
  element.innerHTML = '';
  var canvas = document.createElement('canvas');
  var context = canvas.getContext("2d");
  element.appendChild(canvas);

  // Circle Params
  context.lineWidth = thickness;
  context.strokeStyle = colour;

  var width = canvas.width;
  var height = canvas.height;
  var mathPi = Math.PI;
  var x = canvas.width / 2;
  var y = canvas.height / 2;
  var radius = 40;
  var startAngle = 1.5 * mathPi;
  var endAngle = 1.5 * mathPi;
  context.lineWidth = thickness;
  context.strokeStyle = colour;

   var erasing = false;

  function animate() {

    if(erasing) {
      startAngle = startAngle + 0.01 * mathPi;
    } else {
      endAngle = endAngle + 0.01 * mathPi;
    }

    if (endAngle > (1.5 * mathPi)) {
      erasing = true;
    }
    if (startAngle > (1.5 * mathPi)) {
      erasing = false;
    }

    context.beginPath();
    context.arc(x, y, radius, startAngle, endAngle, false);
    context.stroke();
    context.closePath();

  }

  setInterval(animate, 10);

}

f(document.getElementById('out'), '#800080', 4, 60);

context.arc lets you optionally draw your arc counterclockwise.

This ability lets you create your desired effect:

  • To "draw" the arc, draw an increasing arc clockwise.
  • To "erase" the arc, draw a decreasing arc counterclockwise.

Here's example code and a Demo:

 var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; ctx.lineWidth=2; ctx.strokeStyle='#800080'; var PI=Math.PI; var cx=cw/2; var cy=ch/2; var radius=cw/2-30; var angle=0; var direction=1; requestAnimationFrame(animate); function animate(time){ ctx.clearRect(0,0,cw,ch); angle+=PI/120; if(angle<0 || angle>PI*2){ angle=0; direction*=-1; } draw(); requestAnimationFrame(animate); } function draw(){ var counterclockwise=(direction>0)?false:true; var s=-Math.PI/2; var e=angle-Math.PI/2; ctx.beginPath(); ctx.arc(cx,cy,radius,s,e,counterclockwise); ctx.stroke(); } 
 body{ background-color: ivory; } #canvas{border:1px solid red; margin:0 auto; } 
 <canvas id="canvas" width=300 height=300></canvas> 

You need to clear the canvas on each repaint using the clearRect() method.

You need to change the conditions when erasing variable is toggled. If erasing and startAngle >= endAngle then toggle erasing variable. If not erasing and endAngle >= startAngle + 2 * PI then toggle erasing variable.

The animate() method then become...

function animate() {

    if(erasing) {
        startAngle = startAngle + 0.01 * mathPi;
        if (startAngle >= endAngle) {
            erasing = false;
        }
    } else {
        endAngle = endAngle + 0.01 * mathPi;
        if (endAngle >= startAngle + 2.0 * mathPi) {
            erasing = true;
        }
    }

    context.clearRect(0, 0, canvas.width, canvas.height);
    context.beginPath();
    context.arc(x, y, radius, startAngle, endAngle, false);
    context.stroke();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM