Quiero implementar la función de selección arrastrando, por lo que si arrastre en el gráfico de cuadrícula, la celda múltiple en forma de rectángulo/cuadrado, pero la mía no funciona correctamente; se debe formar un cuadrado mientras muevo el mouse. Pero ahora dibuja un cuadrado cuando lo arrastro y muevo el mouse hacia arriba.
También quiero que la celda seleccione por cuadrado en todas las direcciones de las diagonales.
¿Cómo lo soluciono?
function getSquare(canvas, evt) { var rect = canvas.getBoundingClientRect(); return { x: 1 + (evt.clientX - rect.left) - (evt.clientX - rect.left)%10, y: 1 + (evt.clientY - rect.top) - (evt.clientY - rect.top)%10 }; } function drawBoard(context) { for (var x = 0.5; x < 10001; x += 10) { context.moveTo(x, 0); context.lineTo(x, 10000); } for (var y = 0.5; y < 10001; y += 10) { context.moveTo(0, y); context.lineTo(10000, y); } context.strokeStyle = "#ddd"; context.stroke(); } function fillSquare(context, x, y){ context.fillStyle = "#70B7B5" context.fillRect(x,y,9,9); } var canvas = document.getElementById('myBoard'); var context = canvas.getContext('2d'); drawBoard(context); var isDrag=false; var previousPos = (-1,-1); canvas.addEventListener('mousedown', function(evt) { var mousePos = getSquare(canvas, evt); isDrag=true; fillSquare(context, mousePos.x, mousePos.y) previousPos = mousePos; }, false); canvas.addEventListener('mousemove', function(evt) { if (isDrag){ var mousePos = getSquare(canvas, evt); if (mousePos.x-previousPos.x){ for (i=0; i<(mousePos.x-previousPos.x)/10;i++){ for(j=0; j<(mousePos.x-previousPos.x)/10;j++){ fillSquare(context, mousePos.x-(j*10), mousePos.y-(i*10)); } } }else{ for (i=0; i<(previousPos.x-mousePos.x)/10;i++){ for(j=0; j<(previousPos.x-mousePos.x)/10;j++){ fillSquare(context, mousePos.x+(j*10), mousePos.y-(i*10)); } } } previousPos = mousePos; } }, false); canvas.addEventListener('mouseup', function(evt) { if (isDrag){ isDrag = false; } }, false); <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> </head> <body> <canvas id="myBoard" width="10000" height="10000"></canvas> <script type="text/javascript" src="myBoard2.js"></script> </body>hiciste todo bien y lo cambié un poco como se muestra a continuación: usa esta función de rango para seleccionar cuadrados en todas las direcciones de las diagonales
function range(start, end) { var ans = []; if (end > start) { for (let i = start; i <= end; i += 10) { ans.push(i); } } else { emptySquare(context); for (let i = start; i >= end; i -= 10) { ans.push(i); }} return ans; }y emptySquare() para borrar el color del contexto, como se muestra a continuación:
function emptySquare(context) { context.rect(0, 0, canvas.width, canvas.height); context.fillStyle = "#ffffff" context.fill(); context.strokeStyle = "#ddd"; context.stroke(); }entonces solo necesita reescribir el controlador de movimiento del mouse de esta manera:
canvas.addEventListener('mousemove', function(evt) { if (isDrag) { var mousePos = getSquare(canvas, evt); var x_dist = range(previousPos.x, mousePos.x); var y_dist = range(previousPos.y, mousePos.y); for (x in x_dist) { for (y in y_dist) { fillSquare(context, x_dist[x], y_dist[y]); }}} }, false);y llame al cuadrado vacío (contexto); en el controlador mousedown también ...
Un diseño un poco más legible, y acelerado un poco acelerando la lógica de movimiento del mouse.
const canvas = document.getElementById('board'); const context = canvas.getContext('2d'); let anchor = null; let pos = null; let lastPos = null; // return x,y in grid coords from an event function position(event) { const rect = canvas.getBoundingClientRect(); return [ Math.floor((event.clientX-rect.left)/10), Math.floor((event.clientY-rect.top)/10) ]; } // color the rectangle with corners at posA, posB function colorRegion(posA, posB, color) { const minX = Math.min(posA[0], posB[0]); const minY = Math.min(posA[1], posB[1]); const maxX = Math.max(posA[0], posB[0]); const maxY = Math.max(posA[1], posB[1]); context.fillStyle = color for (let i=minX; i<maxX; i++) { const tenI = i*10+1 for (let j=minY; j<maxY; j++) { context.fillRect(tenI,10*j+1,9,9); } } } // mouse down, set the anchor canvas.addEventListener('mousedown', function(evt) { anchor = position(evt); lastPos = position(evt); }) // mouse up, clear the anchor canvas.addEventListener('mouseup', function(evt) { anchor = null; }) // mouse move, color the old rect white, color new rect green // remember the last pos function onmove() { if (!anchor) return; colorRegion(anchor, lastPos, 'white') colorRegion(anchor, pos, '#70B7B5') lastPos = pos; } // no need to run this on every pixel // you could also measure absolute mouse move > 10x10 as a throttle const throttledOnMove = _.throttle(onmove, 100); canvas.addEventListener('mousemove', function(evt) { pos = position(evt); throttledOnMove() }) .container { height: 10000px; width: 10000px; } .grid { box-sizing: border-box; margin: 0; height: 100%; width: 100%; background-image: repeating-linear-gradient(0deg, transparent, transparent 9px, #ccc 9px, #ccc 10px), repeating-linear-gradient(-90deg, transparent, transparent 9px, #ccc 9px, #ccc 10px); } <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script> <div class="container"> <div class="grid"> <canvas id="board" width="10000" height="10000"></canvas> </div> </div>