Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用网格中的坐标绘制二维对象_Javascript_Html_Canvas - Fatal编程技术网

Javascript 使用网格中的坐标绘制二维对象

Javascript 使用网格中的坐标绘制二维对象,javascript,html,canvas,Javascript,Html,Canvas,我有两个函数,第一个函数绘制一个带线条的空网格(28x16),第二个函数绘制一个方形框,用颜色填充选定的网格位置,每个框为25X25。第二个函数允许我使用网格位置在画布的任意位置绘制一个方框。因此,为了绘制长方体,我创建了另一个调用网格位置的函数,并将其绘制在那里,例如,为了在网格位置绘制长方体,其中x=5和y=4,必须输入drawWalls(5,4)这条线可以一次又一次地用于绘制不同的方框,因此我可以绘制方框,函数工作得非常完美,现在我想同时创建多个方形方框(例如一行方框),问题是,我从未创建

我有两个函数,第一个函数绘制一个带线条的空网格(28x16),第二个函数绘制一个方形框,用颜色填充选定的网格位置,每个框为25X25。第二个函数允许我使用网格位置在画布的任意位置绘制一个方框。因此,为了绘制长方体,我创建了另一个调用网格位置的函数,并将其绘制在那里,例如,为了在网格位置绘制长方体,其中x=5和y=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可以将每个形状保持为一个对象并响应事件