I can't delete dom element 'img' in onclick function of Object - javascript

I write a simple bubble game(I create Array and he has bubble Objects) and Bubble has to burst, when I click it(so I delete dom img), but i can't apply to dom elemnt in function onclick. Why? How can I apply to my dom element(IMG) or how can I delete dom img in func onclick????
My Object "bubble"
enter image description here
Google Chrome Inspector write...enter image description here
Full Code:
function resize() {
Grass.width = document.documentElement.clientWidth;
Grass.style.left = 0 + 'px';
Grass.style.top = document.documentElement.clientHeight - 180 + 'px';
}
function bubble(id) {
this.IMG = document.createElement('img');
this.IMG.src = './bubble.png';
this.IMG.id = id;
this.IMG.onclick = function () {
document.getElementById(this.IMG.id).parentNode.removeChild(document.getElementById(this.IMG.id));
}
this.createBubble = function () {
this.bubbleSize = Math.random() * (144 - 30) + 30;
this.bomDiapozon = Math.random() * (75 - 55) + 55;
this.IMG.style.width = this.bubbleSize + 'px';
this.IMG.style.height = this.bubbleSize + 'px';
this.xStart = Math.random() * document.documentElement.clientWidth;
this.yStart = -Math.random() * document.documentElement.clientHeight;
this.x = this.xStart;
this.y = this.yStart;
this.xSpeed = Math.random() * (9 + 9) - 9;
this.ySpeed = Math.random() * (5 - 1) + 1;
this.flyWidth = Math.random() * (288 - 144) + 144;
}
this.createBubble();
document.body.appendChild(this.IMG);
this.fly = function () {
if (this.y + this.bubbleSize >= document.documentElement.clientHeight - this.bomDiapozon) {
this.createBubble();
}
if ((this.x >= this.xStart + this.flyWidth / 2) || (this.x <= this.xStart - this.flyWidth / 2)) {
this.xSpeed = -this.xSpeed;
}
this.IMG.style.left = this.x + 'px';
this.IMG.style.top = this.y + 'px';
this.x += this.xSpeed;
this.y += this.ySpeed;
}
}
function go() {
for (var i = 0; i < amountBubbles; i++) {
bubbles[i].fly();
}
}
document.body.style.overflow = 'hidden';
var amountBubbles = 30;
var bubbles = [];
for (var i = 0; i < amountBubbles; i++) {
bubbles[i] = new bubble(i + 1);
}
var Grass = document.createElement('img');
Grass.src = './Grass.png';
document.body.appendChild(Grass);
resize();
setInterval(go, 40);
img {
position:absolute;
}

You already have access to the event and node without needing to re-select it. Try this:
this.IMG.onclick = function(event) {
var parent = event.target.parentElement;
parent.removeChild(event.target)
}

Welcome to Stalk Overflow!
In your anonymous function there is no context to this.
The snippet below binds this to that function, and it will be no longer undefined:
this.IMG.onclick = (function () {
document.getElementById(this.IMG.id).parentNode.removeChild(document.getElementById(this.IMG.id));
}).bind(this)
Just notice how you wrap it with () and then add .bind(this) to it.
Another way to bind the context is by using an arrow function:
this.IMG.onclick = () => {
document.getElementById(this.IMG.id).parentNode.removeChild(document.getElementById(this.IMG.id));
}
This arrow function binds this, arguments and super to your method.
Read more on arrow functions here
See it working below with .bind(this):
function resize() {
Grass.width = document.documentElement.clientWidth;
Grass.style.left = 0 + 'px';
Grass.style.top = document.documentElement.clientHeight - 180 + 'px';
}
function bubble(id) {
this.IMG = document.createElement('img');
this.IMG.src = './bubble.png';
this.IMG.id = id;
this.IMG.onclick = (function () {
document.getElementById(this.IMG.id).parentNode.removeChild(document.getElementById(this.IMG.id));
}).bind(this)
this.createBubble = function () {
this.bubbleSize = Math.random() * (144 - 30) + 30;
this.bomDiapozon = Math.random() * (75 - 55) + 55;
this.IMG.style.width = this.bubbleSize + 'px';
this.IMG.style.height = this.bubbleSize + 'px';
this.xStart = Math.random() * document.documentElement.clientWidth;
this.yStart = -Math.random() * document.documentElement.clientHeight;
this.x = this.xStart;
this.y = this.yStart;
this.xSpeed = Math.random() * (9 + 9) - 9;
this.ySpeed = Math.random() * (5 - 1) + 1;
this.flyWidth = Math.random() * (288 - 144) + 144;
}
this.createBubble();
document.body.appendChild(this.IMG);
this.fly = function () {
if (this.y + this.bubbleSize >= document.documentElement.clientHeight - this.bomDiapozon) {
this.createBubble();
}
if ((this.x >= this.xStart + this.flyWidth / 2) || (this.x <= this.xStart - this.flyWidth / 2)) {
this.xSpeed = -this.xSpeed;
}
this.IMG.style.left = this.x + 'px';
this.IMG.style.top = this.y + 'px';
this.x += this.xSpeed;
this.y += this.ySpeed;
}
}
function go() {
for (var i = 0; i < amountBubbles; i++) {
bubbles[i].fly();
}
}
document.body.style.overflow = 'hidden';
var amountBubbles = 30;
var bubbles = [];
for (var i = 0; i < amountBubbles; i++) {
bubbles[i] = new bubble(i + 1);
}
var Grass = document.createElement('img');
Grass.src = './Grass.png';
document.body.appendChild(Grass);
resize();
setInterval(go, 40);
img {
position:absolute;
}

Related

Why won't the image load

What is wrong with the code, I can't find the problem. I think it's because of the drawFrame and loadImage function, but I don't know. So is there a way to make the image load and you will still be able to move it around and shoot?
And when I try to remove the drawFrame function nothing would work. And if posiible is there a way to change the bullet from squares to circles?
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8">
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
canvas {
cursor: crosshair;
background-color: cornflowerblue;
}
</style>
</head>
<body>
<canvas id="Trump"></canvas>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
(async function main() {
var canvas = document.getElementById('Trump');
if (!canvas.getContext) return;
var ctx = canvas.getContext('2d');
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
//const fps = 60;
const ronaNum = 30; // number of particles at start
const ronaSize = 70; // corona size
const ronaSpeed = 100; // speed
let chinabmg;
function draw() {
$("canvas").one("click", function () {
chinabmg = new sound("stankytrumpchina.mp3");
chinabmg.play();
});
//mutes when clicked on m
document.body.onkeyup = function (e) {
if (e.keyCode == 77) { chinabmg.stop() }
};
//compatability
var requestAnimationFrame = window.requestAnimationFrame || //Chromium
window.webkitRequestAnimationFrame || //Webkit
window.mozRequestAnimationFrame || //Mozilla Geko
window.oRequestAnimationFrame || //Opera Presto
window.msRequestAnimationFrame || //IE Trident?
function (callback) { //Fallback function
window.setTimeout(callback, 1000 / 60);
};
var DrawX = 0;
var DrawY = 0;
var time = 0;
var width = canvas.width;
var height = canvas.height;
var offTop = canvas.offsetTop;
var offLeft = canvas.offsetLeft;
var rectWidth = 15;
var rectHeight = 15;
var speed = 1;
var x = width / 2;
var y = height / 2;
var size = 30;
var id = 0;
var bulletId = 0;
function sound(src) {
this.sound = document.createElement("audio");
this.sound.src = src;
this.sound.setAttribute("preload", "auto");
this.sound.setAttribute("controls", "none");
this.sound.setAttribute("loop", "auto");
this.sound.style.display = "none";
document.body.appendChild(this.sound);
this.play = function () {
this.sound.play();
}
this.stop = function () {
this.sound.pause();
}
}
function player(id, color, size, x, y) {
this.id = id;
this.color = color;
this.size = size;
this.x = x;
this.y = y;
this.speed = speed;
}
var playerList = [];
function addPlayer(color, size, x, y) {
playerList[id] = new player(id, color, size, x, y);
id += 1;
}
addPlayer("blue", size, width / 2 - 50, height / 2);
var pressedKeys = [];
function moveLeft(checkId, checkX, checkY, cSize, cSpeed, cKey) {
var x = checkX - cSpeed;
var y = checkY - cSpeed;
var x2 = checkX + cSize + cSpeed;
var y2 = checkY + cSize + cSpeed;
if (x > 0) {
playerList[checkId].x = checkX - cSpeed;
} else {
playerList[checkId].x = 0;
}
}
function moveUp(checkId, checkX, checkY, cSize, cSpeed, cKey) {
var x = checkX - cSpeed;
var y = checkY - cSpeed;
var x2 = checkX + cSize + cSpeed;
var y2 = checkY + cSize + cSpeed;
if (y > 0) {
playerList[checkId].y = checkY - cSpeed;
} else {
playerList[checkId].y = 0;
}
}
function moveRight(checkId, checkX, checkY, cSize, cSpeed, cKey) {
var x = checkX - cSpeed;
var y = checkY - cSpeed;
var x2 = checkX + cSize + cSpeed;
var y2 = checkY + cSize + cSpeed;
if (x2 < width) {
playerList[checkId].x = checkX + cSpeed;
} else {
playerList[checkId].x = width - cSize;
}
}
function moveDown(checkId, checkX, checkY, cSize, cSpeed, cKey) {
var x = checkX - cSpeed;
var y = checkY - cSpeed;
var x2 = checkX + cSize + cSpeed;
var y2 = checkY + cSize + cSpeed;
if (y2 < height) {
playerList[checkId].y = checkY + cSpeed;
} else {
playerList[checkId].y = height - cSize;
}
}
function Move(checkId, checkX, checkY, cSize, cSpeed, cKey) {
if (checkId === 0) {
switch (cKey) {
case 65:
// left
moveLeft(checkId, checkX, checkY, cSize, cSpeed, cKey);
break;
case 87:
// up
moveUp(checkId, checkX, checkY, cSize, cSpeed, cKey);
break;
case 68:
// right
moveRight(checkId, checkX, checkY, cSize, cSpeed, cKey);
break;
case 83:
// down
moveDown(checkId, checkX, checkY, cSize, cSpeed, cKey);
break;
default:
return; // exit this handler for other keys
}
}
}
var validKeys = [];
validKeys[0] = "65,87,68,83-107,109,80";
// == KEYDOWN ==
$(document.body).keydown(function (e) {
e.preventDefault();
//go through all players
$.each(playerList, function (i, currentPlayer) {
if (validKeys[currentPlayer.id].indexOf(e.which) == -1) return true;
if (!pressedKeys[e.which]) {
//set interval for the function
pressedKeys[e.which] = setInterval(function () {
Move(currentPlayer.id, currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, e.which);
}, 5);
}
});
});
// == KEYUP ==
$(document.body).keyup(function (e) {
if (pressedKeys[e.which]) {
clearInterval(pressedKeys[e.which]);
delete pressedKeys[e.which];
}
});
//=============================== SHOOTING ===============================
//Bullets
function bullet(id, color, size, speed, x, y, eX, eY) {
this.id = id;
this.color = color;
this.size = size;
this.x = x;
this.y = y;
this.eX = eX;
this.eY = eY;
this.velocityX = 1;
this.velocityY = 1;
this.speed = 9;
}
var bulletList = [];
function addBullet(color, bsize, bspeed, x, y, eX, eY) {
bulletList[bulletId] = new bullet(bulletId, color, bsize, 9, x, y, eX, eY);
bulletId += 1;
}
function updateBullet(bullet, player) {
var dx = (bullet.eX - player.x);
var dy = (bullet.eY - player.y);
var mag = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = (dx / mag) * 9;
bullet.velocityY = (dy / mag) * 9;
bullet.x += bullet.velocityX;
bullet.y += bullet.velocityY;
}
// Add event listener for `click` events.
canvas.onmousedown = function (e) {
addBullet("#696969", 10, 2, playerList[0].x, playerList[0].y, e.x, e.y);
};
//corona part
let corona = [];
createCoronaParticles();
// game loop
//setInterval(update, 1000 / fps);
function createCoronaParticles() {
corona = [];
let cx, cy;
for (var i = 0; i < ronaNum; i++) {
do {
cx = Math.floor(Math.random() * canvas.width);
cy = Math.floor(Math.random() * canvas.height);
} while (noSpawnOnFigure(canvas.height / 2, canvas.width / 2, cy, cx) < ronaSize * 5);
corona.push(newParticle(cx, cy));
}
}
function noSpawnOnFigure(cy1, cx1, cy2, cx2) {
return Math.sqrt(Math.pow(cy2 - cy1, 2) + Math.pow(cx2 - cx1, 2));
}
function newParticle(cx, cy) {
let rona = {
ca: Math.random() * Math.PI * 2, //radians
cr: ronaSize / 2,
cx: cx,
cy: cy,
cxv: Math.random() * ronaSpeed / 60 * (Math.random() < 0.5 ? 1 : -1),
cyv: Math.random() * ronaSpeed / 60 * (Math.random() < 0.5 ? 1 : -1)
};
return rona;
}
// function update() {
// }
// ======= DRAWING =======
function drawFrame() {
requestAnimationFrame(drawFrame);
ctx.font = "15pt Georgia"; // sets the font and font size of the text
ctx.clearRect(0, 0, width, height);
$.each(playerList, function (index, currentPlayer) {
//debug
//draw players
function loadImage(path) {
let image = new Image();
let promise = new Promise((resolve, reject) => {
image.onload = () => resolve(image);
image.onerror = reject
});
image.src = path;
return promise;
}
loadImage.src = 'trump.gif';
});
//draw bullets
$.each(bulletList, function (index, bullet) {
updateBullet(bullet, playerList[0]);
ctx.fillStyle = bullet.color;
ctx.fillRect(bullet.x, bullet.y, bullet.size, bullet.size);
});
// canvas
//ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw corona particles
ctx.strokeStyle = "rgb(150, 0, 0)";
ctx.lineWidth = 20;
let ca, cr, cx, cy;
for (let i = 0; i < corona.length; i++) {
// get properties
ca = corona[i].ca;
cr = corona[i].cr;
cx = corona[i].cx;
cy = corona[i].cy;
// draw path
ctx.beginPath();
ctx.fillStyle = "rgb(200, 0, 0)"
ctx.moveTo(
cx + cr * Math.cos(ca),
cy + cr * Math.sin(ca)
);
// draw circle
for (let j = 1; j < 180; j++) {
ctx.lineTo(
cx + cr * Math.cos(ca + j * Math.PI * 2 / 180),
cy + cr * Math.sin(ca + j * Math.PI * 2 / 180)
);
}
ctx.closePath();
ctx.stroke();
ctx.fill();
// move particles
corona[i].cx += corona[i].cxv;
corona[i].cy += corona[i].cyv;
// particle edge of screen
if (corona[i].cx < 0 - corona[i].cr) {
corona[i].cx = canvas.width + corona[i].cr;
} else if (corona[i].cx > canvas.width + corona[i].cr) {
corona[i].cx = 0 - corona[i].cr
}
if (corona[i].cy < 0 - corona[i].cr) {
corona[i].cy = canvas.height + corona[i].cr;
} else if (corona[i].cy > canvas.height + corona[i].cr) {
corona[i].cy = 0 - corona[i].cr
}
}
}
drawFrame();
}
$(draw);
}
)();
</script>
</body>
</html>
//draw players
function loadImage(path) {
let image = new Image();
let promise = new Promise((resolve, reject) => {
image.onload = () => resolve(image);
image.onerror = reject
});
image.src = path;
//Add the following line
ctx.drawImage(image,playerList[0].x,playerList[0].y);
return promise;
}
// change loadImage.src = 'trump.gif' into this
loadImage('trump.gif');

