<!-- import shader-box -->
<script>window.ShaderBox=function(t){var e={};function i(s){if(e[s])return e[s].exports;var r=e[s]={i:s,l:!1,exports:{}};return t[s].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,s){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:s})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(s,r,function(e){return t[e]}.bind(null,r));return s},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="/",i(i.s=0)}([function(t,e,i){var s,r,h;h=i(1)(),s=class{constructor(t){var e,i,s,r,h,a;for(this.setViewport=this.setViewport.bind(this),this.canvas=t.canvas,this.grid=t.grid||[1,1],this.shaders=[],this.pos=[],this.gl=this.canvas.getContext("experimental-webgl",t.context||{antialias:!0,depth:!1}),this.gl||alert("failed to start webgl :("),this.focus=-1,this.setViewport(),t.resize&&window.addEventListener("resize",this.setViewport),t.clearColor?this.gl.clearColor(t.clearColor[0],t.clearColor[1],t.clearColor[2],t.clearColor[3]):this.gl.clearColor(0,0,0,1),a=e=0,s=this.grid[1];0<=s?e<s:e>s;a=0<=s?++e:--e)for(h=i=0,r=this.grid[0];0<=r?i<r:i>r;h=0<=r?++i:--i)this.pos.push({x:h,y:a});this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null)}createBuffer(t,e,i){var s,r,h,a,o;return s=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,s),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(i),this.gl.STATIC_DRAW),r=1-this.grid[0]+2*t,h=this.grid[1]-1-2*e,s.u_move={origin:[r,h],state:[r,h],stage:[r,h]},a=1/this.grid[0],o=1/this.grid[1],s.u_scale={origin:[a,o],state:[a,o],stage:[a,o]},s}setViewport(){var t,e,i,s,r;for(this.canvas.width=this.width=this.canvas.clientWidth,this.canvas.height=this.height=this.canvas.clientHeight,this.gl.viewport(0,0,this.width,this.height),s=[],t=0,e=(i=this.shaders).length;t<e;t++)r=i[t],s.push(r.setUvBuffer(r.index));return s}add(t){return t.init(this,this.shaders.length),this.shaders.push(t),this}clear(){return this.gl.clear(this.gl.COLOR_BUFFER_BIT|this.gl.DEPTH_BUFFER_BIT),this}draw(t){var e,i,s,r,h,a,o;if(!t.gl)throw new Error("shader has not been added.");for(i=i||0,o=t.vert_buffer,this.gl.useProgram(t.program),t.updateUvBuffer(),this.focus>=0?t.index===this.focus?(o.u_move.state[0]=o.u_move.state[1]=0,o.u_scale.state[0]=o.u_scale.state[1]=1):o.u_scale.state[0]=o.u_scale.state[1]=0:(o.u_move.state[0]=o.u_move.origin[0],o.u_move.state[1]=o.u_move.origin[1],o.u_scale.state[0]=o.u_scale.origin[0],o.u_scale.state[1]=o.u_scale.origin[1]),o.u_move.stage[0]+=.25*(o.u_move.state[0]-o.u_move.stage[0]),o.u_move.stage[1]+=.25*(o.u_move.state[1]-o.u_move.stage[1]),o.u_scale.stage[0]+=.25*(o.u_scale.state[0]-o.u_scale.stage[0]),o.u_scale.stage[1]+=.25*(o.u_scale.state[1]-o.u_scale.stage[1]),this.gl.uniform2f(t.u_move,o.u_move.stage[0],o.u_move.stage[1]),this.gl.uniform2f(t.u_scale,o.u_scale.stage[0],o.u_scale.stage[1]),s=0,r=(h=t._uniforms).length;s<r;s++)(a=h[s]).isArray?a.set(a.loc,t.uniforms[a.name].value):(e=t.uniforms[a.name],Array.isArray(e.value)?a.set(a.loc,e.value[0],e.value[1],e.value[2],e.value[3]):a.set(a.loc,e.value));return this.gl.bindBuffer(this.gl.ARRAY_BUFFER,o),this.gl.vertexAttribPointer(t.a_position,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(t.a_position),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,t.uv_buffer),this.gl.vertexAttribPointer(t.a_texture,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(t.a_texture),t.texture&&(this.gl.bindTexture(this.gl.TEXTURE_2D,t.texture),this.gl.uniform1i(t.u_texture,0)),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4),this}},r=class{constructor(t){this.code=t.source,this.textureUrl=t.textureUrl,this.uniforms=t.uniforms,this._uniforms=[],this.focus=!1,this.uv=t.uv||[1,1]}updateUvBuffer(){return this.box.focus!==this.index||this.focus?this.box.focus!==this.index&&this.focus?(this.focus=!1,this.setUvBuffer(this.index)):void 0:(this.focus=!0,this.setUvBuffer(this.index))}setUvBuffer(t){var e,i,s;return this.focus?(i=this.box.width/this.uv[0],e=this.box.height/this.uv[1]):(i=this.box.width/this.uv[0]/this.box.grid[0],e=this.box.height/this.uv[1]/this.box.grid[1]),s=.5-i/e/2,.5-e/i/2,0,this.uv_buffer=this.box.createBuffer(this.box.pos[t].x,this.box.pos[t].y,[s,1,s,0,1-s,1,1-s,0])}setVertBuffer(t){return this.vert_buffer=this.box.createBuffer(this.box.pos[t].x,this.box.pos[t].y,[-1,-1,-1,1,1,-1,1,1])}init(t,e){var i,s,r,a,o,l;for(s in this.box=t,this.index=e,this.setUvBuffer(this.index),this.setVertBuffer(this.index),this.gl=this.box.gl,this.program=this.createProgram(h,this.code),this.a_position=this.gl.getAttribLocation(this.program,"a_position"),this.a_texture=this.gl.getAttribLocation(this.program,"a_texture"),this.u_move=this.gl.getUniformLocation(this.program,"u_move"),this.u_scale=this.gl.getUniformLocation(this.program,"u_scale"),this.u_texture=this.gl.getUniformLocation(this.program,"u_texture"),this.textureUrl&&(this.texture=this.gl.createTexture(),this.gl.bindTexture(this.gl.TEXTURE_2D,this.texture),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,1,1,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,new Uint8Array([0,0,255,255])),(i=new Image).crossOrigin="",i.src=this.textureUrl,i.addEventListener("load",t=>(this.gl.bindTexture(this.gl.TEXTURE_2D,this.texture),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,i),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.setUvBuffer(this.index)))),a=[],r=this.uniforms)l=r[s],o={loc:this.gl.getUniformLocation(this.program,s),set:this.gl["uniform"+l.type].bind(this.gl),name:s,isArray:null!=l.type.match(/v$/)},a.push(this._uniforms.push(o));return a}createProgram(t,e){var i,s,r;if(i=this.gl.createShader(this.gl.FRAGMENT_SHADER),this.gl.shaderSource(i,e),this.gl.compileShader(i),!this.gl.getShaderParameter(i,this.gl.COMPILE_STATUS))throw new Error("\nFRAGMENT_COMPILE_ERROR:\n\n"+this.gl.getShaderInfoLog(i)+"\nSOURCE:\n\n"+this.gl.getShaderSource(i));if(r=this.gl.createShader(this.gl.VERTEX_SHADER),this.gl.shaderSource(r,t),this.gl.compileShader(r),!this.gl.getShaderParameter(r,this.gl.COMPILE_STATUS))throw new Error("\nVERTEX_COMPILE_ERROR:\n\n"+this.gl.getShaderInfoLog(r)+"\nSOURCE:\n\n"+gl.getShaderSource(r));if(s=this.gl.createProgram(),this.gl.attachShader(s,i),this.gl.attachShader(s,r),this.gl.linkProgram(s),!this.gl.getProgramParameter(s,this.gl.LINK_STATUS))throw new Error("SHADER_LINK_"+this.gl.getProgramInfoLog(s));return s}},t.exports={Box:s,Shader:r}},function(t,e){t.exports=(t=>"attribute vec2 a_position;\nattribute vec2 a_texture;\nuniform vec2 u_move;\nuniform vec2 u_scale;\nvarying vec2 v_uv;\nvoid main() {\n\tgl_Position = vec4((a_position + u_move) * u_scale, 0.0, 1.0);\n\tv_uv = a_texture;\n}\n")}]);</script>
<canvas id="asd"></canvas>
<link href="https://fonts.googleapis.com/css?family=VT323&display=swap" rel="stylesheet">
<div id="banner">0XF48 2020</div>
body,html,#asd{
  margin: 0;
  width: 100vw;
  height: 100vh;
  background: green;
}
#banner{
  position: absolute;
  bottom: 10%;
  left: 50%;
  color: white;
  font-size: .8em;
  opacity: 0.7;
  letter-spacing: 6px;
  font-family: "VT323", monospace;
  transform: translate(-50%,-50%);
}
# apparently people can't get enough of these, so this is final and best toggle button to trump all other toggle buttons, dont even bother trying to make a cooler f u t u r e looking toggle button than this.
toggle_shader = """

precision highp float;
uniform float alpha;
uniform float beta;
uniform sampler2D u_texture;
varying vec2 v_uv;
uniform vec2 res;
uniform float time;

float meatball(vec2 p, float r){return r / dot(p, p);} //https://www.shadertoy.com/view/XsXGRS

float sdRoundBox( in vec2 p, in vec2 b, in float r ){ //iq
  vec2 q = abs(p) - b;
  return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r;
}

float normpdf(in float x, in float sigma){ return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma; }

vec3 blur(sampler2D source, vec2 coord,vec2 res){ //https://www.shadertoy.com/view/XdfGDH
		const int mSize = 15;
		const int kSize = (mSize-1)/2;
		float kernel[mSize];
		vec3 final_colour = vec3(0.0);
		float sigma = 7.0;
		float Z = 0.0;
		for (int j = 0; j <= kSize; ++j)
		{
			kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j), sigma);
		}
		for (int j = 0; j < mSize; ++j)
		{
			Z += kernel[j];
		}
		for (int i=-kSize; i <= kSize; ++i)
		{
			for (int j=-kSize; j <= kSize; ++j)
			{
				final_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(source, (coord.xy+vec2(float(i),float(j)))/res.xy).rgb;
	
			}
		}
  return final_colour/(Z*Z);
}
  
void main(){
  float w = 1.05/(res.y/min(res.x,res.y));
  float h = .1/(res.y/min(res.x,res.y));
  float r = 0.05;
  vec2 dim = vec2(w,h);
  float scale = res.y/600.0;
  float blur_radius = 40.0;
  vec2 blur_size = vec2(res*.2);
  vec2 bg_uv = vec2((v_uv.x-0.5)*scale+0.5,(v_uv.y-0.5)*scale+0.5);

  float box = smoothstep(0.1,0.2,sdRoundBox((v_uv-0.5)*20.,dim,2.0));
  float box_outer = smoothstep(0.1,0.15,sdRoundBox((v_uv-0.5)*15.5,dim,2.0));
  float box_outer_pad = smoothstep(0.1,0.2,sdRoundBox((v_uv-0.5)*14.,dim,2.0));
  float box_inner = smoothstep(0.2,0.1,sdRoundBox(vec2((v_uv.x-0.5)*23.0+w*1.*(1.0-alpha),(v_uv.y-0.5)*25.),vec2(dim.x*(alpha),dim.y),2.0));

  vec2 toggle_pos = vec2((v_uv.x-0.5)-(w/20.)*(-1.0+alpha*2.)-(beta*.5*w/25.*(1.0-alpha*2.)),v_uv.y-0.5)*25.;
  vec2 toggle_pos_right = vec2((v_uv.x-0.5)-(w/20.)*(1.3),v_uv.y-0.5)*25.;
  vec2 toggle_pos_left = vec2((v_uv.x-0.5)+(w/20.)*(1.3),v_uv.y-0.5)*25.;
  float beta_scale = (1.0-beta*.1);
  float beta_scale2 = (1.0-beta*.1);
  float beta_scale3 = (1.0-beta*.5*(alpha));
  float beta_scale4 = (1.0-beta*.5*(1.0-alpha));
  float toggle = smoothstep(0.2,0.1,sdRoundBox(toggle_pos,vec2(dim.y,dim.y),2.*beta_scale));

  vec3 bg_box = vec3(0.0);

  vec3 blur_bg = vec3(0.0);
  if (box_outer_pad <= 0.0){
    blur_bg = blur(u_texture,bg_uv*100.0,vec2(100.0));
  }

  vec3 bg = texture2D( u_texture,bg_uv).xyz;

  bg_box.xyz *= (1.0-box);
  blur_bg *= (1.0-box_outer);
  bg.xyz *= (box_outer);

  float blob = smoothstep(.01,.011,meatball(toggle_pos_left,.008*beta_scale4)+meatball(toggle_pos,.042*beta_scale2));
  float inv_blob = smoothstep(.01,.011,meatball(toggle_pos_right,.008*beta_scale3)+meatball(toggle_pos,.042*beta_scale2));
  
  float wave_factor = 2.6/res.y;
  float wave_offset = alpha*3.0+time*0.1;
  float clamp_bg = smoothstep(0.5-251./res.y,0.5-250./res.y,v_uv.x+cos(v_uv.y*5.0-wave_offset)*beta*wave_factor)*smoothstep(0.5+251.0/res.y,0.5+250.0/res.y,v_uv.x+sin(v_uv.y*5.0+wave_offset)*beta*wave_factor)*smoothstep(0.1,0.104,v_uv.y+sin(v_uv.x*5.0-wave_offset)*beta*wave_factor)*smoothstep(0.904,0.9,v_uv.y+cos(v_uv.x*5.0+wave_offset)*beta*wave_factor);

  bg.xyz *= clamp_bg;
  vec3 green_blob = vec3(mix(.5,0.0,alpha)*blob,blob,mix(1.0,0.02*blob,alpha)*blob);
  vec3 color = bg*(.3+alpha*.7) + blur_bg*(1.1-alpha*.6) - (inv_blob*(1.0-toggle))*.3 + green_blob + toggle;
  gl_FragColor = vec4(color,1.0);
}
"""

box = new ShaderBox.Box
  canvas: window.asd
  resize: true #auto resize on window.resize
  clearColor: [0.0, 0.0, 0.0, 1.0]
  grid: [1,1]
  context:
    antialias: false
    depth: false

shader = new ShaderBox.Shader
  source: toggle_shader
  textureUrl: "https://storage.googleapis.com/ysid-dev/bg.jpg"
  uniforms:
    alpha:
      type: '1f'
      value: 0
    beta:
      type: '1f'
      value: 0
    res:
      type: '2fv'
      value: [window.innerWidth,window.innerHeight]
    time:
      type: '1f'

box.add shader

alpha_val = beta_val = 0

window.addEventListener 'mousedown',->
  beta_val = 1
window.addEventListener 'mouseup',->
  beta_val = 0
  alpha_val = 1-alpha_val
  
render = (t)->
    box.clear().draw(shader)
    shader.uniforms.res.value[0] = window.innerWidth
    shader.uniforms.res.value[1] = window.innerHeight
    shader.uniforms.time.value = t*0.001
    shader.uniforms.alpha.value += 0.09 * (alpha_val - shader.uniforms.alpha.value)
    shader.uniforms.beta.value += 0.09 * (beta_val - shader.uniforms.beta.value)
    requestAnimationFrame(render)

render()
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.