div#params
label(for="#num_of_dots") Number of dots:
input(type="number" value="80" onChange="setParams()")#num_of_dots
label(for="#max_distance") Maximum distance:
input(type="number" value="150" onChange="setParams()")#max_distance
div#blur
div#container
h1 Floating Dots with Pixi.js
p Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.
View Compiled
html
overflow hidden
background #042C52
background-image radial-gradient(circle farthest-corner at 50% 0%, #1464B2, #042C52)
label, h1, p
color #e0e0e0
p
width 40em
label
display block
opacity .75
margin-top 1em
#params
top 20px
left 20px
position absolute
opacity .9
#blur
position absolute
top 50%
left 50%
width 600px
height 300px
transform translateX(-50%) translateY(-50%)
background rgba(#0E5191, 0.8)
filter blur(40px)
#container
position absolute
top 50%
left 50%
transform translateX(-50%) translateY(-50%)
View Compiled
(function(window, document, undefined) {
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var body = document.getElementsByTagName('body')[0];
var Dots = new Array();
var TOTAL_DOTS = document.getElementById('num_of_dots').value;
var DISTANCE = document.getElementById('max_distance').value;
var GRAVITY = 0.0001;
window.setParams = function() {
TOTAL_DOTS = document.getElementById('num_of_dots').value;
DISTANCE = document.getElementById('max_distance').value;
if (TOTAL_DOTS < Dots.length) {
var del = Dots.length - TOTAL_DOTS;
Dots.splice(TOTAL_DOTS, del);
}
if (TOTAL_DOTS > Dots.length) {
var create = TOTAL_DOTS - Dots.length;
for (var i = 0; i < create; i++) {
var dot = new Dot();
Dots.push(dot);
}
}
}
function Dot() {
this.x = 0;
this.y = 0;
this.vy = 0;
this.vx = 0;
this.r = 2 + 2 * Math.random();
this.c = 0x86A4C1;
this.reset();
}
Dot.prototype.reset = function() {
this.x = (Math.random() * WIDTH);
this.y = (Math.random() * HEIGHT);
var rand = Math.random();
this.vx = (2 * Math.random() + 0.1) * 3 / this.r;
if (rand > .5) {
this.vx = -1 * this.vx;
}
rand = Math.random();
this.vy = (2 * Math.random() + 0.1) * 3 / this.r;
if (rand > .5) {
this.vy = -1 * (2 * Math.random() + 0.1) * 1;
}
}
Dot.prototype.collisionCheck = function() {
if (this.x < 0 - this.r - DISTANCE) this.x = WIDTH;
if (this.x > WIDTH + this.r + DISTANCE) this.x = 0;
if (this.y < 0 - this.r - DISTANCE) this.y = HEIGHT;
if (this.y > HEIGHT + this.r + DISTANCE) this.y = 0;
}
for (var i = 0; i < TOTAL_DOTS; i++) {
var dot = new Dot();
Dots.push(dot);
}
function distance(x1, y1, x2, y2) {
var xdiff = x1 - x2;
var ydiff = y1 - y2;
return Math.sqrt(xdiff * xdiff + ydiff * ydiff);
}
// create a renderer instance.
var renderer = PIXI.autoDetectRenderer(WIDTH, HEIGHT, {
'transparent':true,
'autoResize': true,
'antialias': true,
});
// add the renderer view element to the DOM
document.body.appendChild(renderer.view);
requestAnimationFrame(animate);
var graphics = new PIXI.Graphics();
function animate() {
graphics.clear();
for (var i = 0; i < Dots.length; i++) {
var dot1 = Dots[i];
dot1.collisionCheck();
drawDot(graphics, dot1);
for (var j = i + 1; j < Dots.length; j++) {
var dot2 = Dots[j];
var x1 = dot1.x;
var x2 = dot2.x;
var y1 = dot1.y;
var y2 = dot2.y;
var dist = distance(x1, y1, x2, y2);
if (dist <= DISTANCE) {
var normalizedDist = dist / DISTANCE;
var lineWidth = (dot1.r + dot2.r) * 0.3 / (2 * Math.sqrt(normalizedDist) + 0.00001);
var alpha = 1.0 - (normalizedDist * normalizedDist);
graphics.lineStyle(lineWidth, dot.c, alpha);
var x1r = (0.5 + x1) << 0;
var y1r = (0.5 + y1) << 0;
var x2r = (0.5 + x2) << 0;
var y2r = (0.5 + y2) << 0;
graphics.moveTo(x1r, y1r);
graphics.lineTo(x2r, y2r);
var x1next = dot1.x + dot1.vx;
var y1next = dot1.y + dot1.vy;
var x2next = dot2.x + dot2.vx;
var y2next = dot2.y + dot2.vy;
var distnext = distance(x1next, y1next, x2next, y2next);
if (distnext <= dist) {
// dots are getting closer
dot1.x += GRAVITY * dot2.r * x2 * Math.pow(normalizedDist, 2);
dot2.x += GRAVITY * dot1.r * x1 * Math.pow(normalizedDist, 2);
dot1.y += GRAVITY * dot2.r * y2 * Math.pow(normalizedDist, 2);
dot2.y += GRAVITY * dot1.r * y1 * Math.pow(normalizedDist, 2);
} else {
dot1.x -= GRAVITY * dot2.r * x2 * Math.pow(normalizedDist, 2);
dot2.x -= GRAVITY * dot1.r * x1 * Math.pow(normalizedDist, 2);
dot1.y -= GRAVITY * dot2.r * y2 * Math.pow(normalizedDist, 2);
dot2.y -= GRAVITY * dot1.r * y1 * Math.pow(normalizedDist, 2);
}
}
}
dot1.y += dot1.vy;
dot1.x += dot1.vx;
}
// render the stage
renderer.render(graphics);
requestAnimationFrame(animate);
}
function drawDot(graphics, dot) {
graphics.beginFill(dot.c, 1.0);
graphics.drawCircle(dot.x, dot.y, dot.r);
graphics.endFill();
}
}(window, document));
This Pen doesn't use any external CSS resources.