Binding timed events to DOM object with JavaScript

I'm trying to bind setInterval event to DOM objects. HTML and CSS is obsolete in this example. Tried different approaches but none seem to work. What am I missing here ?
window.onload = function() {
for (let index = 0; index < 20; index++) {
let x = new Box(Math.floor((Math.random() * 100) + 1), index + (index * 10), Math.floor((Math.random() * 100) + 1), 5);
}
}
var id = 0;
class Box{
constructor(x, y, size, speed){
this.speed = speed;
this.x = x;
this.y = y;
this.size = size;
this.id = id;
id++;
this.spawn();
this.move(this.id);
}
spawn(){
let x = document.createElement("div");
x.setAttribute("id", this.id);
x.setAttribute("class", "box");
x.style.top = this.y + 'px';
x.style.left = this.x + 'px';
x.style.width = this.size + 'px';
x.style.height = this.size + 'px';
document.body.appendChild(x);
}
move(id){
setInterval(function() {
document.getElementById(id).style.left = this.speed + 'px';
this.speed += 5;
}, 10);
}
}
The this in setInterval doesnt refer to the object you want, you need to pass in this when calling move, also they dont have a position
window.onload = function() {
for (let index = 0; index < 20; index++) {
let x = new Box(Math.floor((Math.random() * 100) + 1), index + (index * 10), Math.floor((Math.random() * 100) + 1), 5);
}
}
var id = 0;
class Box{
constructor(x, y, size, speed){
this.speed = speed;
this.x = x;
this.y = y;
this.size = size;
this.id = id;
id++;
this.spawn();
this.move(this.id, this);
}
spawn(){
let x = document.createElement("div");
x.setAttribute("id", this.id);
x.setAttribute("class", "box");
x.style.top = this.y + 'px';
x.style.left = this.x + 'px';
x.style.width = this.size + 'px';
x.style.height = this.size + 'px';
document.body.appendChild(x);
}
move(id, _this){
setInterval(function() {
document.getElementById(id).style.left = _this.speed + 'px';
_this.speed += 5;
}, 10);
}
}
div {
position: relative;
background-color: #f00;
}

