Skip to content

Instantly share code, notes, and snippets.

@nucliweb
Created August 11, 2020 10:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nucliweb/1d723f86d38b77dcd77ff3d4212381c8 to your computer and use it in GitHub Desktop.
Save nucliweb/1d723f86d38b77dcd77ff3d4212381c8 to your computer and use it in GitHub Desktop.
mojo working
<canvas id="canvas"></canvas>
<canvas id="postprocessing"></canvas>
<script id="shader-fs" type="x-shader/x-fragment">
precision highp float;
uniform sampler2D uImage;
uniform vec2 uResolution;
uniform float uTime;
varying vec2 vTexCoord;
void main() {
// shader adapted from https://www.shadertoy.com/view/XdXXD4#
vec2 uv = gl_FragCoord.xy / uResolution;
float d = length(uv - vec2(0.5,0.5));
vec4 textureColor = texture2D(uImage, vec2(vTexCoord.s, vTexCoord.t));
// rgb glitch
float blur = 0.0;
blur = (1.0 + sin(uTime*6.0)) * 0.5;
blur *= 1.0 + sin(uTime*16.0) * 0.5;
blur = pow(blur, 3.0);
blur *= 0.05;
blur *= d;
textureColor.r = texture2D( uImage, vec2(uv.x+blur,uv.y) ).r;
textureColor.g = texture2D( uImage, uv ).g;
textureColor.b = texture2D( uImage, vec2(uv.x-blur,uv.y) ).b;
// scanline
float scanline = sin(uv.y*uResolution.y*1.0)*0.04;
textureColor -= scanline;
// vignette
textureColor *= 1.2 - d * 1.5;
// final pixel
gl_FragColor = vec4(textureColor.rgb, 1.0);
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec2 aPosition;
attribute vec2 aTexCoord;
uniform vec2 uResolution;
varying vec2 vTexCoord;
void main() {
vec2 zeroToOne = aPosition / uResolution;
vec2 zeroToTwo = zeroToOne * 2.0;
vec2 clipSpace = zeroToTwo - 1.0;
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
vTexCoord = aTexCoord;
}
</script>

mojo working

This pen features two distinct things. (1) In the JavaScript section, a 'normal" CANVAS 2D interactive demo. (2) Applied on top of it, a WebGL postprocessing effect. GLSL shaders are in the HTML section, the postprocessor is linked from another pen. Integration is relatively easy, feel free to ask in comments if interested...

A Pen by Gerard Ferrandez on CodePen.

License.

! function () {
"use strict";
var prev, img,
particles = 100,
pos = new Array(particles);
// particle constructor
function Particle (x, y) {
this.x = x;
this.px = x;
this.y = y;
this.py = y;
this.dx = 0;
this.dy = 0;
this.next = true;
this.prev = prev;
prev = this;
}
Particle.prototype.link = function () {
if (pointer.hasMoved) {
var vx = this.x - pointer.x;
var vy = this.y - pointer.y;
var d = Math.sqrt(vx * vx + vy * vy);
if (d < 100) {
d = (100 - d) / d;
this.dx += vx * d * .2;
this.dy += vy * d * .2;
}
}
var vx = this.prev.x - this.x;
var vy = this.prev.y - this.y;
var d = Math.sqrt(vx * vx + vy * vy);
if (d > 0) {
d = ((5 - d) / d) / 30;
var dx = vx * d;
var dy = vy * d;
this.dx -= dx;
this.dy -= dy;
this.prev.dx += dx;
this.prev.dy += dy;
}
return this.next;
}
Particle.prototype.update = function () {
this.x += this.dx;
this.y += this.dy;
var w = (img.width || 0) * 0.5;
ctx.drawImage(img, this.x - w, this.y - w);
var vx = this.x - this.px;
var vy = this.y - this.py;
this.px = this.x;
this.py = this.y;
this.x += vx;
this.y += vy;
this.dx = 0;
this.dy = 0;
if (this.x < 0) this.dx = Math.abs(vx) * .1;
else if (this.x > canvas.width) this.dx = -Math.abs(vx) * .1;
if (this.y < 0) this.dy = Math.abs(vy) * .1;
else if (this.y > canvas.height) this.dy = -Math.abs(vy) * .1;
return this.next;
}
// main loop
var run = function () {
requestAnimationFrame(run);
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
var i;
// update velocity
for (
i = 0;
pos[i++].update();
);
// links
for (
i = 1;
pos[i++].link();
);
pointer.hasMoved = false;
// webgl postprocessing draw call
postprocessing.render();
}
// initialization
var canvas = ge1doot.canvas("canvas");
var ctx = canvas.ctx;
var pointer = canvas.pointer;
pointer.move = function () {
pointer.hasMoved = true;
}
// particle image
img = new Image();
img.crossOrigin = "Anonymous";
img.src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/222599/sphere-monochrome.png";
// create particles
for (var i = 0; i < particles; i++ ) {
pos[i] = new Particle (
i * canvas.width / particles,
canvas.height * .5 + Math.sin(i/10) * canvas.height * .25
);
}
pos[particles - 1].next = false;
// initalize webgl postprocessor
var postprocessing = new ge1doot.postprocessing({flipY:true});
run();
}();
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222599/canvas-pointer.js"></script>
<script src="https://codepen.io/ge1doot/pen/0cb7efcffc03d2df74ff29141bdb45ac"></script>
html {
overflow: hidden;
touch-action: none;
content-zooming: none;
}
body {
position:absolute;
margin:0;
padding:0;
background:#fff;
width:100%;
height:100%;
}
#canvas, #postprocessing {
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
background:#FFF;
pointer-events: all;
}
#postprocessing {
pointer-events: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment