Friday, February 10, 2012

Canvas : Shape + shadow

May Allah`s peace , mercy and blessing be upon you

Hi, I've been working on InputCanvas and I faced an issue , finally I got to the solution and I'll share it with you .

I'll use this beautiful cloud from html5canvastutorials.com

the code :
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.beginPath();
context.moveTo(170, 80);
context.bezierCurveTo(130, 100, 130, 150, 230, 150);
context.bezierCurveTo(250, 180, 320, 180, 340, 150);
context.bezierCurveTo(420, 150, 420, 120, 390, 100);
context.bezierCurveTo(430, 40, 370, 30, 340, 50);
context.bezierCurveTo(320, 5, 250, 20, 250, 50);
context.bezierCurveTo(200, 5, 150, 20, 170, 80);
context.closePath();
context.lineWidth = 5;
context.fillStyle = "#8ED6FF";
context.fill();
context.strokeStyle = "#0000ff";
context.stroke();
To add a shadow we have to set shadow's proprieties :
context.shadowColor   = "#000000";
context.shadowBlur    = 3;
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
Our problem is how to place the shadow ?!! first thing I did was :
....
context.closePath();
context.lineWidth = 5;
context.fillStyle = "#8ED6FF";
context.strokeStyle = "#0000ff";
context.shadowColor = "#000000";
context.shadowBlur = 2;
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
context.fill();
context.stroke();
The result :
I was confused I tried to try all different kind of arrangements but all I got was weird results . So I posted the question at stackoverflow , @Neurofluxation proposed a solution using globalCompositeOperation :

....
context.closePath();
context.lineWidth = 5;
context.fillStyle = "#8ED6FF";
context.strokeStyle = "#0000ff";
context.fill();    
context.globalCompositeOperation = "destination-over";
context.shadowColor = "#000000";
context.shadowBlur    = 9; 
context.shadowOffsetX = 3; 
context.shadowOffsetY = 3;    
context.stroke();
:D what he really did her is to increase offset to hide the white space between the shape and the shadow . because it's the stroke's shadow not the fill's !!! http://jsfiddle.net/j8u8p/16/

I accepted the answer -but I wasn't convinced - so I did some experiments , Then I understood the issue ; the problem is that Canvas's shadow is defined to be applied to every drawing ( fill, stroke , .. ) Therefore what I need to do is to apply shadow on the fill then remove it so it wouldn't be applied to the stroke.
The Final solution :
http://jsfiddle.net/j8u8p/18/
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.beginPath();
context.moveTo(170, 80);
context.bezierCurveTo(130, 100, 130, 150, 230, 150); 
context.bezierCurveTo(250, 180, 320, 180, 340, 150);
context.bezierCurveTo(420, 150, 420, 120, 390, 100);
context.bezierCurveTo(430, 40, 370, 30, 340, 50);
context.bezierCurveTo(320, 5, 250, 20, 250, 50);
context.bezierCurveTo(200, 5, 150, 20, 170, 80);
context.closePath();
context.lineWidth = 5;     
context.fillStyle = "#8ED6FF";
context.strokeStyle = "#0000ff";     
context.shadowColor = "#000000";
context.shadowBlur    = 5;
context.shadowOffsetX = 8;
context.shadowOffsetY = 8;
context.fill();    
context.shadowColor = 0;
context.shadowBlur    = 0;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.stroke();

No comments:

Post a Comment


Zoli Issam's blog proudly powered by Blogger | All rights reserved Jaw,B 2010-2013