让绘图留在画布上

时间:2016-11-03 07:43:40

标签: javascript html5 canvas

我在画布和按钮上绘制了一个向上,向下,向左和向右移动的图形。但是,如果我单击方向按钮太多,我在试图考虑如何让绘图不通过画布的边框时遇到问题。我的画布是500 x 500。

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

function drawObject(ctx, x, y) {
ctx.save();
ctx.beginPath(); //Head of ship
ctx.translate(x, y);
ctx.lineTo(0, 0); //starting point
ctx.lineTo(0, 10); // left of head
ctx.lineTo(15, 20); //connecting left to bottom
ctx.lineTo(50, 20); // bottom of head
ctx.lineTo(65, 10); // connecting bottom to right
ctx.lineTo(65, 0); //line on far right 
ctx.lineTo(50, -10); //top of head
ctx.lineTo(15, -10); //connecting top to left
ctx.lineTo(0, 0);
ctx.stroke();
}
drawObject(ctx, 200, 225);

function up() {
var canvas2 = document.getElementById("myCanvas");
ctx.beginPath(); //Head of ship
ctx.clearRect(-10, -15, 500, 500);
ctx.translate(0, -40);
ctx.lineTo(0, 0); //starting point
ctx.lineTo(0, 10); // left of head
ctx.lineTo(15, 20); //connecting left to bottom
ctx.lineTo(50, 20); // bottom of head
ctx.lineTo(65, 10); // connecting bottom to right
ctx.lineTo(65, 0); //line on far right 
ctx.lineTo(50, -10); //top of head
ctx.lineTo(15, -10); //connecting top to left
ctx.lineTo(0, 0);
ctx.stroke();
}

function right() {
var canvas3 = document.getElementById("myCanvas");
ctx.beginPath();
ctx.clearRect(-10, -15, 500, 500);
ctx.translate(5, 0);
ctx.lineTo(0, 0); //starting point
ctx.lineTo(0, 10); // left of head
ctx.lineTo(15, 20); //connecting left to bottom
ctx.lineTo(50, 20); // bottom of head
ctx.lineTo(65, 10); // connecting bottom to right
ctx.lineTo(65, 0); //line on far right 
ctx.lineTo(50, -10); //top of head
ctx.lineTo(15, -10); //connecting top to left
ctx.lineTo(0, 0);
ctx.stroke();
}

function down() {
var canvas4 = document.getElementById("myCanvas");
ctx.beginPath();
ctx.clearRect(-10, -15, 500, 500);
ctx.translate(0, 5);
ctx.lineTo(0, 0); //starting point
ctx.lineTo(0, 10); // left of head
ctx.lineTo(15, 20); //connecting left to bottom
ctx.lineTo(50, 20); // bottom of head
ctx.lineTo(65, 10); // connecting bottom to right
ctx.lineTo(65, 0); //line on far right 
ctx.lineTo(50, -10); //top of head
ctx.lineTo(15, -10); //connecting top to left
ctx.lineTo(0, 0);
ctx.stroke();
}

function left() {
var canvas5 = document.getElementById("myCanvas");
ctx.beginPath();
ctx.clearRect(-10, -15, 500, 500);
ctx.translate(-5, 0);
ctx.lineTo(0, 0); //starting point
ctx.lineTo(0, 10); // left of head
ctx.lineTo(15, 20); //connecting left to bottom
ctx.lineTo(50, 20); // bottom of head
ctx.lineTo(65, 10); // connecting bottom to right
ctx.lineTo(65, 0); //line on far right 
ctx.lineTo(50, -10); //top of head
ctx.lineTo(15, -10); //connecting top to left
ctx.lineTo(0, 0);
ctx.stroke();
}

