Particle particulars
How do I make an particle particulars?
Learning about vectors and how they can represent position, speed and acceleration, allowing us to model particles. Click or touch for more explosions. What is a particle particulars? How do you make a particle particulars? This script and codes were developed by Nick Williams on 27 August 2022, Saturday.
Particle particulars - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Particle particulars</title> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="controls"> <label> # particles: <input type="range" id="particles" min="10" max="99" step="1" /> <output></output> </label>
</div>
<canvas id="canvas"></canvas> <script src="js/index.js"></script>
</body>
</html>
Particle particulars - Script Codes CSS Codes
html, body { margin:0; padding: 0;
}
canvas { display: block; -webkit-user-select: none; -moz-user-select: none; user-select: none;
}
body { font-family: sans-serif;
}
.controls { position: absolute; top : 0; right: 0; padding: 0.75em 1em; background-color: rgba(0,0,0,0.75); color: white; z-index:10;
}
Particle particulars - Script Codes JS Codes
var util = { random : function(minOrMax, max) { if(arguments.length === 1) { return minOrMax * Math.random(); } return minOrMax + (Math.random() * (max - minOrMax)); }, normalise : function(value, min, max) { return (value - min) / (max - min); }, between : function(value, min, max) { return (value > min) && (value < max); }, inBounds : function (x, y, width, height) { return this.between(x, 0, width) && this.between(y, 0, height); }, invoke : function(fn, args) { return function(obj) { return obj[fn].apply(obj, args); }; }
};
function fluent(fn) { return function() { fn.apply(this, arguments); return this; };
}
function Vector (x, y) { this.x = x || 0; this.y = y || 0;
}
Vector.prototype = { constructor : Vector, getX : function() { return this.x; }, setX : fluent(function(x) { this.x = x; }), getY : function() { return this.y; }, setY : fluent(function(y) { this.y = y; }), getAngle : function() { return Math.atan2(this.y, this.x); }, setAngle : fluent(function(angle) { var magnitude = this.getMagnitude(); this.x = Math.cos(angle) * magnitude; this.y = Math.sin(angle) * magnitude; }), getMagnitude : function() { return Math.sqrt( Math.pow(this.x, 2) + Math.pow(this.y, 2) ); }, setMagnitude : fluent(function(magnitude) { var angle = this.getAngle(); this.x = Math.cos(angle) * magnitude; this.y = Math.sin(angle) * magnitude; })
};
Vector.add = function(a, b) { return new Vector( a.getX() + b.getX(), a.getY() + b.getY() );
};
Vector.subtract = function(a, b) { return new Vector( a.getX() - b.getX(), a.getY() - b.getY() );
};
Vector.multiply = function(vector, value) { return new Vector( vector.getX() * value, vector.getY() * value );
};
Vector.divide = function(vector, value) { return new Vector( vector.getX() / value, vector.getY() / value );
};
function Particle (x, y, speed, direction) { this.position = new Vector(x, y); this.velocity = new Vector().setMagnitude(speed).setAngle(direction);
}
Particle.prototype = { constructor : Particle, update : fluent(function() { this.position = Vector.add(this.position, this.velocity); }), accelerate : fluent(function(acceleration) { this.velocity = Vector.add(this.velocity, acceleration); }), getPositionX : function() { return this.position.getX(); }, setPositionX : fluent(function(x) { this.position.setX(x); }), getPositionY : function() { return this.position.getY(); }, setPositionY : fluent(function(y) { this.position.setY(y); })
};
function Canvas (elem, width, height) { this.width = elem.width = (width * Canvas.pixelRatio); this.height = elem.height = (height * Canvas.pixelRatio); elem.style.height = "100%"; elem.style.width = "100%"; this.context = elem.getContext("2d"); this.context.scale(Canvas.pixelRatio, Canvas.pixelRatio); this.setSmoothing(false);
}
Canvas.prototype = { constructor : Canvas, setSmoothing : fluent(function(value) { this.context.webkitImageSmoothingEnabled = value; this.context.mozImageSmoothingEnabled = value; this.context.msImageSmoothingEnabled = value; this.context.imageSmoothingEnabled = value; }), clear : fluent(function(width, height) { width = width || this.width; height = height || this.height; this.context.clearRect(0, 0, width, height); }), rect : fluent(function(x, y, width, height) { x = x || 0; y = y || 0; width = width || this.width; height = height || this.height; this.context.beginPath(); this.context.rect(x, y, width, height); }), circle : fluent(function (x, y, radius) { this.context.beginPath(); this.context.arc(x, y, radius, Math.PI * 2, false); }), fill : fluent(function(color) { color = color || "#000000"; this.context.fillStyle = color; this.context.fill(); }), stroke : fluent(function(color) { color = color || "#000000"; this.context.strokeStyle = color; this.context.stroke(); })
};
Canvas.pixelRatio = window.devicePixelRatio || 1;
var NUM_PARTICLES = 40 / Canvas.pixelRatio; // make it easier for devices pushing more pixels
var FADE = "rgba(255,255,255,0.008)";
function RandomParticle (x, y) { this.particle = new Particle(x, y, util.random(3, 15), util.random(Math.PI * 2)); this.color = RandomParticle.randomColor(); this.radius = util.random(3, 15);
}
RandomParticle.prototype = { constructor : RandomParticle, gravity : new Vector(0, 0.1), render : function(canvas) { this.particle.accelerate(this.gravity).update(); canvas .circle(this.particle.getPositionX(), this.particle.getPositionY(), this.radius) .fill(this.color); }, isVisible : function(width, height) { var x = this.particle.getPositionX(); var y = this.particle.getPositionY(); return util.inBounds(x, y, width, height); }
};
RandomParticle.randomColor = function() { return "hsl(" + util.random(0, 360) + ", 75%, 60%)";
};
RandomParticle.createExplosion = function(x, y) { var explosion = []; for(var i = 0; i < NUM_PARTICLES; i++) { explosion.push(new RandomParticle(x, y)); } return explosion;
};
window.onload = function() { debugger; var width = window.innerWidth; var height = window.innerHeight; var canvas = new Canvas(document.querySelector("#canvas"), width, height); var particles = RandomParticle.createExplosion(width / 2, height / 2); var renderParticle = util.invoke("render", [canvas]); var filterVisibleParticles = util.invoke("isVisible", [width, height]); function render() { if(particles.length) { canvas.rect().fill(FADE); particles.forEach(renderParticle); particles = particles.filter(filterVisibleParticles); } requestAnimationFrame(render); } render(); function explode(e) { e = e.touches ? e.touches[0] : e; particles = particles.concat(RandomParticle.createExplosion(e.clientX, e.clientY)); } document.addEventListener("click", explode); document.addEventListener("touchend", explode); var output = document.querySelector("output"); var slider = document.querySelector("#particles"); slider.value = output.innerHTML = NUM_PARTICLES; slider.addEventListener("input", function(e) { NUM_PARTICLES = output.innerHTML = this.valueAsNumber; });
};
Developer | Nick Williams |
Username | WickyNilliams |
Uploaded | August 27, 2022 |
Rating | 3.5 |
Size | 3,688 Kb |
Views | 32,384 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Headroom.js demo | 3,982 Kb |
Block, Element, Modifier in LESS | 1,735 Kb |
Closure classic | 1,842 Kb |
Pointed | 2,630 Kb |
Conditional Lightbox for Responsive Design | 2,792 Kb |
Got your callback | 2,451 Kb |
A Pen by Nick Williams | 1,616 Kb |
JS module pattern demo | 4,111 Kb |
Gridzzz | 3,199 Kb |
Bokeh | 4,253 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Slide out Menu | Rbiggs | 4,936 Kb |
A Pen by Mohomed Anees | Mohomedanees | 12,597 Kb |
Simple personal profile | Miroot | 2,856 Kb |
Mapbox Directions with geolocation tracking | Pollardld | 5,827 Kb |
Cool Page Split Effect | Anthonyadamski | 6,128 Kb |
JavaScript constructors | Simboonlong | 2,415 Kb |
Basic HTML Slideshow | Tomhodgins | 3,386 Kb |
Scarlett Johansson Tribute Page | Diomed | 3,233 Kb |
Website Concept | Sagoza | 3,104 Kb |
LAMP PURE CSS with Animation | Dam62500 | 2,911 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!