繁体   English   中英

Select canvas 网格中的多个单元格使用鼠标拖动

[英]Select multiple cells in grid of canvas using a mouse drag

我想通过拖动来实现选择功能,所以如果在网格图上拖动,矩形/正方形形式的多个单元格,但我的工作不正常 - 当我移动鼠标时应该形成正方形。 但是现在当我拖动它并向上移动鼠标时它会画一个正方形。

我还希望单元格在对角线的每个方向上按正方形选择

我如何解决它?

 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>

你做的一切都很好,我改变了一点如下:使用这个范围 function 选择对角线的每个方向的正方形

function range(start, end) {
    var ans = [];
    if (end > start) {
        for (let i = start; i <= end; i += 10) {
            ans.push(i);
        }
    } else {
        for (let i = start; i >= end; i -= 10) {
            ans.push(i);
    }}
    return ans;
}

那么你只需要像这样重写 mousemove 处理程序:

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

更具可读性的设计,并通过限制鼠标移动逻辑加快了速度。

 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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM