Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 722
Yoav Kadosh Avatar asked Apr 16 '13 19:04

Yoav Kadosh


1 Answers

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>
like image 192
markE Avatar answered Sep 28 '22 01:09

markE