Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
408 views
in Technique[技术] by (71.8m points)

javascript - Marking the intersecting area between two circles in Canvas

I am trying to mark the overlapping area between two circles (like in a Venn Diagram). I figured the way to do this is by drawing two arcs using the two intersecting points and than fill the path using fill(). I know the coordinates of the intersection points, but how do I use that as an input for the arc() function?

ctx.beginPath();
ctx.arc(circle1.x,circle1.y,circle1.r, ? , ? ,true);
ctx.fill();
ctx.closePath();

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can draw the intersection of 2 shapes using canvas’s globalCompositeOperation

enter image description here

The globalCompositeOperation allows you to control which parts of old and new drawings are shown on the canvas.

You can see examples of each compositing mode here: http://www.html5canvastutorials.com/advanced/html5-canvas-global-composite-operations-tutorial/

We use 2 of these compositing modes to highlight the intersection of your 2 circles:

source-atop

Given that the left circle is already draw, source-atop will draw only the intersecting part of the right circle.

    ctx.globalCompositeOperation="source-atop";
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);

destination-over

Given that the left circle is already draw, destination-over will draw the right circle under the existing left circle.

    ctx.globalCompositeOperation="destination-over";
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);

It’s a lot to take in, so you might comment out all the drawing code and then uncomment it one-opration-at-a-time to see what effect each operation has.

Here’s code and a Fiddle: http://jsfiddle.net/m1erickson/JGSJ5/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    ctx.fillStyle="yellow";
    ctx.strokeStyle="black";
    ctx.lineWidth=3;

    var circle1={x:100,y:100,r:50};
    var circle2={x:140,y:100,r:50};


    // draw circle1
    ctx.save();
    ctx.beginPath();
    ctx.arc(circle1.x,circle1.y,circle1.r, 0, 2*Math.PI, false);
    ctx.stroke();
    ctx.fill();

    // composite mode "source-atop" to draw the intersection
    ctx.beginPath();
    ctx.fillStyle="orange";
    ctx.globalCompositeOperation="source-atop";
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);
    ctx.fill();
    ctx.stroke();
    ctx.restore();

    // destination-over to draw fill for circle2 again
    ctx.beginPath();
    ctx.globalCompositeOperation="destination-over";
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);
    ctx.fill();

    // back to normal composite mode (newest drawings on top)
    ctx.globalCompositeOperation="source-over";

    // draw the stroke for circle1 again
    ctx.beginPath();
    ctx.arc(circle1.x,circle1.y,circle1.r, 0, 2*Math.PI, false);
    ctx.stroke();

    // draw the stroke for circle2 again
    ctx.beginPath();
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);
    ctx.stroke();

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...