2013-01-23 195 views
4

我有一些功能可以在画布元素上绘制矩形。当元素被绘制时,我想通过拖拽它的角来调整它的大小。调整大小矩形HTML5画布

HTML

<canvas id="canvas" width="500" height="500"></canvas> 

JS

var canvas = document.getElementById('canvas'), 
    ctx = canvas.getContext('2d'), 
    rect = {}, 
    drag = false; 

function init() { 
    canvas.addEventListener('mousedown', mouseDown, false); 
    canvas.addEventListener('mouseup', mouseUp, false); 
    canvas.addEventListener('mousemove', mouseMove, false); 
} 

function mouseDown(e) { 
    rect.startX = e.pageX - this.offsetLeft; 
    rect.startY = e.pageY - this.offsetTop; 
    drag = true; 
} 

function mouseUp() { 
    drag = false; 
} 

function mouseMove(e) { 
    if (drag) { 
    rect.w = (e.pageX - this.offsetLeft) - rect.startX; 
    rect.h = (e.pageY - this.offsetTop) - rect.startY ; 
    ctx.clearRect(0,0,canvas.width,canvas.height); 
    draw(); 
    } 
} 

function draw() { 
    ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h); 
} 

init(); 
+0

我编辑我的答案更完整 –

回答

10

通过查看是否一定要使用某种类型的阈值,以检查是否存在拖延的角落,使用closeEnough变量来保存这个阈值,则检查角落角点与鼠标点之差的绝对值小于阈值。除此之外,这只是很多情况。 Here is a jsFiddle of it

var canvas = document.getElementById('canvas'), 
    ctx = canvas.getContext('2d'), 
    rect = {}, 
    drag = false, 
    mouseX, 
    mouseY, 
    closeEnough = 10, 
    dragTL=dragBL=dragTR=dragBR=false; 

function init() { 
    canvas.addEventListener('mousedown', mouseDown, false); 
    canvas.addEventListener('mouseup', mouseUp, false); 
    canvas.addEventListener('mousemove', mouseMove, false); 
} 

function mouseDown(e) { 
    mouseX = e.pageX - this.offsetLeft; 
    mouseY = e.pageY - this.offsetTop; 

    // if there isn't a rect yet 
    if(rect.w === undefined){ 
    rect.startX = mouseY; 
    rect.startY = mouseX; 
    dragBR = true; 
    } 

    // if there is, check which corner 
    // (if any) was clicked 
    // 
    // 4 cases: 
    // 1. top left 
    else if(checkCloseEnough(mouseX, rect.startX) && checkCloseEnough(mouseY, rect.startY)){ 
    dragTL = true; 
    } 
    // 2. top right 
    else if(checkCloseEnough(mouseX, rect.startX+rect.w) && checkCloseEnough(mouseY, rect.startY)){ 
    dragTR = true; 

    } 
    // 3. bottom left 
    else if(checkCloseEnough(mouseX, rect.startX) && checkCloseEnough(mouseY, rect.startY+rect.h)){ 
    dragBL = true; 

    } 
    // 4. bottom right 
    else if(checkCloseEnough(mouseX, rect.startX+rect.w) && checkCloseEnough(mouseY, rect.startY+rect.h)){ 
    dragBR = true; 

    } 
    // (5.) none of them 
    else { 
    // handle not resizing 
    } 

    ctx.clearRect(0,0,canvas.width,canvas.height); 
    draw(); 

} 

function checkCloseEnough(p1, p2){ 
    return Math.abs(p1-p2)<closeEnough; 
} 
function mouseUp() { 
    dragTL = dragTR = dragBL = dragBR = false; 
} 

function mouseMove(e) { 
    mouseX = e.pageX - this.offsetLeft; 
    mouseY = e.pageY - this.offsetTop; 
    if(dragTL){ 
    rect.w += rect.startX-mouseX; 
    rect.h += rect.startY-mouseY; 
    rect.startX = mouseX; 
    rect.startY = mouseY; 
    } else if(dragTR) { 
    rect.w = Math.abs(rect.startX-mouseX); 
    rect.h += rect.startY-mouseY; 
    rect.startY = mouseY; 
    } else if(dragBL) { 
    rect.w += rect.startX-mouseX; 
    rect.h = Math.abs(rect.startY-mouseY); 
    rect.startX = mouseX; 
    } else if(dragBR) { 
    rect.w = Math.abs(rect.startX-mouseX); 
    rect.h = Math.abs(rect.startY-mouseY); 
    } 
    ctx.clearRect(0,0,canvas.width,canvas.height); 
    draw(); 
} 

function draw() { 
    ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h); 
} 

init(); 
+0

它无法正常工作。 – Developer

+0

你能解释一下你的意思吗?它对我来说工作得很好。我更新了小提琴,让它更明显地发生了什么。 –

+0

做得很好,我喜欢把手,所以用户知道如何使用它。 –

7

做一个处理系统:当鼠标移动,让距离各个角落拿到第一个是在光标附近,然后根据它存下来,并调整您的矩形。

这里是一个的jsfiddle说明它:http://jsfiddle.net/BaliBalo/9HXMG/

function getHandle(mouse) { 
    if (dist(mouse, point(rect.x, rect.y)) <= handlesSize) return 'topleft'; 
    if (dist(mouse, point(rect.x + rect.w, rect.y)) <= handlesSize) return 'topright'; 
    if (dist(mouse, point(rect.x, rect.y + rect.h)) <= handlesSize) return 'bottomleft'; 
    if (dist(mouse, point(rect.x + rect.w, rect.y + rect.h)) <= handlesSize) return 'bottomright'; 
    if (dist(mouse, point(rect.x + rect.w/2, rect.y)) <= handlesSize) return 'top'; 
    if (dist(mouse, point(rect.x, rect.y + rect.h/2)) <= handlesSize) return 'left'; 
    if (dist(mouse, point(rect.x + rect.w/2, rect.y + rect.h)) <= handlesSize) return 'bottom'; 
    if (dist(mouse, point(rect.x + rect.w, rect.y + rect.h/2)) <= handlesSize) return 'right'; 
    return false; 
} 
+0

它正在工作。好的解决方案 – Developer