我试图在画布图像上绘制多个(最多6个)矩形而不实际让它们与另一个重叠。怎么能在javascript中完成? 我想不出可用于此的逻辑..
修改:
如何检测任何一个绘制的矩形内是否发生鼠标点击,以便我可以再次在画布周围移动矩形而不重叠?
答案 0 :(得分:1)
要确定新的矩形是否会与现有的任何重叠相叠,您必须进行3次测试:
以下是......
如果您使用javascript对象定义了现有的矩形,请执行以下操作:
var rects=[];
rects.push({left:100,right:200,top:100,bottom:200});
然后你可以测试一个新的矩形是否会重叠任何现有的矩形,如下所示:
var newRectangle={left:50,right:25,top:50,bottom:25};
function willOverlap(newRect){
// shortcut to the new potential rect
var r2=newRect;
// test if one rect is completely inside another rect
var isInside=function(rect1,rect2){
return(rect2.left>=rect1.left &&
rect2.right<=rect1.right &&
rect2.top>=rect1.top &&
rect2.bottom<=rect1.bottom);
}
// test if the new rect is overlapping any existing rect
var isOverlapping=false;
for(var i=0;i<rects.length;i++){
var r1=rects[i];
//
var isIntersecting = !(r2.left>r1.right ||
r2.right<r1.left ||
r2.top>r1.bottom ||
r2.bottom<r1.top);
//
var isContained= isInside(r1,r2) || isInside(r2,r1);
//
if(isIntersecting || isContained){
isOverlapping=true;
}
}
return(isOverlapping);
}
以下是示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
var isDown=false;
var startX,startY;
var rects=[];
var newRect;
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
function handleMouseDown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
isDown=true;
}
function handleMouseUp(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mouseup stuff here
isDown=false;
if(!willOverlap(newRect)){
rects.push(newRect);
}
drawAll();
}
function drawAll(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.lineWidth=1;
ctx.strokeStyle='green';
for(var i=0;i<rects.length;i++){
var r=rects[i];
ctx.strokeRect(r.left,r.top,r.right-r.left,r.bottom-r.top);
}
}
function handleMouseOut(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mouseOut stuff here
isDown=false;
}
function handleMouseMove(e){
if(!isDown){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
newRect={
left:Math.min(startX,mouseX),
right:Math.max(startX,mouseX),
top:Math.min(startY,mouseY),
bottom:Math.max(startY,mouseY),
}
drawAll();
ctx.strokeStyle = "lightgray";
ctx.lineWidth = 3;
ctx.strokeRect(startX,startY,mouseX-startX,mouseY-startY);
}
function willOverlap(newRect){
// shortcut to the new potential rect
var r2=newRect;
// test if one rect is completely inside another rect
var isInside=function(rect1,rect2){
return(rect2.left>=rect1.left &&
rect2.right<=rect1.right &&
rect2.top>=rect1.top &&
rect2.bottom<=rect1.bottom);
}
// test if the new rect is overlapping any existing rect
var isOverlapping=false;
for(var i=0;i<rects.length;i++){
var r1=rects[i];
//
var isIntersecting = !(r2.left>r1.right ||
r2.right<r1.left ||
r2.top>r1.bottom ||
r2.bottom<r1.top);
//
var isContained= isInside(r1,r2) || isInside(r2,r1);
//
if(isIntersecting || isContained){
isOverlapping=true;
}
}
return(isOverlapping);
}
&#13;
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag to create a new rect.<br>New rect will be added if not overlapping.</h4>
<canvas id="canvas" width=300 height=300></canvas>
&#13;
答案 1 :(得分:0)
查看此演示:JSFiddle。
只需在JavaScript中指定矩形的不同起点,然后绘制它们:
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(10, 10, 20, 20);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect(30, 30, 20, 20);
......
}
}
答案 2 :(得分:0)
将每个方块视为一个框,然后插入逻辑。
要检查您是否将方框1视为点云,请检查方框2的四个点中是否有任何一个位于该点云中。
作为一个说明,我是一个java开发人员,但原理是一样的。 Math.abs是x的绝对值。
if((Math.abs(b1X - b2X) < b1Width && Math.abs(b1Y - b2Y) < b1Height) ||
(Math.abs(b1X - (b2X + b2Width)) < b1Width && Math.abs(b1Y - b2Y) < b1Height) ||
(Math.abs(b1X - b2X) < b1Width && Math.abs(b1Y - (b2Y + b2Height)) < b1Height) ||
(Math.abs(b1X - (b2X + b2Width)) < b1Width && Math.abs(b1Y - (b2Y + b2Height)) < b1Height))
return false;
第一行检查b2上的点1是否在点云中,如果点2在点云上则为第2行,如果点3在云上则为第3行,如果点4在云上则为第4行
点定义为
1 ----- 2
|。 。 。 。 |
3 ----- 4
在创建方块时,您必须检查新创建的方块。如果它向任何方块返回false,则它重叠。