Last active
May 20, 2017 19:22
Revisions
-
micahstubbs revised this gist
May 20, 2017 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
micahstubbs revised this gist
May 20, 2017 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ an experiment that swaps the color source [chroma.brewer.YlGnBu](https://gka.github.io/chroma.js/#chroma-brewer) for [d3.interpolateMagma(t)](https://github.com/d3/d3-scale#interpolateMagma) an iteration on the block [ReGL circle animation example](http://bl.ocks.org/rflow/39692bd181fb1eb0b077a4caf886b077) from [@ajdant](https://twitter.com/ajdant) -
micahstubbs created this gist
May 20, 2017 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,2 @@ border: no license: Apache-2.0 This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,5 @@ an experiment that swaps the [chroma.brewer.YlGnBu](https://gka.github.io/chroma.js/#chroma-brewer) for [d3.interpolateMagma(t)](https://github.com/d3/d3-scale#interpolateMagma) an iteration on the block [ReGL circle animation example](http://bl.ocks.org/rflow/39692bd181fb1eb0b077a4caf886b077) from [@ajdant](https://twitter.com/ajdant) commit history and related experiments [here](https://github.com/micahstubbs/regl-experiments) This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,7 @@ <html> <body> <script src='https://cdnjs.cloudflare.com/ajax/libs/regl/1.3.0/regl.min.js'></script> <script src='https://d3js.org/d3.v4.min.js'></script> <script src='vis.js'></script> </body> </html> This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,12 @@ # safe lebab --replace vis.js --transform arrow lebab --replace vis.js --transform for-of lebab --replace vis.js --transform for-each lebab --replace vis.js --transform arg-rest lebab --replace vis.js --transform arg-spread lebab --replace vis.js --transform obj-method lebab --replace vis.js --transform obj-shorthand lebab --replace vis.js --transform multi-var # unsafe lebab --replace vis.js --transform let lebab --replace vis.js --transform template LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.Binary file not shown.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,225 @@ /* global createREGL document window */ const regl = createREGL(); const doc = document.body; const docWidth = window.innerWidth; const docHeight = window.innerHeight; const aspectRatio = docHeight / docWidth; const colCount = 150; const colWidth = docWidth / colCount; const rowCount = parseInt(colCount * aspectRatio, 10); const rowHeight = docHeight / rowCount; const circleCount = rowCount * colCount; const maxRadius = Math.min(colWidth, rowHeight) / 2; const minScale = 1e-6; // use small number to avoid reaching zero const maxScale = 1.0; const randomScale = () => minScale + ((maxScale - minScale) * Math.random()); // sample nine colors from the magma color space const palette = [0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0].map(t => d3.interpolateMagma(t)); console.log('palette', palette); // gl mode uses [r,g,b] vector w normalised values const paletteGL = palette.map(d => { const cGL = d3.color(d).rgb(); return [cGL.r, cGL.g, cGL.b].map(e => e / 255); }); console.log('paletteGL', paletteGL); const randomColor = () => paletteGL[Math.floor(palette.length * Math.random())]; const getGridPoints = (cols, rows, colWidth, rowHeight, gridWidth, gridHeight) => { const count = cols * rows; const points = new Float32Array(count * 2); let col; let row; let xPos; let yPos; let xIndex; let yIndex; for (let i = 0; i < count; i += 1) { col = i % cols; row = parseInt(i / cols, 10); xPos = (col * colWidth) + (colWidth / 2); yPos = (row * rowHeight) + (rowHeight / 2); xIndex = (2 * i); yIndex = xIndex + 1; points[xIndex] = ((2 * xPos) / gridWidth) - 1; // convert to (-1, 1) GL coord space points[yIndex] = ((2 * yPos) / gridHeight) - 1; // convert to (-1, 1) GL coord space } return points; }; const getAnimStates = (count) => { const colors = new Float32Array(count * 3); const scales = new Float32Array(count); let r; let g; let b; let rIndex; let gIndex; let bIndex; for (let i = 0; i < count; i += 1) { [r, g, b] = randomColor(); rIndex = (3 * i); gIndex = rIndex + 1; bIndex = rIndex + 2; colors[rIndex] = r; colors[gIndex] = g; colors[bIndex] = b; scales[i] = randomScale(); } return { colors, scales }; }; // build inputs for our animation: const centroids = getGridPoints(colCount, rowCount, colWidth, rowHeight, docWidth, docHeight); // create a series of animation states for each circle const numStates = 50; const allStates = []; while (allStates.length < numStates) { allStates.push(getAnimStates(circleCount)); } // regl command featuring shaders that will draw supplied points const drawPoints = regl({ vert: ` precision highp float; uniform float progress; // interpolation progress (from 0.0 to 1.0) uniform float maxRadius; // max radius to draw (n.b. point is square of 2*r x 2*r) attribute vec2 point; // position at which to draw attribute float scaleA; // scale factor A attribute float scaleB; // scale factor B attribute vec3 colorA; // color A attribute vec3 colorB; // color B varying vec3 rgb; // interpolated color varying float scale; // interpolated scale void main () { rgb = mix(colorA, colorB, progress); scale = mix(scaleA, scaleB, progress); gl_PointSize = maxRadius * 2. * scale; gl_Position = vec4(point, 0, 1); } `, frag: ` precision highp float; varying vec3 rgb; varying float scale; void main () { // determine normalized distance from center of point float point_dist = length(gl_PointCoord * 2. - 1.); // calc scale at which to start fading out the circle float min_dist = scale * 0.70; // calc scale at which we find the edge of the circle float max_dist = scale; // https://thebookofshaders.com/glossary/?search=smoothstep float alpha = 1. - smoothstep(min_dist, max_dist, point_dist); gl_FragColor = vec4(rgb, alpha); } `, // using textbook example from http://regl.party/api#blending blend: { enable: true, func: { srcRGB: 'src alpha', srcAlpha: 1, dstRGB: 'one minus src alpha', dstAlpha: 1, }, equation: { rgb: 'add', alpha: 'add', }, color: [0, 0, 0, 0], }, attributes: { point: centroids, colorA: regl.prop('currColors'), colorB: regl.prop('nextColors'), scaleA: regl.prop('currScales'), scaleB: regl.prop('nextScales'), }, uniforms: { maxRadius, progress: regl.prop('progress'), }, count: circleCount, primitive: 'points', }); // render loop const fps = 60; const tweenTime = 2; const tweenFrames = fps * tweenTime; let state = 0; regl.frame(({ tick }) => { regl.clear({ color: [0, 0, 0, 1], depth: 1, }); // increment frame counter until we reach the desired loop point const frame = tick % tweenFrames; // increment state counter once we've looped back around if (frame === 0) { state = (state + 1) % numStates; // console.log('state counter', state); } // track progress as proportion of frames completed const progress = frame / tweenFrames; // determine current and next state const currState = allStates[state]; const nextState = allStates[(state + 1) % numStates]; drawPoints({ currColors: currState.colors, currScales: currState.scales, nextColors: nextState.colors, nextScales: nextState.scales, progress, }); });