2017-07-14 196 views
0

我正在寻找一种方法来在画布上“生活”绘制矩形或圆圈。Javascript画布绘制矩形或圆圈

我发现用fillRect()来绘制矩形,但没有生活的各种方式。我的意思是,能够在一点上将mouseDown()移动到画布中的另一个点上,画布定义画布的大小,就像例如在Microsoft Paint,OneNote等中一样。

任何人都可以帮助我,并告诉我如何开始?我可能会想对如何做到这一点的方式,没有看到矩形(或圆形)的尺寸变化,是这样的:

$("canvas").mousedown(function(event){ 
    var ctx = this.getContext("2d"); 
    ctx.clearRect(0,0,$(this).width(),$(this).height()); 
    var initialX = event.clientX - this.getBoundingClientRect().left; 
    var initialY = event.clientY - this.getBoundingClientRect().top; 

    $(this).mousemove(function(evt) { 
     ctx.strokeRect(initialX, initialY, evt.clientX - event.clientX, evt.clientY - event.clientY); 
    }); 
}); 

但我想现场观看,所以矩形的大小如何变化的时候,用户移动鼠标。

+0

使用'window.requestAnimationFrame()'经常刷新画布 – frozen

+0

@ randnum-1和?你的意思是每隔50ms重绘一次画布或像'setInterval()'中的那样,直到'mouseUp'? – nameless

+0

我假设你想要像这样的东西https://jsfiddle.net/jk607fqn/3/在画布上单击以绘制红色方块 – slackOverflow

回答

1

https://jsfiddle.net/zb66mxra/2/

要做到这一点活,你需要保持你的画布一个固定的图像。这很容易通过保持一个对象数组被JavaScript重复地重复来完成。

let drawArr = []; 

一个例子对象包含x和y坐标开始绘制,宽度和高度:

{ x: 100, 
    y: 100, 
    w: 10, 
    h: 10 } 

当你的鼠标在画布上移动时,你只希望它改变的数组,如果鼠标关闭。这意味着你需要设置一个标志,看看这种情况下是真或假:

let mousedown = false; 
    canvas.addEventListener('mousedown', function(e) { 
    mousedown = true; 
    ... 
    }); 
    canvas.addEventListener('mouseup', function(e) { 
    mousedown = false; 
    }); 

当你按下鼠标时要添加的项目提请阵列:

canvas.addEventListener('mousedown', function(e) { 
    mousedown = true; 
    drawArr.push({ 
    x: e.pageX, 
    y: e.pageY, 
    w: 0, 
    h: 0 
    }); 
}); 

高度和宽度最初设置为0.我们现在想要做的事情是,如果可以想象的话,是在将鼠标拖动到画布上并且鼠标关闭时创建矩形的高度和宽度。我们希望随时对此进行调整,以便在重新渲染屏幕时将其视为正在绘制。

操纵高度和宽度很容易,因为只要您只能一次绘制一个,它总是最近添加到绘制数组的对象。

canvas.addEventListener('mousemove', function(e) { 
    if (mousedown) { 
    let i = drawArr.length -1; 

    let { 
     x, 
     y 
    } = drawArr[i]; 
    drawArr[i].w = e.pageX - x; 
    drawArr[i].h = e.pageY - y; 
    } 
}); 

最后我们使用requestAnimationFrame在draw数组中不断绘制任何对象。

requestAnimationFrame(draw); 

然后递归内绘制函数:

function draw() { 
... 
requestAnimationFrame(draw); 
} 

然后,我们只需要清除原先的屏幕呈现和遍历平局阵列我们通过调用它时,页面加载做到这一点并再次将所有内容绘制到屏幕上。

function draw() { 
    ctx.clearRect(0, 0, window.innerWidth, window.innerHeight); 
    for (let obj of drawArr) { 
    let { 
     x, 
     y, 
     w, 
     h 
    } = obj; 
     ctx.strokeRect(x, y, w, h); 
    } 
    requestAnimationFrame(draw); 
    } 

瞧。

+0

感谢您的回答,看起来不错,而且正是我想要的,我会尽快尝试可能的,一个问题:难以用这样的代码画一个圆圈吗?那么这将是一个大变化吗?如此相同的原则,只需一个圆圈 – nameless

+0

@nameless它会非常相似。您需要使用arc context方法,接着使用stroke()而不是strokeRect。您还需要在绘制对象中存储半径,并在拖动画布时更新它。 – zfrisch

+0

https://medium.com/wdstack/quick-blurb-2d-canvas-app-setup-5e6f13e12884我写的这篇文章可能会帮助您更好地理解2d画布的基本方法和体系结构。此外,如果这是您要查找的内容,请点击旁边的绿色复选框接受此答案。 – zfrisch