【问题标题】:Why is the drawn line not clearing from canvas?为什么画线没有从画布上清除?
【发布时间】:2023-04-04 00:20:02
【问题描述】:

完整代码的 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

【问题讨论】:

  • "通过将当前状态压入堆栈来保存画布的整个状态。保存到堆栈中的绘图状态包括:当前变换矩阵. 当前剪辑区域。当前短划线列表。当前以下属性的值strokeStylefillStyleglobalAlphalineWidthlineCaplineJoinmiterLimitlineDashOffsetshadowOffsetXshadowOffsetYshadowBlurshadowColorglobalCompositeOperationfonttextAligntextBaselinedirectionimageSmoothingEnabled"
  • save 不存储画布内容,仅存储画布属性。

标签: javascript canvas html5-canvas


【解决方案1】:

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

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

抱歉,拼写错误

【讨论】:

    猜你喜欢
    • 2012-07-19
    • 2016-07-05
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 2014-01-02
    • 2017-06-21
    相关资源
    最近更新 更多