Why circles aren't separated properly

I have this code for separating two circles. the problem is that whenever the radius of one of the circle changes (ie becomes bigger or smaller than the other) the circles start moving somewhere else. i am trying to move the circles apart together (). i dont know much about vectors. i got the vector posrtion of my code from Why circles are vibrating on collision (Canvas)
CollisionHandler.pushApart = function(cell, check) {
var x = check.x - cell.x;
var y = check.y - cell.y;
var distance = Math.hypot(x, y);
var cSz = Blob.getSize(cell.mass);
var chSz = Blob.getSize(check.mass);
var maxDist = cSz + chSz;
var boosting = Math.abs(cell.move.x) > 2 ||
Math.abs(cell.move.y) > 2 ||
Math.abs(check.move.x) > 2 ||
Math.abs(check.move.y) > 2;
if (distance < maxDist && !boosting) {
x /= distance;
y /= distance;
var pLen = cSz / (cSz + chSz);
var cx = cell.x + pLen * x * distance;
var cy = cell.y + pLen * y * distance;
cell.x += (cx - x * chSz - cell.x) * animationConstant;
cell.y += (cy - y * chSz - cell.y) * animationConstant;
check.x += (cx + x * cSz - check.x) * animationConstant;
check.y += (cy + y * cSz - check.y) * animationConstant;
/*var targetX = check.x - maxDistance * x;
var targetY = check.y - maxDistance * y;
cell.x += (targetX - cell.x) * animationConstant;
cell.y += (targetY - cell.y) * animationConstant;*/
}
};
<!DOCTYPE html>
<html>
<head>
<title>this is my clone of agar.io.</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<canvas></canvas>
<script>
var canvas = document.querySelector("canvas");
var ctx = canvas.getContext("2d");
var width = innerWidth;
var height = innerHeight;
canvas.width = width;
canvas.height = height;
var blobsFood = [];
var blobsVirus = [];
var blobsEject = [];
var blobsPlayer = [];
function getRandom(n) {
return Math.random() * n;
};
var gameWidth = 10000;
var gameHeight = 10000;
var massFood = 5;
var animationConstant = 0.2;
var maxSplit = 64;
function Blob(x, y, mass, hue) {
this.x = x;
this.y = y;
this.mass = mass;
this._mass = mass;
this.hue = hue;
this.time = Date.now();
this.move = {
x: 0,
y: 0,
angle: 0
};
};
Blob.getSize = function(mass) {
return Math.sqrt(mass * 100);
};
Blob.getSpeed = function(mass) {
return 15 * 1.6/Math.pow(mass, 0.32);
};
Blob.getBoostSpeed = function(mass) {
return 15 * 2.6 * Math.pow(mass, 0.0122);
};
Blob.prototype.boostMove = function() {
this.x += this.move.x;
this.y += this.move.y;
this.move.x *= 0.95;
this.move.y *= 0.95;
};
Blob.prototype.getAngle = function() {
return this.move.angle;
};
Blob.prototype.draw = function() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.beginPath();
this._mass += (this.mass - this._mass) * animationConstant;
ctx.arc(0, 0, Blob.getSize(this._mass), 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = "hsl(" + this.hue + ", 100%, 60%)";
ctx.strokeStyle = "hsl(" + this.hue + ", 100%, 50%)";
ctx.lineWidth = 5;
ctx.fill();
ctx.stroke();
ctx.restore();
};
Blob.prototype.onEaten = function(eater) {
// For virus and other cells
};
Blob.prototype.onEat = function(prey) {
this.mass += prey.mass;
};
function Virus() {
this.x = Math.random() * gameWidth;
this.y = Math.random() * gameWidth;
this.mass = 100;
this._mass = 100;
this.maxMass = 150;
this.hue = Math.random() * 360;
};
Virus.prototype = new Blob();
Virus.prototype.onEat = function(prey) {
this.mass += prey.mass;
if(this.mass >= this.maxMass) {
shootVirus(this, prey.getAngle());
}
};
Virus.prototype.onEaten = function(eater) {
var numSplits = maxSplit - blobsPlayer.length;
if(numSplits <= 0)
return;
var massLeft = eater.mass;
var splitAmount = 1;
var smallMass = 50;
while(massLeft > 0) {
splitAmount *= 2;
massLeft = eater.mass - splitAmount * 30;
};
var splitMass = eater.mass/splitAmount;
for(var i = 0; i < Math.min(splitAmount, numSplits); i++) {
if (eater.mass <= smallMass)
break;
var angle = Math.random() * 2 * Math.PI;
addPlayer(eater.x, eater.y, splitMass, angle, eater.hue);
eater.mass -= splitMass;
};
};
function CollisionHandler() {
console.log("CollisionHandler started.");
};
CollisionHandler.eatFactor = 0.02;
CollisionHandler.canEat = function(eater, check) {
var x = eater.x - check.x;
var y = eater.y - check.y;
var distance = Math.hypot(x, y);
var maxDistance = Blob.getSize(eater.mass + check.mass);
var minMass = CollisionHandler.eatFactor * check.mass + check.mass;
if(distance < maxDistance && eater.mass > minMass) {
return true;
} else {
return false;
}
};
CollisionHandler.pushApart = function(cell, check) {
var x = check.x - cell.x;
var y = check.y - cell.y;
var distance = Math.hypot(x, y);
var cSz = Blob.getSize(cell.mass);
var chSz = Blob.getSize(check.mass);
var maxDist = cSz + chSz;
var boosting = Math.abs(cell.move.x) > 2 ||
Math.abs(cell.move.y) > 2 ||
Math.abs(check.move.x) > 2 ||
Math.abs(check.move.y) > 2;
if(distance < maxDist && !boosting) {
x /= distance;
y /= distance;
var pLen = cSz / (cSz + chSz);
var cx = cell.x + pLen * x * distance;
var cy = cell.y + pLen * y * distance;
cell.x += (cx - x * chSz - cell.x) * animationConstant;
cell.y += (cy - y * chSz - cell.y) * animationConstant;
check.x += (cx + x * cSz - check.x) * animationConstant;
check.y += (cy + y * cSz - check.y) * animationConstant;
/*var targetX = check.x - maxDistance * x;
var targetY = check.y - maxDistance * y;
cell.x += (targetX - cell.x) * animationConstant;
cell.y += (targetY - cell.y) * animationConstant;*/
}
};
function addFood(n) {
for(var i = 0; i < n ; i++) {
var blob = new Blob(
getRandom(gameWidth),
getRandom(gameHeight),
massFood,
getRandom(360)
);
blobsFood.push(blob);
};
console.log(blobsFood.length);
};
var massVirus = 80;
var massVirusMax = 120;
function addVirus(n) {
for(var i = 0; i < n ; i++) {
var blob = new Virus();
blobsVirus.push(blob);
};
console.log(blobsVirus.length);
};
var massEject = 10;
function addEject(blob) {
if(blob.mass < 20)
return;
blob.mass -= massEject;
var angle = getMouseAngle(blob.x, blob.y);
var r = Blob.getSize(blob.mass);
var blob = new Blob(
blob.x + Math.cos(angle) * r,
blob.y + Math.sin(angle) * r,
massEject,
blob.hue
);
blob.move.x = Math.cos(angle) * 30;
blob.move.y = Math.sin(angle) * 30;
blob.move.angle = angle;
blobsEject.push(blob);
};
function addPlayer(x, y, mass, angle, hue) {
var moveX = Math.cos(angle) * Blob.getBoostSpeed(mass);
var moveY = Math.sin(angle) * Blob.getBoostSpeed(mass);
var blob = new Blob(x, y, mass, hue);
blob.move.x = moveX;
blob.move.y = moveY;
blob.move.angle = angle;
blobsPlayer.push(blob);
};
var mouseX = 0;
var mouseY = 0;
var cameraX = 0;
var cameraY = 0;
var _cameraX = 0;
var _cameraY = 0;
var zoom = 1;
var _zoom = 1;
function updateCamera() {
var x = 0;
var y = 0;
var m = 0;
var len = blobsPlayer.length;
blobsPlayer.forEach(function(blob) {
x += blob.x;
y += blob.y;
m += Blob.getSize(blob.mass);
});
cameraX = x/len;
cameraY = y/len;
zoom = 1/(Math.sqrt(m)/Math.log(m));
};
document.onmousemove = function(evt) {
mouseX = evt.clientX;
mouseY = evt.clientY;
};
document.onkeydown = function(evt) {
var key = evt.keyCode;
if(key == 32) {
var len = blobsPlayer.length;
for(var i = 0; i < len; i++) {
var blob = blobsPlayer[i];
splitPlayerBlob(blob);
};
}
if(key == 87) {
var len = blobsPlayer.length;
for(var i = 0; i < len; i++) {
var blob = blobsPlayer[i];
addEject(blob);
};
}
};
function getMouseAngle(x, y) {
var x = mouseX - width/2 + (cameraX - x) * zoom;
var y = mouseY - height/2 + (cameraY - y) * zoom;
return Math.atan2(y, x);
};
function splitPlayerBlob(blob) {
var numSplits = 16 - blobsPlayer.length;
if(numSplits <= 0) return;
if(blob.mass >= 20) {
blob.mass /= 2;
var angle = getMouseAngle(blob.x, blob.y);
addPlayer(blob.x, blob.y, blob.mass, angle, blob.hue);
}
};
function mouseMovePlayer() {
blobsPlayer.forEach(function(blob) {
var angle = getMouseAngle(blob.x, blob.y);
var speed = Blob.getSpeed(blob.mass);
var x = mouseX - width/2 + (cameraX - blob.x) * zoom;
var y = mouseY - height/2 + (cameraY - blob.y) * zoom;
// blob.x += Math.cos(angle) * speed * Math.min(1, Math.pow(x/toRadius(blob.mass), 2));
// blob.y += Math.sin(angle) * speed * Math.min(1, Math.pow(y/toRadius(blob.mass), 2));
blob.x += Math.cos(angle) * speed;
blob.y += Math.sin(angle) * speed;
});
};
function movePlayer() {
blobsPlayer.forEach(function(blob) {
blob.boostMove();
});
};
function moveEject() {
blobsEject.forEach(function(blob) {
blob.boostMove();
});
};
function separateEject() {
blobsEject.forEach(function(a, i) {
blobsEject.forEach(function(b, j) {
if(i == j)
return;
CollisionHandler.pushApart(a, b);
});
});
};
function separatePlayer() {
blobsPlayer.forEach(function(a, i) {
blobsPlayer.forEach(function(b, j) {
if(i == j)
return;
var ref1 = a;
var ref2 = b;
CollisionHandler.pushApart(ref1, ref2);
});
});
};
function eatFood() {
blobsPlayer.forEach(function(player) {
blobsFood.forEach(function(food, i) {
if(CollisionHandler.canEat(player, food)) {
player.onEat(food);
blobsFood.splice(i, 1);
}
});
});
};
function eatEject() {
blobsPlayer.forEach(function(player) {
blobsEject.forEach(function(eject, i) {
if(CollisionHandler.canEat(player, eject)) {
player.onEat(eject);
blobsEject.splice(i, 1);
}
});
});
blobsVirus.forEach(function(virus) {
blobsEject.forEach(function(eject, i) {
if(CollisionHandler.canEat(virus, eject)) {
virus.onEat(eject);
blobsEject.splice(i, 1);
}
});
});
};
function shootVirus(virus, angle) {
virus.mass = massVirus;
var speed = Blob.getSpeed(massVirus);
var blob = new Blob(virus.x, virus.y, massVirus, virus.hue);
var x = Math.cos(angle) * 30;
var y = Math.sin(angle) * 30;
blob.move.x = x;
blob.move.y = y;
blob.move.angle = angle;
blobsVirus.push(blob);
};
function moveVirus() {
blobsVirus.forEach(function(blob) {
blob.x += blob.move.x;
blob.y += blob.move.y;
blob.move.x *= 0.95;
blob.move.y *= 0.95;
});
};
function separateVirus() {
blobsVirus.forEach(function(a, i) {
blobsVirus.forEach(function(b, j) {
if(i == j)
return;
CollisionHandler.pushApart(a, b);
});
});
};
function eatVirus() {
blobsPlayer.forEach(function(player) {
blobsVirus.forEach(function(virus, i) {
if(CollisionHandler.canEat(player, virus)) {
player.onEat(virus);
virus.onEaten(player);
blobsVirus.splice(i, 1);
}
});
});
};
var baseTime = 10000;
function canCombine(player) {
var t = Math.floor(baseTime + (0.02 * player.mass));
var now = Date.now() - player.time;
return t < now;
};
function combinePlayer() {
blobsPlayer.forEach(function(a, i) {
blobsPlayer.forEach(function(b, j) {
if(i == j)
return;
var x = a.x - b.x;
var y = a.y - b.y;
var d = Math.hypot(x, y);
var r = Blob.getSize(a.mass + b.mass);
if(d < r && canCombine(a) && canCombine(b)) {
if(a.mass > b.mass) {
a.mass += b.mass;
blobsPlayer.splice(j, 1);
} else {
b.mass += a.mass;
blobsPlayer.splice(i, 1);
}
}
});
});
};
function updateGame() {
movePlayer();
mouseMovePlayer();
separatePlayer();
combinePlayer();
moveEject();
separateEject();
moveVirus();
separateVirus();
eatFood();
eatEject();
eatVirus();
updateCamera();
};
function drawGame() {
clearCanvas();
ctx.save();
_zoom += (zoom - _zoom) * 0.1;
_cameraX += (cameraX - _cameraX) * 0.1;
_cameraY += (cameraY - _cameraY) * 0.1;
ctx.translate(-_cameraX * _zoom + width/2, -_cameraY * _zoom + height/2);
ctx.scale(_zoom, _zoom);
drawAllBlobs();
ctx.restore();
};
function clearCanvas() {
ctx.fillStyle = "white";
ctx.fillRect(0, 0, width, height);
};
function drawAllBlobs() {
var blobs = blobsFood
.concat(blobsEject)
.concat(blobsVirus)
.concat(blobsPlayer);
var blobs = blobs.sort(function(a, b) {
return a.mass - b.mass;
});
blobs.forEach(function(blob) {
blob.draw();
});
};
function loop() {
updateGame();
drawGame();
requestAnimationFrame(loop);
};
addFood(300);
addVirus(15);
addPlayer(0, 0, 3000, 0, 45)
loop();
</script>
</body>
</html>

How is this website getting such good performance? And how can I get it?

I'm trying to replicate this "blackhole" effect in Javascript as seen on i-remember.fr but I am not getting anywhere NEAR as good performance as them, what am I doing wrong? I used to have a jQuery selector in my code that ran every animationframe, but I have that removed now which helps out a bunch. But I'm still running at 40 FPS when their FPS is ridiculously low!
See their timeline
And here is mine
I would never be able to use mine in actual practice because of the framerate! Any ideas on what type of sorcery they are using to increase the framerate?
My Current Engine
View it on CodePen
Javascript
/*$('.blackhole').click(function() {
$(this).toggleClass('open_blackhole');
$(this).toggleClass('close_blackhole');
});*/
// Define Apparatus Variables.
var cw = window.innerWidth,
ch = window.innerHeight,
blackhole_entities = {},
blackhole_entitiesIndex = 0,
blackhole_entitieAmount = 12000, //6000
blackhole_button = $('.blackhole'),
canvas = $('<canvas/>').attr({
width: cw,
height: ch,
id: "apparatus"
}).appendTo('body'),
context = canvas.get(0).getContext("2d");
var requestframe = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
// IE Fallback, you can even fallback to onscroll
function(callback) {
window.setTimeout(callback, 1000 / 60)
};
// Default Entity "Class"
apparatus.blackhole = function(orbit) {
blackhole_entitiesIndex++;
this.id = blackhole_entitiesIndex;
blackhole_entities[blackhole_entitiesIndex] = this;
this.width = .5;
this.height = .5;
this.orbit = orbit;
this.velocity = Math.floor((Math.random() * 3200) + 2500);
this.angle = (Math.PI * 2 / this.width) * Math.floor((Math.random() * cw*4) + 10);;
var choice = Math.random() * 5;
var rands = [];
rands.push(Math.random() * 100 + 1);
rands.push(Math.random() * 10 + 241);
var choice2 = Math.random() * 4;
var rands2 = [];
rands2.push(Math.random() * 100 + 1);
rands2.push(Math.random() * 180 + 211);
this.distance = (rands.reduce(function(p, c) {
return p + c;
}, 0) / rands.length);
this.distance2 = (rands2.reduce(function(p, c) {
return p + c;
}, 0) / rands2.length);
this.increase = Math.PI * 2 / this.width;
this.distancefix = this.distance;
this.distance2fix = this.distance2;
this.color = "255,255,255";
this.alpha = 0.6
this.bx = Math.random() * 20 + 1;
this.by = Math.random() * 20 + 1;
this.inplace = true;
}
apparatus.blackhole.prototype.draw = function() {
if (this.orbit >= 2) {
this.x = this.bx + this.distance * Math.cos(this.angle / this.velocity) + cw / 2;
this.y = this.by + this.distance * Math.sin(this.angle / this.velocity) + ch / 2;
this.alpha = 0.6;
} else {
this.x = this.bx + this.distance2 * Math.cos(this.angle / this.velocity) + cw / 2;
this.y = this.by + this.distance2 * Math.sin(this.angle / this.velocity) + ch / 2;
this.alpha = 0.4;
}/*
if (blackhole_button.hasClass('open_blackhole')) {
blackhole_button.removeClass('close_blackhole');
if (this.distance >= 171) {
this.distance = this.distance - 4;
} else if (this.distance <= 161) {
this.distance= this.distance + 8;
}
if (this.distance2 >= 201) {
this.distance2 = this.distance2 - 6;
} else if (this.distance2 <= 161) {
this.distance2 = this.distance2 + 6;
}
}
if(blackhole_button.hasClass('close_blackhole')){
if (this.distance >= this.distancefix + 4) {
this.distance = this.distance - 4;
} else if (this.distance <= this.distancefix - 5) {
this.distance= this.distance + 5;
}
if (this.distance2 >= this.distance2fix + 10) {
this.distance2 = this.distance2 - 4;
} else if (this.distance2 <= this.distance2fix - 10) {
this.distance2 = this.distance2 + 4;
}
}*/
this.angle += this.increase;
context.fillStyle = "rgba(" + this.color + "," + this.alpha + ")";
context.fillRect(this.x, this.y, this.width, this.height);
}
apparatus.start = function() {
apparatus('true');
}
apparatus.stop = function() {
apparatus('false');
}
for (var i = 0; i < blackhole_entitieAmount; i++) {
new apparatus.blackhole((Math.random() * 5));
}
var mode;
apparatus.spawn_blackhole = function(){
for (i in blackhole_entities) {
blackhole_entities[i].draw();
}
}
function apparatus(mode) {
if (mode == 'true') {
var i;
requestframe(function() {
context.clearRect(0, 0, cw, ch);
apparatus.spawn_blackhole();
apparatus('true');
});
}
}
apparatus.start();
Hopefully someone will have an idea on how I can do this. I am simply trying to further my knowledge in Javascript canvas manipulation.
Thanks a bunch for any tips you can throw my way!
This question might be marked for being a duplicate of my last question, but my last question didn't give me a real, usable framerate. And due to the fact that the person did "answer" my question, I'm here now.

