首页 > 解决方案 > 为什么画线没有从画布上清除?

问题描述

链接到 JSFiddle 以获取整个代码:https ://jsfiddle.net/u4mk0gdt/

我阅读了关于 save() 和 restore() 的 Mozilla 文档,我认为“保存”保存了整个画布的当前状态,“恢复”将画布恢复到最近的“保存”状态。因此,我以这样一种方式放置了保存和恢复,它应该清除在绘制后绘制到画布上的白线。但是,当我运行此代码时,白线永远不会从画布上清除,并且会在不清除的情况下连续绘制。

ctx.restore();
ctx.save(); // <--should save blank canvas

//DRAW LINE
ctx.moveTo(tMatrix.x1, tMatrix.y1);
ctx.lineTo(w/2,h/2);
ctx.strokeStyle = "white";
ctx.stroke();
ctx.restore(); // <-- should restore to the "save()" above
ctx.save(); // <-- <--should save blank canvas again

标签: javascriptcanvashtml5-canvas

解决方案


如您所见,我对您的代码进行了很多修改:

console.log("rotating_recs");
// create canvas and add resize
var canvas, ctx;

function createCanvas() {
  canvas = document.createElement("canvas");
  canvas.style.position = "absolute";
  canvas.style.left = "0px";
  canvas.style.top = "0px";
  canvas.style.zIndex = 1000;
  document.body.appendChild(canvas);
}

function resizeCanvas() {
  if (canvas === undefined) {
    createCanvas();
  }
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  ctx = canvas.getContext("2d");
}

resizeCanvas();
window.addEventListener("resize", resizeCanvas);



var Player = function(x, y, height, width, rot) {
  this.x = x;
  this.y = y;
  this.width = width;
  this.height = height;
  this.rot = rot;
  this.objWinX = 0; //translate the window object and then apply to this
  this.objWinY = 0;

  this.draw = function() {

    //rotate by user.rot degrees, from the players center
    ctx.translate(this.x + this.width / 2, this.y + this.height / 2)
    ctx.rotate(this.rot * Math.PI / 180)
    ctx.translate(-this.x - this.width / 2, -this.y - this.height / 2)

    ctx.fillStyle = "grey";
    ctx.fillRect(this.x, this.y, this.height, this.width);

    ctx.translate(this.x + this.width / 2, this.y + this.height / 2)
    ctx.rotate(-this.rot * Math.PI / 180)
    ctx.translate(-this.x - this.width / 2, -this.y - this.height / 2)
  }
}

var user = new Player(0, 0, 40, 40, 0);

var user2 = new Player(0, 0, 40, 40, 0);

let rot = 0;


function update(time) {

  var w, h;
  w = canvas.width; // get canvas size incase there has been a resize
  h = canvas.height;
  ctx.clearRect(0, 0, w, h); // clear the canvas

  //MIDDLE RECT
  /*
  if you don't want this you can just translate by w/2 and h/2, but I would recommend just making the p     layers position the middle
  */

  user.x = w / 2 - 20;
  user.y = h / 2 - 20;

  user.rot += 0.5 // or whatever speed
  user.draw(); //draw player -- look at the draw function I added some stuff

  //LINE
  /*
  I don't know what you are trying to do, but I just drew the line to the user2's position,
  if this doesn't work for your scenario you can change it back
  */
  ctx.beginPath()
  ctx.moveTo(user2.x + user2.width/2, user2.y + user2.height/2);
  ctx.lineTo(w / 2, h / 2);
  ctx.strokeStyle = "white";
  ctx.stroke();

  //FAST SPIN RECT

  /*
  There are multiple ways to do this, the one that I think you should do, is actually change the position of user two, this uses some very simple trigonometry, if you know this, this is a great way to do this, if not, you can do it how you did previously, and just translate to the center, rotate, and translate back. Similar to what I did with the player draw function. I am going to demonstrate the trig way here:
  */
  user2.rot += 5
  rot += 2;
  
  user2.x = w/2 + (w/2) * Math.cos(rot * (Math.PI/180))
  user2.y = h/2 + (w/2) * Math.sin(rot * (Math.PI/180))
  user2.draw();

  //RED RECT
  ctx.fillStyle = 'red';
  ctx.fillRect(140, 60, 40, 40);

  requestAnimationFrame(update); // do it all again
}
requestAnimationFrame(update);

虽然我认为您应该将其中一些修改添加到您的代码中,但它们并不是非常必要的。要解决线条问题,您只需在绘制之前添加 ctx.beginPath() 即可。我做的演示不是很好(因此是演示),你可能不应该完全使用它,但一定要看看它。为您绘制线条的修改后的代码如下所示:

    //LINE
    ctx.beginPath()
    ctx.moveTo(tMatrix.x1, tMatrix.y1);
    ctx.lineTo(w/2,h/2);
    ctx.strokeStyle = "white";
    ctx.stroke();
    ctx.restore();
    ctx.save();

希望这会有所帮助:D

抱歉拼写错误


推荐阅读