javascript - 清除 Canvas 仅工作一次

标签 javascript html canvas

因此,在我的代码中,我在全屏 Canvas 中绘制了一个箭头。一秒钟后,它会被我的清晰 Canvas 功能删除,效果很好。现在要画一个圆。也工作得很好。之后我想再次清除 Canvas ,但它不再起作用了。有谁知道为什么它只能工作一次? 非常感谢,任何答案都会有帮助!

function generateRandomNumber() {
  var minangle = 0;
  var maxangle = 2 * Math.PI;
  randangle = Math.random() * (maxangle - minangle) + minangle;
  return randangle;
};


function createArrowAngle() {
  var currentangle = generateRandomNumber();
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;
  var x1 = centerX + 50 * Math.cos(currentangle);
  var y1 = centerY + 50 * Math.sin(currentangle);
  var x2 = centerX + 50 * Math.cos(currentangle + Math.PI);
  var y2 = centerY + 50 * Math.sin(currentangle + Math.PI);
  return [x1, y1, x2, y2]
}

function drawCircle(circleColour) {
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;
  var radius = 20;

  context.beginPath();
  context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
  context.fillStyle = circleColour;
  context.fill();
  context.lineWidth = 20;
  context.strokeStyle = circleColour;
  context.stroke();
}

function drawArrow(fromx, fromy, tox, toy, colourarrow) {
  //variables to be used when creating the arrow
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  var headlen = 3;

  var angle = Math.atan2(toy - fromy, tox - fromx);

  //starting path of the arrow from the start square to the end square and drawing the stroke
  ctx.beginPath();
  ctx.moveTo(fromx, fromy);
  ctx.lineTo(tox, toy);
  ctx.strokeStyle = colourarrow;
  ctx.lineWidth = 20;
  ctx.stroke();

  //starting a new path from the head of the arrow to one of the sides of the point
  ctx.beginPath();
  ctx.moveTo(tox, toy);
  ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 7), toy - headlen * Math.sin(angle - Math.PI / 7));

  //path from the side point of the arrow, to the other side point
  ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 7), toy - headlen * Math.sin(angle + Math.PI / 7));

  //path from the side point back to the tip of the arrow, and then again to the opposite side point
  ctx.lineTo(tox, toy);
  ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 7), toy - headlen * Math.sin(angle - Math.PI / 7));

  //draws the paths created above
  ctx.strokeStyle = colourarrow;
  ctx.lineWidth = 20;
  ctx.stroke();
  ctx.fillStyle = colourarrow
  ctx.fill();
}

function clearcanvas1(canvastoclear) {
  var canvas = document.getElementById(canvastoclear),
    ctx = canvas.getContext("2d");
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}

try {
  var canvas = document.getElementById("myCanvas");
  canvas.width = innerWidth;
  canvas.height = innerHeight;
  var differentcolours = ['#FFA500', '#FFFF00', '#FF0000', '#0000FF', '#008000', '#EE82EE', '#40E0D0', '#FFFFFF'];
  var angles = createArrowAngle();

  //draw an arrow after 1 second
  drawArrow(angles[0], angles[1], angles[2], angles[3], differentcolours[7]);
  //clear canvas after 1 second --> this works
  setTimeout(function() {
    clearcanvas1("myCanvas")
  }, 1000);
  //draw a circle after 4 seconds --> this works
  setTimeout(function() {
    drawCircle(differentcolours[7])
  }, 4000);
  //clear canvas after 1 second --> this doesn't work
  setTimeout(function() {
    clearcanvas1("myCanvas")
  }, 1000);

} catch (err) {
  document.getElementById("demo").innerHTML = err.message;
}
* {
  margin: 0;
  padding: 0;
}

body,
html {
  height: 100%;
}

#myCanvas {
  position: absolute;
  width: 100%;
  height: 100%;
}
<body bgcolor='black'>
  <canvas id="myCanvas" oncl></canvas>
  <p id="demo" style="color: white" oncl></p>
</body>

最佳答案

问题是您假设 setTimeout 将等待函数执行,但事实并非如此,

//draw an arrow after 1 second
drawArrow(angles[0],angles[1],angles[2],angles[3],differentcolours[7]);  
//clear canvas after 1 second --> this works
setTimeout(function(){clearcanvas1("myCanvas")},1000);
//draw a circle after 4 seconds --> this works
setTimeout(function(){drawCircle(differentcolours[7])},4000);
//clear canvas after 1 second --> this doesn't work
setTimeout(function(){clearcanvas1("myCanvas")},1000);

您希望绘制箭头,然后在 1 秒后清除 Canvas ,然后在 4 秒后绘制圆圈,然后在 1 秒后清除 Canvas ,发生的情况是,它绘制了箭头,然后1 秒后它会清除 Canvas 两次,3 秒后它会绘制圆圈。 我会将最后一个超时更改为 5000,您将获得假定的功能