using querySelectorAll to move more than one div

I'm trying to use the queryselectorall to be able to move more than one div, but I'm getting trouble for not knowing how to adapt. I thought of using a while that style:
[].forEach.call(els, function(el) {
...
});
But not got success, how can I fix my script to make it work?
My code:
var draggableEl = document.querySelectorAll('[data-drag]'), magnet = document.querySelector('.magnet-zone');
function isOverlapping(el1, el2) {
var rect1 = el1.getBoundingClientRect(), rect2 = el2.getBoundingClientRect();
return !(rect1.top > rect2.bottom || rect1.right < rect2.left || rect1.bottom < rect2.top || rect1.left > rect2.right);
}
function moveToPos(x, y) {
var el = draggableEl;
el.style.transform = 'translate(' + Math.round(x, 10) + 'px, ' + Math.round(y, 10) + 'px) translateZ(0)';
el.style.webkitTransform = 'translate(' + Math.round(x, 10) + 'px, ' + Math.round(y, 10) + 'px) translateZ(0)';
}
function moveMagnet(x, y) {
var dist = 12, width = $('body').width() / 2, height = $('body').height(), direction = x > width ? 1 : -1, percX = x > width ? (x - width) / width : -(width - x) / width, percY = Math.min(1, (height - y) / (height / 2));
magnet.style.marginLeft = Math.round(dist / 1.5 * percX) + 'px';
magnet.style.marginBottom = Math.round(dist * percY) + 'px';
}
function move(event) {
var el = draggableEl, magnetRect = magnet.getBoundingClientRect(), elRect = el.getBoundingClientRect();
x = this._posOrigin.x + event.pageX - this._touchOrigin.x;
y = this._posOrigin.y + event.pageY - this._touchOrigin.y;
moveMagnet(x + elRect.width / 2, y + elRect.height / 2);
$('body').addClass('moving');
var touchPos = {
top: y,
right: x + elRect.width,
bottom: y + elRect.height,
left: x
};
overlapping = !(touchPos.top > magnetRect.bottom || touchPos.right < magnetRect.left || touchPos.bottom < magnetRect.top || touchPos.left > magnetRect.right);
if (overlapping) {
var mx = magnetRect.width / 2 + magnetRect.left;
var my = magnetRect.height / 2 + magnetRect.top;
x = mx - elRect.width / 2;
y = my - elRect.height / 2;
if (!$(el).hasClass('overlap')) {
$(el).addClass('transition');
setTimeout(function () {
$(el).removeClass('transition');
}, 150);
setTimeout(function () {
el.remove();
setTimeout(function () {
$('body').removeClass('moving touching');
}, 900);
}, 1000);
}
magnet.className = magnet.className.replace(' overlap', '') + ' overlap';
el.className = el.className.replace(' overlap', '') + ' overlap';
} else {
if ($(el).hasClass('transition')) {
$(el).removeClass('transition');
}
if ($(el).hasClass('overlap')) {
$(el).addClass('transition');
setTimeout(function () {
$(el).removeClass('transition');
}, 100);
}
magnet.className = magnet.className.replace(' overlap', '');
el.className = el.className.replace(' overlap', '');
}
moveToPos(x, y);
}
$(draggableEl).on('touchstart mousedown', onTouchStart).on('touchmove drag', move).on('touchend mouseup', onTouchEnd);
function onTouchStart(event) {
var rect = this.getBoundingClientRect();
$('body').addClass('touching');
$(this).removeClass('edge transition');
this._touchOrigin = {
x: event.pageX,
y: event.pageY
};
this._posOrigin = {
x: rect.left,
y: rect.top
};
}
function onTouchEnd(event) {
var el = draggableEl, rect = el.getBoundingClientRect(), width = $('body').width(), halfScreen = width / 2;
if (!$(el).hasClass('overlap')) {
$('body').removeClass('moving touching');
magnet.style.marginBottom = magnet.style.marginLeft = '0px';
var x = rect.left + rect.width / 2 < halfScreen ? +10 : width - 10 - rect.width;
$(el).addClass('edge');
moveToPos(x, rect.top);
setTimeout(function () {
$(el).removeClass('edge');
}, 500);
}
}
source: http://jsfiddle.net/4yt1roa6/

Categories

Resources