A while ago (8 years in fact) I wanted to make something like this. I made a slightly half-assed React library that used twgl to overlay a shader on an element on a page (or a canvas for some effects). One thing I had was measuring where an element was on the page and then using absolute positioning to put a canvas over it so effects could expand beyond the confines of the element. I still think that has potential for some fun things but browsers aren't really fast enough to keep it in the right place with scrolling so it never works properly. https://react-neon.ooer.com/ + https://github.com/onion2k/react-neon

These new libraries are much better than anything I came up with.

Can you elaborate on the scrolling issue?

It’s a WebGL issue, fixed in WebGPU.

Browsers generally only allow a fixed number of WebGL contexts per page. So a generic element effect library has the issue that too many elements some will start losing contexts. The workaround is to just make one large screen size canvas and then figure out where the elements are you need to draw an effect for. now you only have one context drawing all the elements. But, you can’t know where to draw until the browser scrolls and renders so you’re always one frame behind.

https://webgl2fundamentals.org/webgl/lessons/webgl-multiple-...

WebGPU doesn’t have this issue. You can use the same device with multiple canvases

https://webgpufundamentals.org/webgpu/lessons/webgpu-multipl...

It's been a while so I might be a little off, but the problem was that the effect would lag behind slightly (one frame?) because I used an observer to match where the element moved to because the overlay element was logged to the viewport. I think I did that to avoid having a canvas that was the size of the entire page. Where a canvas could just be abs positioned it was ok but for reasons I can't remember that didn't work for everything.