Browser in the Dark: flashlights with CSS and canvas
voussoir.net
voussoir.net
I think CSS clip-path might be a solution like you want but without the canvas. Just tried it out here to confirm: https://codepen.io/dsmmcken/pen/BaJqrwX
mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="200%25" height="200%25"><circle r="160" cx="50%25" cy="50%25" fill="white"/></svg>') calc(var(--x) - 100%) calc(var(--y) - 100%) / 200% 200%;
This doesn’t seem to work below one screenful of content, though, and I’m not sure why and don’t intend to spend the time required to make it work. The SVG size technique I’ve used is a bit dodgy (in a fun kind of way) anyway. You’d probably be better to have a separate `position: fixed` element that sits on top of everything, and apply the mask to it.The mix-blend-mode trick is cool for all of the variety of effects though!
Kudos to the OP for coding up the feature in CSS. The effect is fairly easy to recreate in the canvas element, using a radialGradient in a rectangle for a simple spotlight or, for the replacement effect, playing with globalcompositeoperation when rendering the scene.
Here's my spotlight demo, which I did for a CodePen Challenge last year (warning: page will ask to use your device's camera): https://codepen.io/kaliedarik/pen/gORXpya
A bit of a tangent, but gosh did I find Dancer in the Dark to be traumatizing. So sad! Bjork (whom I love) said she wouldn't do movies again after that one but I was happy to see her pop up in The Northman trailer.
Take a look! https://www.davidwparker.com/
Bug report: I can see a tiny pixel of the tip of the cat's ear when the flashlight is out of his frame: https://i.imgur.com/XBWYLDI.png
I wonder if you could put the canvas/flashlight controls in a fixed corner of the page (instead of inline as you scroll up & down). Fixed, omnipresent controls would be more video game like.
Plus, inlined controls add to the suspense -- you might truly get lost in the dark! And breathe a sigh of relief when you find the button again :)
background: radial-gradient(circle at var(--lightx) var(--lighty), transparent 0, transparent 100px, black 110px); #blackout
{
position: fixed;
z-index: 1;
inset: -100%;
background: radial-gradient(circle at center, transparent 0px, transparent 100px, black 110px);
transform: translate(var(--lightx), var(--lighty));
pointer-events: none;
}
document.body.addEventListener("mousemove", function(e){
document.documentElement.style.setProperty('--lightx', (e.clientX - (document.body.clientWidth/2)) + "px");
document.documentElement.style.setProperty('--lighty', (e.clientY - (document.body.clientHeight/2)) + "px");
});
This works too. I'm finding that while the dev tools are open, the transform method drops to very low fps whereas the recalculating method only loses a bit of fps. While the dev tools are closed they seem to be equal on my computer. Of course on a weaker computer there might be a bigger difference.Thanks!
But where does "CSS" come in?
The CSS comes in the form of the mix-blend-mode divs, "grayscale", "bright white", "inverse", etc. They are more like lenses than flashlights since they don't illuminate what's not already there, but flashlights were my inspiration for doing this so that's the term I stuck with, though I did use the word lens once.
The CSS idea came first, and the canvas idea came second when I wanted to make a full blackout and didn't know about clip-path.