R.Atim
R.Atim

Reputation: 387

HTML5 CANVAS Shadow a bug? or a code defect?

I'm faced with the problem about drawing of canvas.

Canvas is saved to data:image once.
And it is made to redraw.
Two problems occur at this time.

  1. A shadow will be applied to the object which has not drawn the shadow.
  2. A shadow will become deep if save and a redraw are repeated.

<canvas id="SAMPLE" width="960" height="480"></canvas>
<script type="text/javascript" src="./jquery.js"></script>
<script>
    var canvas = $("#SAMPLE"),
        ctx = canvas[0].getContext("2d");

    // first object (no shadow)
    ctx.strokeStyle   = "#0067ef";
    ctx.fillStyle     = "#0067ef";
    ctx.lineCap       = "round";
    ctx.lineWidth     = "15";
    ctx.globalAlpha   = 1;
    ctx.shadowBlur    = 0;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;
    ctx.shadowColor   = "#363636";
    ctx.beginPath();
    ctx.moveTo( 10, 10);
    ctx.lineTo(200, 200);
    ctx.stroke();
    ctx.closePath();

    // second object (has shadow)
    ctx.shadowBlur    = 5;
    ctx.shadowOffsetX = 5;
    ctx.shadowOffsetY = 5;
    ctx.shadowColor   = "#363636";
    ctx.beginPath();
    ctx.moveTo(300, 10);
    ctx.lineTo(400, 200);
    ctx.stroke();
    ctx.closePath();

    // Canvas is saved to data:image once.
    var save = canvas[0].toDataURL();

    // clear canvas
    ctx.clearRect(0, 0, 960, 480);

    // redraw
    var img = new Image();
        img.src = save;
        img.onload = function() {
            ctx.drawImage(this,0,0);
        };
</script>

It was normal when the picture at the time of save and before a redraw was investigated.

Two problems occur at the time of a redraw.

  1. A shadow will be applied to the object which has not drawn the shadow.
  2. A shadow will become deep if save and a redraw are repeated.

Does my code have a defect?

Upvotes: 1

Views: 887

Answers (2)

Technophile
Technophile

Reputation: 16

I also recently faced the same problem when I was implementing circle detection. I wanted to add shadow to make them look better and this problem popped up. I tried wrapping the shadow inside the beginPath() and closePath(). And, it worked fine!

This is my current working code:

ctx.beginPath();
ctx.fillStyle = "red";
ctx.shadowColor = "red";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 25;
ctx.arc(150, 150, 50, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();

Hope it helps to anyone who is having the same issue!

Upvotes: 0

Passerby
Passerby

Reputation: 10080

Because your fillStyle and other parameters are preserved, so upon drawing image, the effect is stacking up.

Use save() and restore() to prevent this:

ctx.save();
// first object (no shadow)
ctx.strokeStyle   = "#0067ef";
ctx.fillStyle     = "#0067ef";
/*
...
*/
ctx.closePath();
ctx.restore();

// Canvas is saved to data:image once.

JSFiddle demo with one extra canvas and the appended image for comparison.

Comment out the save() and restore() and re-run the fiddle, you'll notice the different.

Upvotes: 1

Related Questions