How do I achive a grainy effect using an SVG after inlining it from a file?

5 days ago 13
ARTICLE AD BOX

I have an SVG as a file

<svg viewBox="0 0 200 200" xmlns='http://www.w3.org/2000/svg'> <filter id='noiseFilter'> <feTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch' /> </filter> <rect width='100%' height='100%' filter='url(#noiseFilter)' /> </svg>

It gets used as a background in css

.noise { height: 100%; background: linear-gradient(90deg, black, transparent), url(noise.svg); filter: contrast(170%) brightness(500%); }

This gives me the grainy effect I am after (from this tutorial).

But I need to be able to edit this svg with JS, which I can't do if its a file due to CORS. So I have tried a few ways to add the svg into the html directly so I can edit it, however the effect is lost.

<!DOCTYPE html> <html lang="en"> <head> <title>NoiseTest</title> <meta charset="utf-8"> </head> <body> <!--https://css-tricks.com/grainy-gradients/--> <style> body { display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 10px; height: 100vh; margin: 0; background-color: powderblue; } section { position: relative; width: 300px; height: 300px; box-shadow: rgb(50 50 93 / 20%) 0px 30px 60px -12px, rgb(0 0 0 / 28%) 0px 18px 36px -18px; } .noise { height: 100%; background: linear-gradient(90deg, black, transparent), url(noise.svg); filter: contrast(170%) brightness(500%); } /* Chrome-specific */ @media all and (-webkit-min-device-pixel-ratio:0) and (min-resolution: .001dpcm) { .noise { filter: contrast(290%) brightness(500%); } } .isolate { isolation: isolate; position: relative; width: 100%; height: 100%; } /*Test - SVG in div*/ .bg { height: 100%; background: linear-gradient(90deg, black, transparent); } .svg-bg { position: absolute; inset: 0; mix-blend-mode: multiply; filter: brightness(500%); } /*Test - SVG as filter*/ .bg1 { height: 100%; background: linear-gradient(90deg, black, transparent); filter: url(#noiseFilter1); } </style> <section> <div class="isolate"> <div class="noise"></div> </div> </section> <!--in div test--> <section> <div class="isolate"> <svg class="svg-bg" viewBox="0 0 200 200" xmlns='http://www.w3.org/2000/svg'> <filter id='noiseFilter'> <feTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch' /> </filter> <rect width='100%' height='100%' filter='url(#noiseFilter)' /> </svg> <div class="bg"></div> </div> </section> <!--as filter test--> <section> <div class="isolate"> <div class="bg1"></div> </div> </section> <svg style="display:none" xmlns='http://www.w3.org/2000/svg'> <filter id='noiseFilter1'> <feTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch' /> <feColorMatrix type="saturate" values="10"/> <feBlend in="SourceGraphic" mode="multiply"/> </filter> </svg> <script> </script> </body> </html>

Top square show the desired effect with noise applied to a gradient while the bottom two squares show the results of tests trying to replicate the first square with different techniques.

Top div is the goal and the other two are what I have been able to accomplish.

So how do I get this effect using an SVG I can edit with JS?

Read Entire Article