ultraviolet

Super ⚡ performant 2D graphics library backed by WebGL2

<script src='https://ultraviolet.js.org/uv.min.js'></script> <canvas width='500' height='300' id='canvas'></canvas> <script> const ctx = setTargetCanvas(document.getElementById('canvas')) // ... </script>
This library exposes drawing functionalities much like OpenGL: Build meshes and draw them with GLSL shaders
At the same time making best use of JS paradigm and APIs

// autoCanvas() is a convenience function to replace setTargetCanvas() // Make sure to call it before anything else const ctx = autoCanvas(everyFrame) const cat = Texture().fromSrc('./sample.png') let rot = 0 function everyFrame(width, height, dt){ rot += dt // Edit me! ctx.translate(width/2, height/2) const mesh = makeCatpheus(160 + Math.sin(rot*4)*10, rot) ctx.draw(mesh, cat) drawParticles(ctx.sub(), height, dt) } // You can create one mesh ahead of time and pre-upload it for increased performance // const mesh = makeCatpheus().upload() function makeCatpheus(rad = 170, rot = 0){ const msh = Mesh() msh.rotate(rot) msh.addRect(-100, -100, 200, 200) msh.rotate(-rot*2) for(let i = 0; i < 16; i++){ const wave = Math.sin((PI2*(i/16) - rot)*5)*15 // addRect(x, y, width, height, uv, effect, tint_r, tint_g, tint_b, tint_a) // Here we imagine the image to be broken into a 4x4 grid // and we choose a sub-square based on i msh.addRect(-10, rad + wave, 20, 20, uv(i%4/4, Math.floor(i/4)/4, .25, .25)) msh.rotate(PI2/16) } return msh.upload() } // Shaders! The particles change color as they fall const particleShader = Shader(`void main(){ color = texture(tex0, uv.xy); float x = abs(effect-.5); color.rgb = (color.rrr*x - color.bbb*x + color.bbb*(1.-x))*.3; }`, [NORM]) const particles = new Float32Array(100) for(let i = 0; i < particles.length; i++) particles[i] = Math.random() const additiveBlend = Blend(ONE, ADD, ONE) // src*1 + dst*1 function drawParticles(subCtx, h, dt){ const mesh = Mesh() subCtx.shader = particleShader // Go left mesh.translate(-202,0) let prevY = 0 for(let i = 0; i < 100; i++){ const pos = particles[i], pos2 = pos*pos mesh.translate(4, -(pos2-prevY)*(h+16)) mesh.addRect(-8, -8, 16, 16, _, (pos+i/5)%1) prevY = pos2 particles[i] = (pos+dt/2)%1 } subCtx.translate(0,h/2+8) subCtx.blend = additiveBlend subCtx.draw(mesh, cat) }