2015-06-12 95 views
1

我有2個函數,第一個函數繪製一個內襯的空網格(28x16),第二個函數繪製一個方框,用一種顏色填充選定的網格位置,每個方框爲25X25 。第二個函數允許我使用網格位置在畫布中的任意位置繪製一個框。因此,繪製一個盒子,我創建了另一個調用網格位置並在那裏繪製的函數,例如在x = 5和y = 4的網格位置繪製一個盒子,必須輸入此行。drawWalls(5,4);此行可以再次使用並再次繪製不同的框,所以我可以繪製框和功能完美的工作,現在我想同時創建超過1個方框(例如一行框),問題是,我從來沒有創建一個像這樣的循環或者一個有多於一個變量的循環,請大家幫忙,我也對數組感到困惑,我想知道這些數組是否存儲在一個數組中,我怎樣才能再次調用它們,比如說我點擊一個框,它會被刪除,這並不重要,但如果您對第一個問題有任何想法,請幫助,感謝您的時間。使用網格中的座標繪製2D對象JavaScript

繪製網格

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); 
}  

繪製

function Wall(row, col) { 
    this.row = row; 
    this.col = col; 
    this.color = "#000"; 

    this.width = 25 
    this.height = 25 
    this.leftX = this.row; 
    this.rightX = this.row + this.width; 
    this.topY = this.col; 
    this.bottomY = this.col + this.height; 
} 
function drawWalls(x,y) { 
    walls.push(new Wall(x, y)); 

    for (var b = 0; b < walls.length; b++) { 
    ctxWall.fillStyle = walls[b].color; 
    ctxWall.fillRect(walls[b].row * gridSize, walls[b].col * gridSize, walls[b].width, walls[b].height); 
    } 
} 

function createWalls() { 
    drawWalls(9,9); 
    drawWalls(8,8); 
    drawWalls(7,7); 
} 

我試圖使功能createWalls在循環中繪製它們放在一起,不幸的是我還沒有創建的鼠標點擊在牆上事件,但我會很快

+0

顯示您的實際代碼。 – alex

+0

您應該顯示一些現有的代碼。關於單擊框,畫布不支持繪製任何東西上的事件,唯一的方法是存儲可點擊對象的邊界,捕獲畫布上的點擊,並遍歷所有邊界,直到找到其中一個邊界爲止。 SVG可以將每個形狀保持爲一個對象並響應事件。 –

+0

我會看看SVG,謝謝 – Dalomo

回答

3

把你牆的定義放在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) 
      } 
     } 
    } 
} 

如果您稍後想要刪除特定牆,您可以:

  • 從牆壁陣列中刪除該牆。
  • 清除畫布,
  • 重新繪製數組中所有剩餘的牆(刪除的牆不會被重繪)。

如果你日後想從牆上刪除僅1中,您可以:

  • 刪除牆從牆上陣列。
  • 加回仍然存在的牆壁陣列壁的部分(S),
  • 清除畫布,
  • 重繪所有牆壁陣列(刪除框不會重繪)英寸

這裏的示例代碼和演示:

enter image description here

var canvas=document.getElementById("canvas"); 
 
var ctxBg=canvas.getContext("2d"); 
 
var ctxWall=canvas.getContext("2d"); 
 
var canvasWidth=canvas.width; 
 
var canvasHeight=canvas.height; 
 

 
var colCount=8; 
 
var rowCount=8; 
 
var cellSize=25; 
 

 
var walls=[ 
 
    {direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'}, 
 
    {direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'} 
 
]; 
 

 
drawGrid(); 
 
drawAllWalls(walls); 
 

 
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) 
 
     } 
 
    } 
 
    } 
 
} 
 

 
function drawGrid(){ 
 
    ctxBg.beginPath(); 
 
    for(var x=0;x<colCount+1;x++){ 
 
    ctxBg.moveTo(x*cellSize,0); 
 
    ctxBg.lineTo(x*cellSize,rowCount*cellSize); 
 
    } 
 
    for(var y=0;y<rowCount+1;y++){ 
 
    ctxBg.moveTo(0,y*cellSize,0); 
 
    ctxBg.lineTo(colCount*cellSize,y*cellSize); 
 
    } 
 
    ctxBg.stroke(); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

+1

謝謝,這確實有助於很多:) – Dalomo

4

這是一個有趣的事情:http://jsfiddle.net/techsin/rcjouqkf/

要得到任何「盒/細胞」協調所有你需要做的是這樣的:通過一個盒子的大小,所以你知道

  • 哪個箱子你在一輪點擊鴻溝它的

    1. GET x位置它到下一個整數,其中
    2. 代表你所在的盒子。然後用方框 大小乘以該數字。這會讓你重複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); 
      } 
      
  • +1

    Upvote for simple code。 :-)你可以將sx,sy和fillRect隔離到一個單獨的函數中,這樣提問者也可以通過編程方式繪製牆。 – markE

    +0

    哈哈,真是太棒了,謝謝 – Dalomo