JavaScript HTML5画布绘制透明圆形

5

我需要一个函数,在鼠标按下时从中心点 (x, y) 开始绘制多个圆形,并拖动鼠标到 deltaX、deltaY,从而创建每个圆的半径 r。这些圆不能填充(需要透明),以便用户清楚地看到它们相交的位置。我的当前代码在拖动鼠标时绘制圆形,这是预期的,但它也会留下额外的圆形。我只需要在鼠标松开时保留一个圆形。感谢您的帮助。谢谢 :).

<html>

<head>

</head>

<body style="margin:0">
<canvas id="canvas" width="500" height="500" style="border:1px solid"></canvas>

<script>

var canvas=document.getElementById('canvas');
var context=canvas.getContext('2d');
var radius=50;
var nStartX = 0;
var nStartY = 0;
var bIsDrawing = false;
var putPoint = function(e){
  nStartX = e.clientX;nStartY = e.clientY;
  bIsDrawing = true;
  radius = 0;
}
var drawPoint = function(e){
  if(!bIsDrawing)
    return;
  
  var nDeltaX = nStartX - e.clientX;
  var nDeltaY = nStartY - e.clientY;
  radius = Math.sqrt(nDeltaX * nDeltaX + nDeltaY * nDeltaY)
  context.beginPath();
  context.arc(nStartX, nStartY, radius, 0, Math.PI*2);
  context.strokeStyle="#000000";
  //context.fillStyle="#FFFFFF";
  context.fillStyle = 'rgba(0, 0, 0, 0)';
  context.stroke();
  context.fill();
}
var stopPoint = function(e){
  //context.clip();
  //context.clearRect(0, 0, canvas.width, canvas.height);
  bIsDrawing = false;
}
canvas.addEventListener('mousedown',putPoint);
canvas.addEventListener('mousemove',drawPoint);
canvas.addEventListener('mouseup',stopPoint);

</script>
</body>

</html>


3
使用两块画布。在顶部的画布上绘制当前处理的圆形,每个时间间隔清除它。在底部的画布上绘制最终结果而不清除。或者跟踪所有圆形并不断重新绘制。 - Yoshi
如果你的圆可以是椭圆,我也有一个对应的JSFiddle示例:http://jsfiddle.net/xXqsu/2/ - Hugo S. Mendes
2个回答

4
你需要跟踪你画过的圆形(和其他物体)- 一种方法是在鼠标松开时将它们推入一个数组中。然后每次绘制之前都应该清除画布并重新绘制保存的圆形。
var circles = [];
...

清除画布
...
radius = Math.sqrt(nDeltaX * nDeltaX + nDeltaY * nDeltaY)
context.clearRect(0, 0, canvas.width, canvas.height);
...

绘制保存的圆形。
...
context.fill();
// drawing saved circles
circles.forEach(function(circle){
    context.beginPath();
    context.arc(circle.nStartX, circle.nStartY, circle.radius, 0, Math.PI*2);
    context.strokeStyle="#000000";
    context.fillStyle="#FFFFFF";
    context.fillStyle = 'rgba(0, 0, 0, 0)';
    context.stroke();
    context.fill();
})
...

保存已完成的圆形

...
bIsDrawing = false;
// saving completed circles
var nDeltaX = nStartX - e.clientX;
var nDeltaY = nStartY - e.clientY;
radius = Math.sqrt(nDeltaX * nDeltaX + nDeltaY * nDeltaY);
circles.push({ nStartX: nStartX, nStartY: nStartY, radius: radius });
...

Fiddle - https://jsfiddle.net/9x77sg2h/


这些不是透明的圆圈,请在您的Canva中添加颜色,然后您就会看到。 - user889030

2

为了进一步阐明我的评论,这里有一个跟踪所有圆形的示例。基本上与potatopeelings的答案相同,但我想展示如何使用requestAnimationFrame来独立地重新绘制,而不受用户行为的影响。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var circles = [];
var currentCircle = null;

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

function putPoint(e){
    currentCircle = {
        center: {
            x: e.clientX - this.offsetLeft + window.scrollX,
            y: e.clientY - this.offsetTop + window.scrollY
        }
    };
}

function drawPoint(e)
{
    if (null !== currentCircle) {
        currentCircle.radius = Math.sqrt(
              Math.pow(currentCircle.center.x - e.clientX + this.offsetLeft - window.scrollX, 2)
            + Math.pow(currentCircle.center.y - e.clientY + this.offsetTop - window.scrollY, 2)
        );
    }
}

function drawCircles()
{
    // clear canvas
    context.clearRect(0, 0, canvas.width, canvas.height);

    // previous
    circles.forEach(drawCircle);

    // current
    if (null !== currentCircle) {
        drawCircle(currentCircle);
    }
}

function drawCircle(circle)
{
    context.save();
    context.beginPath();
    context.arc(circle.center.x, circle.center.y, circle.radius, 0, 2 * Math.PI);
    context.strokeStyle= '#000000';
    context.fillStyle = 'rgba(0, 0, 0, 0)';
    context.stroke();
    context.fill();
    context.restore();
}

function stopPoint()
{
    if (null !== currentCircle) {
        circles.push(currentCircle);
        currentCircle = null;
    }
}

canvas.addEventListener('mousedown', putPoint, false);
canvas.addEventListener('mousemove', drawPoint, false);
canvas.addEventListener('mouseup', stopPoint, false);
<canvas id="canvas" width="500" height="500" style="border:1px solid"></canvas>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接