2017-10-10 2 views
0

J'ai une forme semi-transparente:Ombre/effet de lueur de toile sur une forme semi-transparente?

this.cx.beginPath(); 
this.cx.globalAlpha = .1; 
this.cx.fillStyle = gradientFill; 
this.cx.strokeStyle = gradientStroke; 
this.cx.arc(150, 150, 139, 0, Math.PI * 2, true); 
this.cx.lineWidth = 1; 
this.cx.stroke(); 
this.cx.fill(); 

Je veux ajouter un peu d'ombre, mais je veux qu'il apparaisse seulement en dehors de la forme, je suppose que plus d'une lueur qu'une ombre. Est-il possible de le faire en toile comme mes tentatives avec:

this.cx.shadowColor = 'rgba(0, 0, 0, .75)'; 
this.cx.shadowBlur = 5; 
this.cx.shadowOffsetX = 5; 
this.cx.shadowOffsetY = -5; 

fée Look ordinaire l'ombre est visible à travers la forme semi-transparente.

Merci!

Répondre

0

Une façon est d'utiliser globalCompositeOperations afin de ne conserver que votre ombre extérieure, puis de redessiner vos parties semi-transparentes.

Mais notez que vous aurez beaucoup de bruit artefact ...

(async function() { 
 
    var ctx = c.getContext('2d'); 
 
    // commons 
 
    var gradientFill = ctx.createLinearGradient(0, 0, 200, 0); 
 
    gradientFill.addColorStop(0, 'rgba(0,0,0,0)') 
 
    gradientFill.addColorStop(1, 'rgba(255,0,0,1)') 
 
    var gradientStroke = ctx.createLinearGradient(0, 0, 200, 0); 
 
    gradientStroke.addColorStop(0, 'rgba(0,0,0,0)') 
 
    gradientStroke.addColorStop(1, 'rgba(0,255,0,1)') 
 
    ctx.lineWidth = 5; 
 
    // needed only once 
 
    ctx.beginPath(); 
 
    ctx.arc(150, 150, 139, 0, Math.PI * 2, true); 
 

 
    await wait(1000); // simply to show each step 
 

 
    // firt we draw only the shadow with black fill and stroke 
 
    ctx.shadowColor = 'rgba(0, 0, 0, .75)'; 
 
    ctx.shadowBlur = 5; 
 
    ctx.shadowOffsetX = 5; 
 
    ctx.shadowOffsetY = -5; 
 
    ctx.stroke(); 
 
    ctx.fill(); 
 

 
    await wait(1000); 
 

 
    // then keep only the shadow 
 
    ctx.globalCompositeOperation = 'destination-out'; // will erase existing content at drawn position 
 
    ctx.shadowColor = 'transparent'; // remove the shadow 
 
    ctx.stroke(); 
 
    ctx.fill(); 
 

 
    await wait(1000); 
 
    
 
    // finally draw the semi-transparent version 
 
    ctx.globalCompositeOperation = 'source-over'; 
 
    ctx.globalAlpha = .1; 
 
    ctx.fillStyle = gradientFill; 
 
    ctx.strokeStyle = gradientStroke; 
 
    ctx.stroke(); 
 
    ctx.fill(); 
 

 
})(); 
 

 
function wait(t) { 
 
    return new Promise(r => setTimeout(r, t)) 
 
}
<canvas id="c" height="300"></canvas>