Hay una cuadrícula rectangular que será de tamaño 12 por 12, en la que cada esquina se puede hacer clic, que son 6 * 3 células de cada esquina de 12 * 12 Grid (solo haga clic en las 4 esquinas, deben seleccionar 6 * 3 células ).

Tengo una matriz multidimensional creada de tamaño 12 * 12, que se representará por 0. y dependiendo del usuario de la esquina elige que las células 6 * 3 correspondientes se convertirán en 1. ¿Cómo mostrar este concepto a través de la lona HTML? Así es como Represente esta matriz en forma de una cuadrícula, también quiero que la esquina de la cuadrícula seleccionara, es decir, esas células que se están convirtiendo en 1 para que se representen en un color diferente.

addBed = (x,y) => {let test = Array(12).fill(0).map(x => Array(12).fill(0));                    

  let bedX = 3, bedY = 6; // BED AREA = 6*3                                                     
  let dx = 1, dy = 1;                                                                           
  let endX = bedX, endY = bedY;                                                                 
  const roomX = 11, roomY = 11                                                                  
  if(x === roomX) {                                                                             
    dx = -1                                                                                     
    endX = roomX-bedX                                                                           
  }                                                                                             
  if (y === roomY) {                                                                            
    dy = -1                                                                                     
    endY = roomY-bedY                                                                           
  }                                                                                             
  for(let i = x; dx === 1 ? i < endX : i > endX; i += dx) {                                     
    for(let j = y; dy === 1 ? j < endY: j > endY; j += dy) {                                    
      test[i][j] = 1;                                                                           
    }                                                                                           
  }                                                                                             

  console.log(test)                                                                             
  // this.setState({ testMap: test });                                                          
}                                                                                               

addBed(0,0);        // this will make the first corner to be turned to 1
1
Asha 13 jul. 2019 a las 22:01

1 respuesta

La mejor respuesta

Así es como lo haría: usaría una matriz de células unidimensionales.

También crearía la matriz de las células seleccionables con el índice en la matriz de celdas y la corrección extendida correspondiente a dibujar en el clic.

Por favor lea los comentarios en mi código.

let ctx = room.getContext("2d");
let cw = room.width = 300;//the width of the canvas
let ch = room.height = 300;//the height of the canvas

let size = 25;//the size of every cell
let rows = 12;//number of rows
let cols = 12;//number of columns

// initiate the cells array
let cells = new Array(cols*rows);

// the clickable cells: the index in the cells array and the extended rect position (x,y) and size (w,h)
let clickble = [
  {index:0, rect:{x:0,y:0,w:size*3,h:size*6}},
  {index:11, rect:{x:300-size*3,y:0,w:size*3,h:size*6}},
  {index:12*11, rect:{x:0,y:300-size*6,w:size*3,h:size*6}},
  {index:12*12-1, rect:{x:300-size*3,y:300-size*6,w:size*3,h:size*6}}
]


// fill the cells array with values
 for (y = 0; y <= rows; y++) {
    for (x = 0; x < cols; x++) {
      let index = x + y * cols;
      let cell = {}
      cell.x = x*size;
      cell.y = y*size;
      
      cells[index] = cell;
    }
 }
//draw every cell in the grid of cells
cells.forEach((c,i)=>{
  ctx.beginPath();
  ctx.strokeRect(c.x,c.y,size,size);  
})


// mark the cells clickble
clickble.forEach(c=>{ctx.fillRect(cells[c.index].x,cells[c.index].y,size,size);})


// when clicking on the canvas
room.addEventListener("click",(evt)=>{
  //get the mouse position
  let m = oMousePos(room, evt);
  
  for(let i = 0; i < clickble.length; i++ ){
    let cell =  cells[clickble[i].index];
    
    ctx.beginPath();
    //get the extended rect
    ctx.rect(cell.x,cell.y,size,size);
    // if the click happened inside one of the clickable cells
    if (ctx.isPointInPath(m.x, m.y)){
      let rect =  clickble[i].rect;
      // draw the extended rect
      ctx.beginPath();
      ctx.fillStyle = "red";
      ctx.fillRect(rect.x,rect.y,rect.w,rect.h);
      //breack the loop. No need to search further
      break;}
    
  }
})



// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
	return { 
	x: Math.round(evt.clientX - ClientRect.left),
	y: Math.round(evt.clientY - ClientRect.top)
}
}
<canvas id="room"></canvas>

Actualizar

El OP está comentando:

Necesito todas las 4 esquinas, pero depende del usuario para elegir en qué esquina para hacer clic, después de hacer clic en una esquina, no podrá hacer clic en otra esquina.

En este caso al Código anterior, estoy agregando una variable global let clicked = false;: No se hizo clic en la esquina.

Cuando el usuario está haciendo clic en una esquina clicked = true; y no se puede hacer clic en otra esquina.

if (ctx.isPointInPath(m.x, m.y)){
      clicked = true;
................

Porque en su clic sucede solo if(!clicked)

room.addEventListener("click",(evt)=>{
  if(!clicked){...........}
let ctx = room.getContext("2d");
let cw = room.width = 300;
let ch = room.height = 300;

let size = 25;
let rows = 12;
let cols = 12;


let clicked = false;


let cells = new Array(cols*rows)
// the clickables cells: the index in the cells array and the extended rect position (x,y) and size (w,h)
let clickbles = [
  {index:0, rect:{x:0,y:0,w:size*3,h:size*6}},
  {index:11,rect:{x:300-size*3,y:0,w:size*3,h:size*6}},
  {index:12*11,rect:{x:0,y:300-size*6,w:size*3,h:size*6}},
  {index:12*12-1,rect:{x:300-size*3,y:300-size*6,w:size*3,h:size*6}}
]


//draw the grid of cells
 for (y = 0; y <= rows; y++) {
    for (x = 0; x < cols; x++) {
      let index = x + y * cols;
      let cell = {}
      cell.x = x*size;
      cell.y = y*size;
      
      cells[index] = cell;
    }
 }

cells.forEach((c,i)=>{
  ctx.beginPath();
  ctx.strokeRect(c.x,c.y,size,size);  
})


// mark the cells clickbles
clickbles.forEach(c=>{ctx.fillRect(cells[c.index].x,cells[c.index].y,size,size);})


// when clicking on the canvas
room.addEventListener("click",(evt)=>{
  
  
  if(!clicked){
  //get the mouse position
  let m = oMousePos(room, evt);
  
  for(let i = 0; i < clickbles.length; i++ ){
    let cell =  cells[clickbles[i].index];
    let rect =  clickbles[i].rect;
    ctx.beginPath();
    ctx.rect(cell.x,cell.y,size,size);
    // if the click happened inside one of the clickables cells
    if (ctx.isPointInPath(m.x, m.y)){
      clicked = true;
      
      // draw the extended rect
      ctx.beginPath();
      ctx.fillStyle = "red";
      ctx.fillRect(rect.x,rect.y,rect.w,rect.h);
      //breack the loop. No need to search further
      break;}
  }
  }
})

function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
	return { 
	x: Math.round(evt.clientX - ClientRect.left),
	y: Math.round(evt.clientY - ClientRect.top)
}
}
<canvas id="room"></canvas>

Espero que esto sea lo que estabas preguntando.

1
marc_s 15 jul. 2019 a las 04:50