Browser in the Dark: flashlights with CSS and canvas ==================================================== Note: this article will make more sense if you are using a mouse or other pointing device. Requires javascript. Warning: things can get a little spooky in the dark! You can read the source code for this document [here](https://git.voussoir.net/voussoir/voussoir.net/raw/branch/master/voussoir.net/writing/browser_in_the_dark/browser_in_the_dark.md) (or by pressing Ctrl+U in chrome / firefox). ## mix-blend-mode
I really like the "dark mode" switch on https://tonsky.me [footnote_link]. It's a fun subversion of expectations and reminds me of [Night Light (1995)](/writing/night_light_1995), a PC game for kids about using a flashlight in the dark. One of the splash texts I put on [my homepage](/?justthesplash) a while back says "looks better in black and white". Yesterday, while hypnotized by my own pulsating creation [footnote_link], I had the idea to put the two together and create a grayscale "flashlight", or perhaps a lens. I learned that the CSS property `mix-blend-mode` allows me to make a div that turns everything below it gray. The other mix-blend-mode options are cool too. The results don't look exactly like a light source, but it's a nice toy. Here are some different flashlights and photos with which to admire them:It applies to all elements on the page. sample sample sample sample sample. ♫ It's just your imagination
If at any time you need to come back, all you must do is open your eyes. This works great in conjunction with the mix-blend-mode lights:
Go back up and look at the images again! After [posting](https://news.ycombinator.com/item?id=31029845) this article to Hacker News, I got some great suggestions for solving this problem with CSS: ```CSS body { clip-path: circle(80px at var(--lightx) var(--lighty)); } ``` alternatively: ```CSS #blackout { position: fixed; z-index: 1; inset: -5px; background: radial-gradient(circle at var(--lightx) var(--lighty), transparent 0, transparent 100px, black 110px); pointer-events: none; } ``` where lightx and lighty are set by a mousemove handler. I haven't assessed the performance impact of the Canvas solution versus these CSS solutions, but if I need to do this again in the future I think I will preferentially reach for the CSS version since it fits well with my usual way of doing things. ## Night Light with CSS I also wanted to try making a Night Light game effect. The player who recorded the above video also uploaded the game .iso to the Internet Archive. Thank you Vulnerose! https://archive.org/details/NightLight_201809 I was able to open the iso in 7-zip, extract the level artwork as bmp files, produce the toy below. I've made a [followup article](/writing/night_light_1995) with the other assets. I first tried to approach it with mix-blend-mode, but I don't think you can use those effects to produce arbitrary image masks. I got it done with a more traditional method of translating a background-image property. The only jank fix I'm not really happy about is the background-size property for the flashlight layer, which I had to set using px values in javascript to match the rendered size of the parent. All the other background-size options created ill effects when I wanted to change the size of the flashlight to anything other than 100%. But I'm not that good with CSS and there might be a better answer. Please turn off your flashlight first. Or don't, and enjoy the two effects together!
Have fun! [footnote_text] [Archived here](tonsky_me.html) in case it gets changed. [footnote_text] A little vanity goes a long way!