Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Another way to play with light is to use the globalCompositeOperation mode 'ligther' to ligthen things, and just use globalAlpha to darken things. </p> <p>First here's an image, with a cartoon lightening on the left, and a more realistic lightening on the right, but you'd rather watch the fiddle, since it's animated :<br> <a href="http://jsfiddle.net/gamealchemist/ABfVj/" rel="noreferrer">http://jsfiddle.net/gamealchemist/ABfVj/</a></p> <p><img src="https://i.stack.imgur.com/4rng6.png" alt="let&#39;s play with candles and lights"></p> <p>So how i did things :</p> <p>To darken :<br> - Choose a darkening color( most likely black, but you can choose a red or another color to teint the result).<br> - choose an opacity ( 0.3 seems a good start value ).<br> - fillRect the area you want to darken.</p> <pre><code>function darken(x, y, w, h, darkenColor, amount) { ctx.fillStyle = darkenColor; ctx.globalAlpha = amount; ctx.fillRect(x, y, w, h); ctx.globalAlpha = 1; } </code></pre> <p>To lighten :<br> - Choose a lightening color. Beware that this color's r,g,b will be added to the previous point's r,g,b : if you use a high value your color will get burnt.<br> - change the globalCompositeOperation to 'lighter'<br> - you might change opacity also, to have more control over the lightening.<br> - fillRect or arc the area you want to lighten. </p> <p>If you draw several circles while in lighter mode, the results will add up, so you can choose a quite low value and draw several circles.</p> <pre><code>function ligthen(x, y, radius, color) { ctx.save(); var rnd = 0.03 * Math.sin(1.1 * Date.now() / 1000); radius = radius * (1 + rnd); ctx.globalCompositeOperation = 'lighter'; ctx.fillStyle = '#0B0B00'; ctx.beginPath(); ctx.arc(x, y, radius, 0, 2 * π); ctx.fill(); ctx.fillStyle = color; ctx.beginPath(); ctx.arc(x, y, radius * 0.90+rnd, 0, 2 * π); ctx.fill(); ctx.beginPath(); ctx.arc(x, y, radius * 0.4+rnd, 0, 2 * π); ctx.fill(); ctx.restore(); } </code></pre> <p>Notice that i added a sinusoidal variation to make the light more living.</p> <p>Ligthen : another way :<br> You can also, while still using the 'ligther' mode, use a gradient to have a smoother effect (first one is more cartoon like, unless you draw a lot of circles.).</p> <pre><code>function ligthenGradient(x, y, radius) { ctx.save(); ctx.globalCompositeOperation = 'lighter'; var rnd = 0.05 * Math.sin(1.1 * Date.now() / 1000); radius = radius * (1 + rnd); var radialGradient = ctx.createRadialGradient(x, y, 0, x, y, radius); radialGradient.addColorStop(0.0, '#BB9'); radialGradient.addColorStop(0.2 + rnd, '#AA8'); radialGradient.addColorStop(0.7 + rnd, '#330'); radialGradient.addColorStop(0.90, '#110'); radialGradient.addColorStop(1, '#000'); ctx.fillStyle = radialGradient; ctx.beginPath(); ctx.arc(x, y, radius, 0, 2 * π); ctx.fill(); ctx.restore(); } </code></pre> <p>i also added here a sin variation.<br> Rq : creating a gradient on each draw will create garbage : store the gradient if you use a single gradient, and store them in an array if you want to animate the gradients.<br> If you are using the same light in several places, have a single gradient built, centered on (0,0), and translate the canvas before drawing always with this single gradient.</p> <p>Rq 2 : you can use clipping to prevent some parts of the screen to be lightened (if there's an obstacle). I added the blue circle on my example to show this. </p> <p>So you might want to ligthen directly your scene with those effects, or create separately a light layer that you darken/lighten as you want before drawImage it on the screen. </p> <p>There are too many scenari to discuss them here (light animated or not, clipping or not, pre-compute a light layer or not, ...) but as far as speed is concerned, for Safari and iOS safari, the solution using rect/arc draws -either with gradient or a solid fill- will be rocket faster than drawing an image/canvas.<br> On Chrome it will be quite the opposite : it's faster to draw an image than to draw each geometry when the geometry count raises.<br> Firefox is rather similar to Chrome for this.</p>
    singulars
    1. This table or related slice is empty.
    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.
    3. 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