Javascript 使用网格中的坐标绘制二维对象
我有两个函数,第一个函数绘制一个带线条的空网格(28x16),第二个函数绘制一个方形框,用颜色填充选定的网格位置,每个框为25X25。第二个函数允许我使用网格位置在画布的任意位置绘制一个方框。因此,为了绘制长方体,我创建了另一个调用网格位置的函数,并将其绘制在那里,例如,为了在网格位置绘制长方体,其中x=5和y=4,必须输入Javascript 使用网格中的坐标绘制二维对象,javascript,html,canvas,Javascript,Html,Canvas,我有两个函数,第一个函数绘制一个带线条的空网格(28x16),第二个函数绘制一个方形框,用颜色填充选定的网格位置,每个框为25X25。第二个函数允许我使用网格位置在画布的任意位置绘制一个方框。因此,为了绘制长方体,我创建了另一个调用网格位置的函数,并将其绘制在那里,例如,为了在网格位置绘制长方体,其中x=5和y=4,必须输入drawWalls(5,4)这条线可以一次又一次地用于绘制不同的方框,因此我可以绘制方框,函数工作得非常完美,现在我想同时创建多个方形方框(例如一行方框),问题是,我从未创建
drawWalls(5,4)代码>这条线可以一次又一次地用于绘制不同的方框,因此我可以绘制方框,函数工作得非常完美,现在我想同时创建多个方形方框(例如一行方框),问题是,我从未创建过这样的循环或多个变量的循环,请帮助,另外,我对数组有点困惑,我想知道这些框是否存储在数组中,我如何再次调用它们,例如,我单击一个框,它被删除,这并不重要,但如果您对第一个问题有任何想法,请帮助,谢谢您的时间
绘制网格
function drawGrid() {
ctxBg.beginPath();
for (var i = 0; i <= canvasWidth-25; i+= 25) {
ctxBg.moveTo(-25 + i,55);
ctxBg.lineTo(-25 + i, canvasHeight - 55);
}
for (var i = 25; i <= canvasHeight -75; i+= 25) {
ctxBg.moveTo(55,25 + i);
ctxBg.lineTo(canvasWidth-55, 25 + i);
}
ctxBg.stroke();
}
function ClearBg() {
ctxBg.clearRect(0,0,canvasWidth,canvasHeight);
}
函数drawGrid(){
ctxBg.beginPath();
对于(var i=0;i将墙的定义放在javascript对象中,并将这些墙对象存储在数组中。然后根据需要使用数组绘制墙
每个墙对象都包含绘制一面墙所需的信息:
var walls=[
{direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'},
{direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'}
];
var cellSize=25;
function drawAllWalls(walls){
for(var i=0;i<walls.length;i++){
var w=walls[i];
ctxWall.fillStyle=w.fill;
if(w.direction=='horizontal'){
for(var x=w.startX;x<=w.endX;x++){
ctxWall.fillRect(x*cellSize,w.Y*cellSize,cellSize,cellSize)
}
}else{
for(var y=w.startY;y<=w.endY;y++){
ctxWall.fillRect(w.X*cellSize,y*cellSize,cellSize,cellSize)
}
}
}
}
然后您可以在阵列中循环并基于每个墙对象绘制每面墙:
var walls=[
{direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'},
{direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'}
];
var cellSize=25;
function drawAllWalls(walls){
for(var i=0;i<walls.length;i++){
var w=walls[i];
ctxWall.fillStyle=w.fill;
if(w.direction=='horizontal'){
for(var x=w.startX;x<=w.endX;x++){
ctxWall.fillRect(x*cellSize,w.Y*cellSize,cellSize,cellSize)
}
}else{
for(var y=w.startY;y<=w.endY;y++){
ctxWall.fillRect(w.X*cellSize,y*cellSize,cellSize,cellSize)
}
}
}
}
将墙的定义放在javascript对象中,并将这些墙对象存储在数组中。然后根据需要使用数组绘制墙
每个墙对象都包含绘制一面墙所需的信息:
var walls=[
{direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'},
{direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'}
];
var cellSize=25;
function drawAllWalls(walls){
for(var i=0;i<walls.length;i++){
var w=walls[i];
ctxWall.fillStyle=w.fill;
if(w.direction=='horizontal'){
for(var x=w.startX;x<=w.endX;x++){
ctxWall.fillRect(x*cellSize,w.Y*cellSize,cellSize,cellSize)
}
}else{
for(var y=w.startY;y<=w.endY;y++){
ctxWall.fillRect(w.X*cellSize,y*cellSize,cellSize,cellSize)
}
}
}
}
然后您可以在阵列中循环并基于每个墙对象绘制每面墙:
var walls=[
{direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'},
{direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'}
];
var cellSize=25;
function drawAllWalls(walls){
for(var i=0;i<walls.length;i++){
var w=walls[i];
ctxWall.fillStyle=w.fill;
if(w.direction=='horizontal'){
for(var x=w.startX;x<=w.endX;x++){
ctxWall.fillRect(x*cellSize,w.Y*cellSize,cellSize,cellSize)
}
}else{
for(var y=w.startY;y<=w.endY;y++){
ctxWall.fillRect(w.X*cellSize,y*cellSize,cellSize,cellSize)
}
}
}
}
这是一件有趣的事情:
要获取任何“框/单元”坐标,您只需执行以下操作:
获取点击的x位置,将其除以一个框的大小,这样您就知道了
你在哪一个盒子里?把它四舍五入到下一个整数,哪个
表示您所在的方框。然后乘以方框中的数字
尺寸。这给你盒子的右边缘
对y重复此操作以获得底部边缘
要得到顶部和左侧,只需从边上减去大小
var can = getById('can'),
boxes = 20,
size = 20,
ctx = can.getContext('2d'),
clearBtn = getById('clearBtn');
drawGrid();
function drawGrid() {
var len = can.height = can.width = boxes * size;
for (var i = 0; i < boxes; i++) {
ctx.beginPath();
ctx.moveTo(size + size * i - .5, 0);
ctx.lineTo(size + size * i - .5, len);
ctx.moveTo(0, size + size * i - .5);
ctx.lineTo(len, size + size * i - .5);
ctx.stroke();
}
}
can.addEventListener('mousemove', function (evt) {
var mousePos = getMousePos(can, evt);
var sx = (Math.ceil(mousePos.x/size)-1)*size,
sy = (Math.ceil(mousePos.y/size)-1)*size;
console.log(sx,sy,sx+size,sy+size);
ctx.fillRect(sx,sy,size,size);
}, false);
clearBtn.addEventListener('click', function (evt) {
ctx.clearRect(0,0,can.width,can.height);
drawGrid();
});
function getMousePos(canvas, evt) {
var rect = can.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function getById(x) {
return document.getElementById(x);
}
var can=getById('can'),
盒子=20,
尺寸=20,
ctx=can.getContext('2d'),
clearBtn=getById('clearBtn');
drawGrid();
函数drawGrid(){
var len=can.height=can.WITH=BOX*尺寸;
对于(变量i=0;i
这是一件有趣的事情:
要获取任何“框/单元”坐标,您只需执行以下操作:
获取点击的x位置,将其除以一个框的大小,这样您就知道了
你在哪一个盒子里?把它四舍五入到下一个整数,哪个
表示您所在的方框。然后乘以方框中的数字
尺寸。这给你盒子的右边缘
对y重复此操作以获得底部边缘
要得到顶部和左侧,只需从边上减去大小
var can = getById('can'),
boxes = 20,
size = 20,
ctx = can.getContext('2d'),
clearBtn = getById('clearBtn');
drawGrid();
function drawGrid() {
var len = can.height = can.width = boxes * size;
for (var i = 0; i < boxes; i++) {
ctx.beginPath();
ctx.moveTo(size + size * i - .5, 0);
ctx.lineTo(size + size * i - .5, len);
ctx.moveTo(0, size + size * i - .5);
ctx.lineTo(len, size + size * i - .5);
ctx.stroke();
}
}
can.addEventListener('mousemove', function (evt) {
var mousePos = getMousePos(can, evt);
var sx = (Math.ceil(mousePos.x/size)-1)*size,
sy = (Math.ceil(mousePos.y/size)-1)*size;
console.log(sx,sy,sx+size,sy+size);
ctx.fillRect(sx,sy,size,size);
}, false);
clearBtn.addEventListener('click', function (evt) {
ctx.clearRect(0,0,can.width,can.height);
drawGrid();
});
function getMousePos(canvas, evt) {
var rect = can.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function getById(x) {
return document.getElementById(x);
}
var can=getById('can'),
盒子=20,
尺寸=20,
ctx=can.getContext('2d'),
clearBtn=getById('clearBtn');
drawGrid();
函数drawGrid(){
var len=can.height=can.WITH=BOX*尺寸;
对于(变量i=0;i
显示您的实际代码。您应该显示一些现有代码。关于单击方框,画布不支持您绘制的任何内容上的事件,实现这一点的唯一方法是存储可单击对象的边界,捕获画布上的单击,并在所有边界之间循环,直到在其中找到一个。SVG可以将每个形状保持为ob对象并响应事件。我将看一看SVG,谢谢您展示您的实际代码。您应该展示一些现有代码。关于单击框,画布不支持您绘制的任何对象上的事件,实现这一点的唯一方法是存储可单击对象的边界,捕获画布上的单击,并循环所有边界SVG可以将每个形状保持为一个对象并响应事件