Skip to content

Instantly share code, notes, and snippets.

@Strangemother
Created February 24, 2022 01:20
Show Gist options
  • Save Strangemother/5adf34e560f952585b96099f0c1cb5ab to your computer and use it in GitHub Desktop.
Save Strangemother/5adf34e560f952585b96099f0c1cb5ab to your computer and use it in GitHub Desktop.
Perlin Disruption
<canvas id="canvas"></canvas>
var Utils = {
setCanvasSize: function(){
canvas.width = document.documentElement.clientWidth,
canvas.height = document.documentElement.clientHeight;
canvas.setAttribute("width", canvas.width);
canvas.setAttribute("height", canvas.height);
},
addEvents: function() {
window.addEventListener(
'resize', function() {
Utils.setCanvasSize();
refresh()
}
);
},
degToRad: function(deg) {
return deg * Math.PI / 180;
},
randInt: function(min, max) {
return Math.floor(Math.random()*max)+min;
},
reload: function() {
window.location.reload();
}
};
function Generator(params) {
this.x = params.x;
this.y = params.y;
this.particleCount = 1500;
this.initialDistance = 100;
this.distanceThreshold = 10;
this.thresholdVariation = 100;
this.seed_1 = 1;
this.seed_2 = 0;
this.particleSize = 1;
this.particleRotationSpeed = .05;
this.particleDistanceSpeed = 3;
this.perlinAmp = this.newPerlinAmp = 1;
this.perlinAmpIncrease = true;
this.perlinIncreaseSpeed = .2;
this.particles = [];
this.populate();
}
var G = Generator.prototype;
G.populate = function() {
for (var i = 0; i < this.particleCount; i++) {
this.particles.push(new Particle({
x: this.x,
y: this.y,
angle: Utils.randInt(1,360),
distance: this.initialDistance,
distanceThreshold: this.distanceThreshold,
thresholdVariation: this.thresholdVariation,
color: (Math.random() < .5) ? "rgba(51, 204, 255,.02)" : "rgba(255, 50, 50,.02)",
size: this.particleSize,
}));
}
}
G.draw = function() {
if (this.perlinAmpIncrease) this.newPerlinAmp -= this.perlinIncreaseSpeed;
this.particles.forEach(function(particle) {
particle.move();
});
}
function Particle(params) {
this.initX = this.x = params.x || canvas.width / 2;
this.initY = this.y = params.y || canvas.height / 2;
this.angle = Utils.degToRad(params.angle || Utils.randInt(1,360));
this.distance = params.distance;
this.x = this.initX + Math.cos(this.angle) * this.distance;
this.y = this.initY + Math.sin(this.angle) * this.distance;
this.distanceThreshold = params.distanceThreshold + Utils.randInt(0,params.thresholdVariation);
this.color = params.color;
this.size = params.size || 1;
}
var P = Particle.prototype;
P.move = function() {
if (this.distance < this.distanceThreshold) {
this.distance += generator.particleDistanceSpeed + generator.newPerlinAmp * perlin.noise(
this.x * generator.seed_1,
this.y * generator.seed_2,
1);
} else {
this.distance += generator.newPerlinAmp * perlin.noise(
this.x * generator.seed_1,
this.y * generator.seed_2,
1);
}
this.angle += Utils.degToRad(generator.particleRotationSpeed);
this.x = this.initX + Math.cos(this.angle) * this.distance;
this.y = this.initY + Math.sin(this.angle) * this.distance;
this.draw();
}
P.draw = function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size);
}
var perlin = new ClassicalNoise(),
canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
generator,
gui,
globalParams = {
compositeOperation: true
};
(function init(){
Utils.setCanvasSize();
Utils.addEvents();
generator = new Generator({
x: canvas.width / 2,
y: canvas.height / 2
});
gui = new dat.GUI();
var folder_0 = gui.addFolder('Global');
folder_0.open();
folder_0.add(globalParams, 'compositeOperation').onFinishChange(refresh);
var folder_1 = gui.addFolder('Generator');
folder_1.open();
folder_1.add(generator, 'particleCount', 1, 5000).step(10).onFinishChange(refresh);
folder_1.add(generator, 'initialDistance', -100, 100).step(10).onFinishChange(refresh);
folder_1.add(generator, 'distanceThreshold', 0, 1000).step(10).onFinishChange(refresh);
folder_1.add(generator, 'seed_1', 0, 5).onFinishChange(refresh);
folder_1.add(generator, 'seed_2', 0, 5).onFinishChange(refresh);
folder_1.add(generator, 'perlinAmp', 0, 100).step(1).onFinishChange(refresh);
folder_1.add(generator, 'perlinAmpIncrease').onFinishChange(refresh);
folder_1.add(generator, 'perlinIncreaseSpeed', 0, 10).onFinishChange(refresh);
var folder_2 = gui.addFolder('Particles');
folder_2.open();
folder_2.add(generator, 'thresholdVariation', 0, 500).step(1).onFinishChange(refresh);
folder_2.add(generator, 'particleSize', 1, 3).step(1).onFinishChange(refresh);
folder_2.add(generator, 'particleRotationSpeed', 0, 3).onFinishChange(refresh);
folder_2.add(generator, 'particleDistanceSpeed', 0, 3).onFinishChange(refresh);
generator.populate();
animate();
})();
function refresh() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
generator.particles = [];
generator.newPerlinAmp = generator.perlinAmp;
generator.populate();
}
function animate() {
if (globalParams.compositeOperation) {
ctx.fillStyle = "rgba(0,0,0,.02)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "lighter";
} else {
ctx.fillStyle = "rgba(0,0,0,1)";
//ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "source-over";
}
generator.draw();
requestAnimationFrame(animate);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.0/dat.gui.min.js"></script>
<script src="https://codepen.io/Thibka/pen/LWGOWR"></script>
html,
body {
margin: 0;
overflow: hidden;
background-color: black;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment