让绘图留在 canvas
getting the drawing to stay on canvas
我在 canvas 上画了一个图,并用按钮将其上下左右移动。但是我在考虑如何让绘图不通过 canvas 的边界时遇到问题,如果我点击方向按钮太多的话。我的 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();
}
如果你想阻止它越过边界,你需要得到一些随着翻译而改变的x,y
变量。
例如,只要有 translate( 0, 5 )
,就应该在它前面加上 x += 0; y += 5
。这样你就可以检查 x
和 y
是否在边界之外,并防止在翻译之前发生任何事情:
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 语句中的所有边界:
向上:y - 5 <= 0
左:x - 5 <= 0
向下:y + 5 >= canvas5.height
右:x + 5 >= canvas5.width
您必须在某些变量中保持当前位置(例如 x
和 y
)。
然后,不是使用 translate
增加当前变换矩阵,而是使用 setTransform
方法。这将使我们能够避免经常使用不当的 save
方法,并在每次绘制新图时轻松清除 canvas。
那么,你已经有了drawObject
方法,就用吧
为了避免撞墙,您只需要在修改 x
和 y
值时检查您是否超出范围(请注意,您还必须考虑执行此检查时的图纸尺寸)
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>
我在 canvas 上画了一个图,并用按钮将其上下左右移动。但是我在考虑如何让绘图不通过 canvas 的边界时遇到问题,如果我点击方向按钮太多的话。我的 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();
}
如果你想阻止它越过边界,你需要得到一些随着翻译而改变的x,y
变量。
例如,只要有 translate( 0, 5 )
,就应该在它前面加上 x += 0; y += 5
。这样你就可以检查 x
和 y
是否在边界之外,并防止在翻译之前发生任何事情:
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 语句中的所有边界:
向上:y - 5 <= 0
左:x - 5 <= 0
向下:y + 5 >= canvas5.height
右:x + 5 >= canvas5.width
您必须在某些变量中保持当前位置(例如 x
和 y
)。
然后,不是使用 translate
增加当前变换矩阵,而是使用 setTransform
方法。这将使我们能够避免经常使用不当的 save
方法,并在每次绘制新图时轻松清除 canvas。
那么,你已经有了drawObject
方法,就用吧
为了避免撞墙,您只需要在修改 x
和 y
值时检查您是否超出范围(请注意,您还必须考虑执行此检查时的图纸尺寸)
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>