//draw an arrow after 1 second
drawArrow(angles[0],angles[1],angles[2],angles[3],differentcolours[7]);  
//clear canvas after 1 second --> this works
setTimeout(function(){clearcanvas1("myCanvas")},1000);
//draw a circle after 4 seconds --> this works
setTimeout(function(){drawCircle(differentcolours[7])},4000);
//clear canvas after 1 second --> this doesn't work
setTimeout(function(){clearcanvas1("myCanvas")},5000);

您可以在这里看到它的实际效果

          function generateRandomNumber() {
          var minangle = 0;
          var maxangle = 2*Math.PI;
          randangle = Math.random() * (maxangle- minangle) + minangle;
              return randangle;
          };         


            function createArrowAngle() {
              var currentangle=generateRandomNumber();
              var canvas = document.getElementById('myCanvas');
              var context = canvas.getContext('2d');
              var centerX = canvas.width / 2;
              var centerY = canvas.height / 2;
              var x1=centerX+50*Math.cos(currentangle);
              var y1=centerY+50*Math.sin(currentangle);
              var x2=centerX+50*Math.cos(currentangle+Math.PI);
              var y2=centerY+50*Math.sin(currentangle+Math.PI);
              return [x1, y1, x2, y2]
          }

         function drawCircle(circleColour) {
          var canvas = document.getElementById('myCanvas');
          var context = canvas.getContext('2d');
          var centerX = canvas.width / 2;
          var centerY = canvas.height / 2;
          var radius = 20;

          context.beginPath();
          context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
          context.fillStyle = circleColour;
          context.fill();
          context.lineWidth = 20;
          context.strokeStyle = circleColour;
          context.stroke();
               }

               function drawArrow(fromx, fromy, tox, toy, colourarrow){
                    //variables to be used when creating the arrow
                    var c = document.getElementById("myCanvas");
                    var ctx = c.getContext("2d");
                    var headlen = 3;

                    var angle = Math.atan2(toy-fromy,tox-fromx);

                    //starting path of the arrow from the start square to the end square and drawing the stroke
                    ctx.beginPath();
                    ctx.moveTo(fromx, fromy);
                    ctx.lineTo(tox, toy);
                    ctx.strokeStyle = colourarrow;
                    ctx.lineWidth = 20;
                    ctx.stroke();

                    //starting a new path from the head of the arrow to one of the sides of the point
                    ctx.beginPath();
                    ctx.moveTo(tox, toy);
                    ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));

                    //path from the side point of the arrow, to the other side point
                    ctx.lineTo(tox-headlen*Math.cos(angle+Math.PI/7),toy-headlen*Math.sin(angle+Math.PI/7));

                    //path from the side point back to the tip of the arrow, and then again to the opposite side point
                    ctx.lineTo(tox, toy);
                    ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));

                    //draws the paths created above
                    ctx.strokeStyle = colourarrow;
                    ctx.lineWidth = 20;
                    ctx.stroke();
                    ctx.fillStyle = colourarrow
                    ctx.fill();
                }

                         function clearcanvas1(canvastoclear)
         {
         var canvas = document.getElementById(canvastoclear),
            ctx = canvas.getContext("2d");
         ctx.clearRect(0, 0, canvas.width, canvas.height);
         }
         
         try {
         var canvas = document.getElementById("myCanvas");
         canvas.width = innerWidth;
         canvas.height = innerHeight;
         var differentcolours = ['#FFA500','#FFFF00','#FF0000','#0000FF','#008000','#EE82EE','#40E0D0','#FFFFFF'];
         var angles=createArrowAngle();

    //draw an arrow after 1 second
         drawArrow(angles[0],angles[1],angles[2],angles[3],differentcolours[7]);  
    //clear canvas after 1 second --> this works
         setTimeout(function(){clearcanvas1("myCanvas")},1000);
    //draw a circle after 4 seconds --> this works
         setTimeout(function(){drawCircle(differentcolours[7])},4000);
    //clear canvas after 1 second --> this doesn't work
         setTimeout(function(){clearcanvas1("myCanvas")},5000);

                 }
         catch(err) {
             document.getElementById("demo").innerHTML = err.message;
         }
         * { margin: 0; padding: 0;}
         body, html { height:100%; }
         #myCanvas {
         position:absolute;
         width:100%;
         height:100%;
         }
<!DOCTYPE html>
<html>
   <head>
      <title>Test</title>
   </head>
   <body bgcolor='black'>
      <canvas  id="myCanvas" oncl></canvas>
            <p  id="demo" style="color: white" oncl></p>
          
   </body>
</html>

关于javascript - 清除 Canvas 仅工作一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47851654/

相关文章:

javascript - 尝试理解 Backbone 继承和特化

javascript - Bootstrap 与 Masonry

javascript - 注册 Controller 和服务 Angular JS?

html - 打印一页

security - 使用 POST 而不是 GET 更安全吗?

javascript - 我怎样才能创建一个阴影效果完全沿 Canvas 的顶部以外的所有侧面运行?

html - 如何将两个 Canvas 元素放在彼此之上?

javascript - 如何确定滚动浏览器窗口底部是否已到达 DIV 顶部?

jquery - jQuery分别用类计算div的长度

javascript - Canvas lineTo() 在错误的位置绘制 y 坐标