I have to create some falling snowflakes in javascript, but they have change current path if they get collision with other flake. Something like on this image:
Here is my current code: http://codepen.io/wojtek1150/pen/QyaYdY
var flakePositions = [[]];
var temp = 0;
// snowflake proto
function Snowflake() {
this.pos = new Physics();
// snowflake guid
this.id = '';
// inits
this.MAX_X_START_POS = 100;
this.X_START_OFFSET = 0;
this.MAX_Y_START_POS = 50;
this.Y_START_OFFSET = -50;
this.MAX_X_SPEED = 4;
this.MAX_Y_SPEED = 1.2;
// use to get sin && cos
this.animationStepsCounter = 0
this.fallFactor = 100;
// snowflake html
this.getId = function () {
if (this.id == '') {
this.id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
function (c) {
var r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
return this.id;
}
this.initalize = function () {
temp++;
//var size = 5 + Math.random() * 20;
var size = 20;
this.flakeDOM.style.width = size + "px";
this.flakeDOM.style.height = size + "px";
this.flakeDOM.style.opacity = Math.random();
this.pos.x = (Math.random() * this.MAX_X_START_POS);
this.pos.y = this.Y_START_OFFSET+(Math.random() * this.MAX_Y_START_POS);
this.pos.xSpeed = Math.random() * this.MAX_X_SPEED* Math.sign(-0.5 + Math.random());
this.pos.ySpeed = Math.random() * this.MAX_Y_SPEED;
//create array
flakePositions[temp] = [];
flakePositions[temp]['id'] = this.id;
flakePositions[temp]['x'] = this.flakeDOM.style.top;
flakePositions[temp]['y'] = this.flakeDOM.style.left;
flakePositions[temp]['width'] = this.flakeDOM.style.width;
flakePositions[temp]['height'] = this.flakeDOM.style.height;
flakePositions[temp]['xspeed'] = this.pos.xSpeed;
flakePositions[temp]['yspeed'] = this.pos.ySpeed
}
this.move = function () {
this.flakeDOM.style.top = (this.pos.y+=this.pos.ySpeed) + "px";
this.flakeDOM.style.left = (this.pos.x += Math.sin(this.animationStepsCounter/this.fallFactor) * this.pos.xSpeed) + "px";
this.animationStepsCounter += this.pos.ySpeed;
//update array
flakePositions[temp]['x'] = this.flakeDOM.style.top;
flakePositions[temp]['y'] = this.flakeDOM.style.left;
//check position with rest
for (var i = 1, len = flakePositions.length; i < len-1; i++) {
var rect1 = flakePositions[i];
var rect1d = rect1['id'];
var rect1sx = rect1['xspeed'];
var rect1sy = rect1['yspeed'];
var rect1x = parseInt(rect1['x']);
var rect1y = parseInt(rect1['y']);
for (var j = 2, len = flakePositions.length; j < len; j++) {
var rect2 = flakePositions[j];
var rect2d = rect2['id'];
var rect2x = parseInt(rect2['x']);
var rect2y = parseInt(rect2['y']);
//if(rect1x == rect2x && rect1y == rect2y)
if(rect1x < rect2x + 10 && rect1x + 10 > rect2x &&
rect1y < rect2y + 10 && 10 + rect1y > rect2y )
{
console.log('collision detected');
var t = document.getElementById(rect1d);
t.style.top = t.style.top+rect1sx+10;
t.style.left = t.style.left+rect1sy-10;
}
}
}
}
}
function Physics() {
// pos
this.x = 0;
this.y = 0;
this.z = 0;
// speed
this.xSpeed = 0;
this.ySpeed = 0;
this.zSpeed = 0;
// acceleration
this.xAccel = 1;
this.yAccel = 1;
this.zAccel = 1;
}
snowflakes = new Array();
var interval = 0;
function makeThisBoom() {
// snowflakes container
snowfield = document.getElementById('snow');
// snowflakes count
snoflakesCount = 20;
for (var i = 0; i < snoflakesCount; i++) {
snowflakes[i] = new Snowflake();
var flake = document.createElement('div');
snowflakes[i].flakeDOM = flake;
flake.id = snowflakes[i].getId();
flake.classList.add('sf');
snow.appendChild(flake);
snowflakes[i].initalize();
snowflakes[i].move();
}
interval = setInterval(anime,50);
}
function anime() {
for (var flake of snowflakes) {
flake.move();
}
}
function setInterface() {
document.getElementById('startstop').onclick = function () {
if (interval != 0) {
clearInterval(interval);
interval = 0;
} else interval = setInterval(anime, 50);
}
}
document.addEventListener("DOMContentLoaded", makeThisBoom);
document.addEventListener("DOMContentLoaded", setInterface);
.sf{
position:absolute;
z-index:9999999;
/*background: -moz-radial-gradient(center, ellipse cover, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%);
background: -webkit-radial-gradient(center, ellipse cover, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%);
background: radial-gradient(ellipse at center, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#00ffffff',GradientType=1 );
*/
border-radius:50%;
display:block;
width:20px; height:20px;
/* FOR DEV ONLY */
background:#FFF;
opacity:1!important;
}
body{
background:#222;
overflow:hidden;
}
#snow {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
#startstop{
width:100px;
height:30px;
border:0;
background:rgb(61, 95, 123);
color:#FFF;
outline:none;
}
<button id="startstop">Start/stop</button>
<div id="snow"> </div>
I already know how to get positions and I got if statement to check if there is any collision. But I don't know how to change path in proper way, even just bounce it :(
Any suggestions?