ZoEM
ZoEM

Reputation: 852

Apply shadow on different drawings in canvas

When I apply the shadow effect to the Sun variable, it automatically applies to the Neptune one as well. I don't want this. Do I give ctx a different name to fix this or does the issue lie somewhere else?

I've been told to keep just one context reference, so I'm terribly confused. I feel I need to shuffle some lines around to be able to give each variable unique properties.

Here's my code for you to see:

function initCanvas(){
    var ctx = document.getElementById('my_canvas').getContext('2d');
    var cW = ctx.canvas.width, cH = ctx.canvas.height;
    var rectW = 40;
    var rectH = 0;
    var rectX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5); 
    var rectY = (ctx.canvas.height * .5) - (rectH * .5);
    var Starsystem = {
        Neptune: {
          x: 180, 
          y: 300,
          render: function(){
            Starsystem.Neptune.x = Starsystem.Neptune.x + 0;
            Starsystem.Neptune.y = Starsystem.Neptune.y - 0;
            ctx.fillStyle = "rgb(65,105,225)";  
            ctx.beginPath();
            ctx.arc( Starsystem.Neptune.x , Starsystem.Neptune.y, 10, 0, Math.PI*2, true); 
            ctx.closePath();
            ctx.fill();
          }
        }, Sun: {
        render: function(){
        ctx.fillStyle = "rgb(255,255,51)";  
        ctx.beginPath();
        ctx.arc(rectX, rectY, rectW, rectH, Math.PI*2, true); //alligns the sun in center
        ctx.closePath();
        ctx.fill();
        ctx.shadowColor = 'yellow';
        ctx.shadowBlur = 50;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 0;      
        //Still applied to all 
        }
    }
}

Upvotes: 2

Views: 78

Answers (3)

Greg Borbonus
Greg Borbonus

Reputation: 1384

I only found 2 issues, and that was that you were setting it globally and you had the shadow AFTER you created the sun. You can move it wherever you'd like, but if you wanted it applied to your "Sun", then it would be best done like this.

The way I've found best to stop that problem is by wrapping my change code in save() and restore() functions. Like this:

    }, Sun: {
    render: function(){
    ctx.fillStyle = "rgb(255,255,51)";  
    ctx.save(); //store ctx so it can be later reused.
    ctx.shadowColor = 'yellow';
    ctx.shadowBlur = 50;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;    
    ctx.beginPath();
    ctx.arc(rectX, rectY, rectW, rectH, Math.PI*2, true); //alligns the sun in center
    ctx.closePath();
    ctx.fill();
    ctx.restore(); //ctx at time of save.

Working Fiddle: https://jsfiddle.net/gregborbonus/g1d6jkh7/

Upvotes: 2

tomasantunes
tomasantunes

Reputation: 945

You need to set the shadow properties before using the fill() method.

ctx.shadowColor = 'yellow';
ctx.shadowBlur = 50;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;      
ctx.fill();

Upvotes: 1

ManoDestra
ManoDestra

Reputation: 6483

Keep one context, yes, but you have to bear in mind that any properties you set on the drawing context, will be remembered for future draw operations. There's a couple of ways round this.

a) ensure that you always set the desired properties prior to any draw operations. Especially ones that may have been overwritten by another object's draw operations.

b) Use context.save() and context.restore(). You can save the state of the context, make changes, do your draw operations and then restore back to its previous state, ready for the next draw operation, ensuring that you have not messed about with any other draw properties for other objects.

http://www.tutorialspoint.com/html5/canvas_states.htm

Upvotes: 1

Related Questions