Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>globalCompositeOperation (xor) will not work on a <strong>rotating</strong> line like a “clock hand”….here’s why:</p> <p>Assume you draw a vertical line. Then draw a second vertical line to the right of the first. Assume the second vertical line <strong>overlaps</strong> the first line by half. </p> <p>Canvas.globalCompositeOperation=”xor” causes overlapping areas to be removed, so the second line removes <strong>half</strong> the first line and also half of itself. </p> <p>Here is code and a Fiddle: <a href="http://jsfiddle.net/m1erickson/e24KU/" rel="nofollow">http://jsfiddle.net/m1erickson/e24KU/</a></p> <pre><code> function drawLine(){ ctx.globalCompositeOperation="xor"; ctx.strokeStyle="red"; ctx.lineWidth=10; ctx.beginPath(); ctx.moveTo(posX,10); ctx.lineTo(posX,100); ctx.stroke(); posX+=5; } </code></pre> <p>This is a Fiddle of a “clock hand” sweeping around a centerpoint: <a href="http://jsfiddle.net/m1erickson/hW2EY/" rel="nofollow">http://jsfiddle.net/m1erickson/hW2EY/</a></p> <p>However, if we try to use “xor” on a rotating line, the lines overlay <strong>at an angle</strong> and therefore the xor is incomplete.</p> <p>Here is a Fiddle showing the line “xor” being ineffective when rotated: <a href="http://jsfiddle.net/m1erickson/f7hHx/" rel="nofollow">http://jsfiddle.net/m1erickson/f7hHx/</a></p> <p><strong>[Edited: new code was supplied by OP allowing for an expanded answer]</strong></p> <p>I looked at your new code and am suggesting some changes and optimizations.</p> <p>As I said in my original answer, you <em>cannot</em> effectively erase a line that was drawn at an angle. This is due to anti-aliasing that the browser does automatically—antiAliasing for canvas cannot be turned off.</p> <p>Here is a Fiddle of the results after the changes: <a href="http://jsfiddle.net/m1erickson/9QD65/" rel="nofollow">http://jsfiddle.net/m1erickson/9QD65/</a></p> <p>Changes:</p> <p><strong>Believe it or not:</strong> It is usual to completely erase and completely redraw the canvas during each animation loop! Canvas really is quick enough to handle these redraws—especially now that canvas is GPU accelerated. If you <em>absolutely</em> need to optimize your performance, you <em>can</em> define “dirty” areas of the canvas that must be erased/redrawn and leave the other areas as previously drawn. In practice, once you need this type of performance, your canvas is so complicated that it’s more efficient to completely clear/redraw than to try to define the dirty areas. </p> <p>Optimizations:</p> <p>Moved canvas,context,centerX,centerY out of the animation loop since these values can be computed once and reused.</p> <p>Here is my suggested code for you to look at:</p> <pre><code> &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt; &lt;title&gt;Clock&lt;/title&gt; &lt;/head&gt; &lt;body onload="spin()"&gt; &lt;canvas id="myCanvas" width="578" height="400"&gt;&lt;/canvas&gt; &lt;script&gt; var firstTime = 0; var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); var centerX=canvas.width/2; var centerY=canvas.height/2; var canvasWidth=canvas.width; var canvasHeight=canvas.height; function spin() { //get the right angle for the clock hand var date = new Date; var seconds = date.getSeconds(); var a = seconds*6; var angleRadian = a*Math.PI/180; var angle = 1/2*Math.PI - angleRadian; if(a &gt; 360) a = 0; //draw line drawLine(angle, 100, canvas, context, "black",1); //repeat for the next second setTimeout(spin, 500); } function drawLine(angle, radius, canvas, context) { var xTarget = centerX + Math.cos(angle)*radius; var yTarget = centerY - Math.sin(angle)*radius; //clear the canvas context.clearRect(0,0,canvasWidth,canvasHeight); //draw context.save(); context.beginPath(); context.moveTo(centerX,centerY); context.lineTo(xTarget, yTarget); context.stroke(); context.restore() } &lt;/script&gt; &lt;/body&gt; &lt;/html&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload