Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<body style="overflow:hidden;margin:0;">
  <canvas id="canvas" style="width:100%;height:100%;"></canvas>
</body>
<script>
 
var now = window.performance && performance.now ? function() { return performance.now(); } : function() { return +new Date(); };
var _requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || setTimeout;
function createShader(vertexSource, fragmentSource) {
  function compileShader(type, source) {
    var shader = gl.createShader(type);
    gl.shaderSource(shader, source);
    gl.compileShader(shader);
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
      throw new Error('Compile error: ' + gl.getShaderInfoLog(shader));
    }
    gl.attachShader(program, shader);
  }
  var program = gl.createProgram();
  compileShader(gl.VERTEX_SHADER, vertexSource);
  compileShader(gl.FRAGMENT_SHADER, fragmentSource);
  gl.linkProgram(program);
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    throw new Error('Link error: ' + gl.getProgramInfoLog(program));
  }
  return program;
}
var gl = canvas.getContext('experimental-webgl', { antialias: false, alpha: false, depth: false, stencil: false });
var buffer = gl.createBuffer();
var shader = createShader('\
  precision highp float;\
  attribute vec2 vertex;\
  varying vec2 coord;\
  void main() {\
    coord = vertex;\
    gl_Position = vec4(vertex, 0.0, 1.0);\
  }\
', '\
  precision highp float;\
  uniform vec2 viewport;\
  uniform vec2 offset;\
  uniform float zoom;\
  varying vec2 coord;\
  void main() {\
    vec2 grid = coord * viewport * pow(2.0, zoom * 0.01) + offset;\
    vec2 foo = fract(grid / 512.0);\
    gl_FragColor = vec4(foo, 0.0, 1.0);\
  }\
');
var viewportUniform = gl.getUniformLocation(shader, 'viewport');
var zoomUniform = gl.getUniformLocation(shader, 'zoom');
var offsetUniform = gl.getUniformLocation(shader, 'offset');
var previousTime = now();
var frameCount = 0;
var zoom = 0;
var offsetX = 0;
var offsetY = 0;
gl.useProgram(shader);
gl.enableVertexAttribArray(0);
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -1, -1, 1, -1, -1, 1, 1, 1 ]), gl.DYNAMIC_DRAW);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
window.onwheel = function(e) {
  e.preventDefault();
  if (e.ctrlKey) {
    zoom += e.deltaY;
  } else {
    offsetX += e.deltaX * 2;
    offsetY -= e.deltaY * 2;
  }
};
function render() {
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.uniform2f(offsetUniform, offsetX, offsetY);
  gl.uniform1f(zoomUniform, zoom);
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  var nextTime = now();
  var deltaTime = (nextTime - previousTime) / 1000;
  frameCount++;
  if (deltaTime > 1) {
    document.title = (frameCount / deltaTime).toFixed(1) + 'fps';
    previousTime = nextTime;
    frameCount = 0;
  }
  _requestAnimationFrame(render);
}
function resize() {
  var dpr = window.devicePixelRatio || 1;
  // dpr = 1;
  gl.canvas.width = innerWidth * dpr;
  gl.canvas.height = innerHeight * dpr;
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  gl.uniform2f(viewportUniform, innerWidth, innerHeight);
}
window.onresize = resize;
resize();
render();
</script>
</body>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers