<html>
<head>
<title>WebGL Demo</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script id="shader-fs" type="x-shader/x-fragment">
precision highp float;
const float PI = 3.14159265359;
uniform float uTime;
uniform vec2 uResolution;
float random(float p) {
return fract(sin(p) * 10000.);
}
float noise(vec2 p) {
float t = uTime / 2000.;
if (t > 1.)
t -= floor(t);
return random(p.x * 14. + p.y * sin(t) * .05);
}
vec2 sw(vec2 p) {
return vec2(floor(p.x), floor(p.y));
}
vec2 se(vec2 p) {
return vec2(ceil(p.x), floor(p.y));
}
vec2 nw(vec2 p) {
return vec2(floor(p.x), ceil(p.y));
}
vec2 ne(vec2 p) {
return vec2(ceil(p.x), ceil(p.y));
}
float smoothNoise(vec2 p) {
vec2 inter = smoothstep(0., 1., fract(p));
float s = mix(noise(sw(p)), noise(se(p)), inter.x);
float n = mix(noise(nw(p)), noise(ne(p)), inter.x);
return mix(s, n, inter.y);
}
mat2 rotate(in float theta) {
float c = cos(theta);
float s = sin(theta);
return mat2(c, -s, s, c);
}
float circ(vec2 p) {
float r = length(p);
r = log(sqrt(r));
return abs(mod(4. * r, PI * 2.) - PI) * 3. + .2;
}
float fbm(in vec2 p) {
float z = 2.;
float rz = 0.;
vec2 bp = p;
for (float i = 1.; i < 6.; i++)
{
rz += abs((smoothNoise(p) - 0.5)* 2.) / z;
z = z * 2.;
p = p * 2.;
}
return rz;
}
void main() {
vec2 p = gl_FragCoord.xy / uResolution.xy - .5;
p.x *= uResolution.x / uResolution.y;
p *= 4.;
float rz = fbm(p);
p /= exp(mod(uTime * 1.5, PI));
rz *= pow(abs(0.1 - circ(p)), .9);
vec3 col = vec3(0.2, 0.1, 0.643) / rz;
gl_FragColor = vec4(col, 1.0);
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
void main() {
gl_Position = vec4(aVertexPosition, 1.0);
}
</script>
<script>
var canvas, gl;
var vertexPositionLocation;
var resolutionLocation, resolution;
var timeLocation, time;
var startTime;
var vertices = [
-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0
];
function resize() {
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
gl.viewport(0, 0, canvas.width, canvas.height);
}
function compileShader(shaderSource, shaderType) {
var shader = gl.createShader(shaderType);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
return shader;
}
function getShader(id){
var shaderScript = document.getElementById(id);
var shaderSource = "";
var textLine = shaderScript.firstChild;
while(textLine) {
// 3 - TEXT_NODE
if (textLine.nodeType == 3)
shaderSource += textLine.textContent;
textLine = textLine.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment")
shader = compileShader(shaderSource, gl.FRAGMENT_SHADER)
else if (shaderScript.type == "x-shader/x-vertex")
shader = compileShader(shaderSource, gl.VERTEX_SHADER);
else
return null;
return shader;
}
function drawScene(){
gl.uniform1f(timeLocation, time);
gl.uniform2fv(resolutionLocation, resolution);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
function render() {
requestAnimationFrame(render);
resolution = [canvas.width, canvas.height];
time = (Date.now() - startTime) / 1000;
drawScene();
};
function bootstrap() {
canvas = document.getElementById("holder");
gl = canvas.getContext("experimental-webgl"); // OpenGL ES 2.0
resize();
window.addEventListener("resize", resize);
var fragmentShader = getShader("shader-fs");
var vertexShader = getShader("shader-vs");
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
resolutionLocation = gl.getUniformLocation(shaderProgram,
"uResolution");
timeLocation = gl.getUniformLocation(shaderProgram,
"uTime");
vertexPositionLocation =
gl.getAttribLocation(shaderProgram, "aVertexPosition");
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array(vertices), gl.STATIC_DRAW);
gl.enableVertexAttribArray(vertexPositionLocation);
gl.vertexAttribPointer(vertexPositionLocation, 2, gl.FLOAT, false, 0, 0);
startTime = Date.now();
render();
}
</script>
<style>
body {
position: absolute;
left: 0;
top: 0;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
canvas {
position: relative;
border: none;
width: 100%;
height: 100%;
}
</style>
</head>
<body onload="bootstrap();">
<canvas id="holder"></canvas>
</body>
</html>
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |