Example 2: Taijitu (Yin Yang)

refresh(dc, width, height) // Sample code by Jim Bumgardner
{
  dc.clearRect(0,0,width,height);
  
  var rad = width*.45;
  var cx = width/2;
  var cy = width/2;
  var sm_rad = rad/2;
  var cx1 = cx;
  var cy1 = cy+sm_rad;
  var cx2 = cx;
  var cy2 = cy-sm_rad;
    
  
  dc.fillStyle = '#000';
  dc.beginPath();
    dc.arc(cx,cy,rad,0,2*Math.PI,false);
    dc.fill();
  
  dc.clearRect(0,0,width/2,height);
  
  dc.beginPath();
    dc.arc(cx1,cy1,sm_rad,0,2*Math.PI,false);
    dc.fill();
  
  dc.fillStyle = '#FFF';
  dc.beginPath();
    dc.arc(cx2,cy2,sm_rad,0,2*Math.PI,false);
    dc.arc(cx1,cy1,sm_rad/3,0,2*Math.PI,false);
    dc.fill();
  
  dc.fillStyle = '#000';
  dc.beginPath();
    dc.arc(cx2,cy2,sm_rad/3,0,2*Math.PI,false);
    dc.fill();
  
  dc.strokeStyle='#000';
  dc.lineWidth = 2;
  dc.beginPath();
    dc.arc(cx,cy,rad,0,2*Math.PI,false);
    dc.stroke(); 
  
  
}

Let's examine the program in detail. First I compute the radius of the outer circle, and its center cordinates, based on the overall width of the drawing. I make it proportional to the width so that if the size is changed, the figure will resize along with the drawing.

  var rad = width*.45;
  var cx = width/2;
  var cy = width/2;
The final figure contains curves which are based on a circle exactly half the size of the larger circle. Here, I work out the radius of this smaller circle.
  var sm_rad = rad/2;
Then I work out coordinates for the center of the black and white dots in the figure.
  var cx1 = cx;
  var cy1 = cy+sm_rad;
  var cx2 = cx;
  var cy2 = cy-sm_rad;
Now I am ready to start drawing. First I draw a large black circle.

  dc.fillStyle = '#000';
  dc.beginPath();
    dc.arc(cx,cy,rad,0,2*Math.PI,false);
    dc.fill();
It looks like this:

Then, I paint half the canvas with a white rectangle, to blank out half of the circle.

  dc.clearRect(0,0,width/2,height);

Then I draw a small black half-sized circle.

  dc.beginPath();
    dc.arc(cx1,cy1,sm_rad,0,2*Math.PI,false);
    dc.fill();

And a small white circle above it. A second arc in this block draws the small white eye.

  dc.fillStyle = '#FFF';
  dc.beginPath();
    dc.arc(cx2,cy2,sm_rad,0,2*Math.PI,false);
    dc.arc(cx1,cy1,sm_rad/3,0,2*Math.PI,false);
    dc.fill();
Here's the half-sized white circle.

And here's the small white eye. The radius of the small white eye is 1/3rd that of the half-sized circle (I found a size I liked through experimentation, the drawings I've found online vary depending on the artist).

Then I draw the small black eye.

  dc.fillStyle = '#000';
  dc.beginPath();
    dc.arc(cx2,cy2,sm_rad/3,0,2*Math.PI,false);
    dc.fill();

Finally, I am ready to draw the circular frame. I use a slightly thicker line thickness of 2 here, because I think it looks nice.

  dc.strokeStyle='#000';
  dc.lineWidth = 2;
  dc.beginPath();
    dc.arc(cx,cy,rad,0,2*Math.PI,false);
    dc.stroke();