function reset() {
var canvas5 = document.getElementById("myCanvas");
ctx.beginPath();
ctx.clearRect(-10, -15, 500, 500);
ctx.restore();
ctx.save();
ctx.translate(200, 225);
ctx.lineTo(0, 0); //starting point
ctx.lineTo(0, 10); // left of head
ctx.lineTo(15, 20); //connecting left to bottom
ctx.lineTo(50, 20); // bottom of head
ctx.lineTo(65, 10); // connecting bottom to right
ctx.lineTo(65, 0); //line on far right 
ctx.lineTo(50, -10); //top of head
ctx.lineTo(15, -10); //connecting top to left
ctx.lineTo(0, 0);
ctx.stroke();
}

2 个答案:

答案 0 :(得分:2)

如果你想阻止它越过边界,你需要获得一些随着翻译而变化的x,y变量。

例如,只要您拥有translate( 0, 5 ),就应该有x += 0; y += 5。这样,您可以检查xy是否超出边界,并防止在翻译之前发生任何事情:

function left(){
    ...
    if( x - 5 <= 0 )
        return false
    x -= 5;
    // having y += 0 is redundant, but you can add it for readability purposes
    translate( -5, 0 )
    ...
}

对于其余的方向函数,您需要检查if语句中的所有边界:

up:y - 5 <= 0

左:x - 5 <= 0

向下:y + 5 >= canvas5.height

右:x + 5 >= canvas5.width

答案 1 :(得分:1)

您必须将当前位置保留在某些变量中(例如xy)。 然后,使用setTransform方法,而不是使用translate递增当前变换矩阵。这将允许我们避免使用常用的save方法,并在每个新绘图时轻松清除画布。

然后,您已经有drawObject方法,只需使用它。

为避免隔离墙,您只需在修改xy值时检查自己是否超出范围(请注意,您还必须考虑到您的图纸执行此检查时的尺寸)

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var defaultX, defaultY; // used in the reset function
var x = defaultX = 200;
var y = defaultY = 125;

function drawObject(ctx, x, y) {
  // reset the current transform so we can clear the canvas
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  // set the current transform to our actual position
  ctx.setTransform(1, 0, 0, 1, x, y);
  // draw our ship
  ctx.beginPath(); //Head of ship
  ctx.lineTo(0, 0); //starting point
  ctx.lineTo(0, 10); // left of head
  ctx.lineTo(15, 20); //connecting left to bottom
  ctx.lineTo(50, 20); // bottom of head
  ctx.lineTo(65, 10); // connecting bottom to right
  ctx.lineTo(65, 0); //line on far right 
  ctx.lineTo(50, -10); //top of head
  ctx.lineTo(15, -10); //connecting top to left
  ctx.lineTo(0, 0);
  ctx.stroke();
}
drawObject(ctx, x, y);

function up() {
  y -= 5;
  // we gone too far, stop it.
  // -10 is your ship top position
  if (y < 10) {
    y = 10;
  }
  drawObject(ctx, x, y);
}

function right() {
  x += 5;
  // 65 is your ship width
  if (x > canvas.width - 65) {
    x = canvas.width - 65;
  }
  drawObject(ctx, x, y);

}

function down() {
  y += 5;
  // 20 is your ship height
  if (y > canvas.height - 20) {
    y = canvas.height - 20;
  }
  drawObject(ctx, x, y);
}

function left() {
  x -= 5;
  if (x < 0) {
    x = 0;
  }
  drawObject(ctx, x, y);

}

function reset() {
    x = defaultX;
    y = defaultY;
    drawObject(ctx, x, y);
  }
  // replacing your buttons with key events (arrows)
window.onkeydown = function(event) {
  switch (event.keyCode) {
    // left
    case 37:
      event.preventDefault();
      left();
      break;

      // up
    case 38:
      event.preventDefault();
      up();
      break;

      // right
    case 39:
      event.preventDefault();
      right();
      break;

      //down
    case 40:
      event.preventDefault();
      down();
      break;
  }
}
document.getElementById('reset').onclick = reset;
button {
  vertical-align: top;
}
canvas {
  border: 1px solid;
}
<canvas id="myCanvas" width="400" height="200"></canvas>
<button id="reset">
  reset
</button>