JSFiddle - React, Tailwind, and code Playground

HTML

<div id="effect"></div>
        <div id="info"></div>

        <script id="vs" type="x-shader/x-vertex">
            attribute vec3 position;
            void main() {
                gl_Position = vec4( position, 1.0 );
            }
        </script>

        <script id="fs" type="x-shader/x-fragment">
            uniform float time;
            uniform vec2 resolution;
            uniform vec2 aspect;

            void main( void ) {

                vec2 position = -aspect.xy + 2.0 * gl_FragCoord.xy / resolution.xy * aspect.xy;
                float angle = 0.0 ;
                float radius = length(position) ;
                if (position.x != 0.0 && position.y != 0.0){
                    angle = degrees(atan(position.y,position.x)) ;
                }
                float amod = mod(angle+30.0*time-120.0*log(radius), 30.0) ;
                if (amod<15.0){
                    gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
                } else{
                    gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );                    
                }
            }

        </script>

CSS

body {
                background-color: #000000;
                margin: 0px;
                overflow: hidden;
            }
            

            #info {
                position: absolute;
                top: 0px;

                color: #ffff88;
                font-family: Monospace;
                font-size: 14px;
                font-weight: bold;
                text-shadow: rgba( 0, 0, 0, 0.75 ) 0px 1px 2px;
                background-color: rgba(0,0,0,0.8) ;
                padding: 1em;
            }

JavaScript

var effectDiv, sourceDiv, canvas, gl, buffer, vertex_shader, fragment_shader, currentProgram,
            vertex_position, parameters = { start_time: new Date().getTime(), time: 0, screenWidth: 0, screenHeight: 0 };

            init();
            setInterval( loop, 1000 / 60 );

            function init() {

                vertex_shader = document.getElementById( 'vs' ).textContent;
                fragment_shader = document.getElementById( 'fs' ).textContent;

                effectDiv = document.getElementById( 'effect' );
                sourceDiv = document.getElementById( 'info' );
                sourceDiv.innerHTML = '--- adapted from http://mrdoob.com/lab/javascript/webgl/glsl/02/ by mrdoob<br/>'+
                                    '--- answer for http://stackoverflow.com/questions/4638317'

                canvas = document.createElement( 'canvas' );
                effectDiv.appendChild( canvas );

                // Initialise WebGL

                try {

                    gl = canvas.getContext( 'experimental-webgl' );

                } catch( error ) { }

                if ( !gl ) {

                    alert("WebGL not supported");
                    throw "cannot create webgl context";

                }

                // Create Vertex buffer (2 triangles)

                buffer = gl.createBuffer();
                gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
                gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( [ - 1.0, - 1.0, 1.0, - 1.0, - 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, - 1.0, 1.0 ] ), gl.STATIC_DRAW );

                // Create Program

                currentProgram = createProgram( vertex_shader, fragment_shader );

                onWindowResize();
                window.addEventListener( 'resize', onWindowResize, false );

            }

            function createProgram( vertex, fragment ) {

                var program = gl.createProgram();

                var vs = createShader( vertex, gl.VERTEX_SHADER );
      ...