I’ve made an explosion animation but I can’t stop it from executing. I’ve tried using setInterval but it doesn’t seem to work. What might be wrong with this code?
script.js
function grow(){ setInterval(function(){
balloon = document.querySelector('.balloon');
balloon.style.width = '200px';
balloon.style.height = '200px';
balloon.style.transition = '3s';
setInterval(function(){
balloon.style.display = 'none';
explode(balloon);
},2000);
}, 2000);
};
grow();
var anchors = document.querySelectorAll('.balloon');
function explode(e) {
var x = e.clientX
var y = e.clientY
var c = document.createElement('canvas')
var ctx = c.getContext('2d')
var ratio = window.devicePixelRatio
var particles = []
document.body.appendChild(c)
c.style.position = 'absolute'
c.style.left = (x - 100) + 'px'
c.style.top = (y - 100) + 'px'
c.style.pointerEvents = 'none'
c.style.width = 200 + 'px'
c.style.height = 200 + 'px'
c.width = 200 * ratio
c.height = 200 * ratio
function Particle() {
return {
x: c.width / 2,
y: c.height / 2,
radius: r(20,30),
color: 'rgb(' + [r(0,255), r(0,255), r(0,255)].join(',') + ')',
rotation: r(0,360, true),
speed: r(8,12),
friction: 0.9,
opacity: r(0,0.5, true),
yVel: 0,
gravity: 0.1
}
}
for(var i=0; ++i<25;) {
particles.push(Particle())
}
console.log(particles[0])
function render() {
ctx.clearRect(0, 0, c.width, c.height)
particles.forEach(function(p, i) {
angleTools.moveOnAngle(p, p.speed)
p.opacity -= 0.01
p.speed *= p.friction
p.radius *= p.friction
p.yVel += p.gravity
p.y += p.yVel
if(p.opacity < 0) return
if(p.radius < 0) return
ctx.beginPath()
ctx.globalAlpha = p.opacity
ctx.fillStyle = p.color
ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, false)
ctx.fill()
})
}
;(function renderLoop(){
requestAnimationFrame(renderLoop)
render()
})()
}
var angleTools={getAngle:function(t,n){var a=n.x-t.x,e=n.y-t.y;return Math.atan2(e,a)/Math.PI*180},getDistance:function(t,n){var a=t.x-n.x,e=t.y-n.y;return Math.sqrt(a*a+e*e)},moveOnAngle:function(t,n){var a=this.getOneFrameDistance(t,n);t.x+=a.x,t.y+=a.y},getOneFrameDistance:function(t,n){return{x:n*Math.cos(t.rotation*Math.PI/180),y:n*Math.sin(t.rotation*Math.PI/180)}}};
function r(a,b,c){ return parseFloat((Math.random()*((a?a:1)-(b?b:0))+(b?b:0)).toFixed(c?c:0)); }
index.html
<div class="balloon"></div>
style.scss
body { margin:20px; background:hsl(70, 31%, 85%); }
.explosion {
position: absolute; // required if positioned on click else 'relative'
width: 600px;
height: 600px;
pointer-events: none; // make it clickable trhough
// particle styling
.particle {
position: absolute; // required
width: 10px;
height: 10px;
border-radius: 50%;
animation: pop 1s reverse forwards; // required
}
}
// animation for particle fly away from the cursor
@keyframes pop {
from {
opacity: 0;
}
to {
top: 50%;
left: 50%;
opacity: 1;
}
}
.balloon {
display:inline-block;
width:103px;
height:125px;
background:hsl(215,50%,65%);
border-radius:80%;
position:relative;
box-shadow:inset -10px -10px 0 rgba(0,0,0,0.07);
margin:20px 30px;
transition:transform 0.5s ease;
z-index:10;
animation:balloons 4s ease-in-out infinite;
transform-origin:bottom center;
}
@keyframes balloons {
0%,100%{ transform:translateY(0) rotate(-4deg); }
50%{ transform:translateY(-25px) rotate(4deg); }
}
.balloon:before {
content:"▲";
font-size:20px;
color:hsl(215,30%,50%);
display:block;
text-align:center;
width:100%;
position:absolute;
bottom:-12px;
z-index:-100;
}
>Solution :
setTimeout instead of setInterval
function grow() {
setTimeout(function() {
balloon = document.querySelector('.balloon');
balloon.style.width = '200px';
balloon.style.height = '200px';
balloon.style.transition = '3s';
setTimeout(function() {
balloon.style.display = 'none';
explode(balloon);
}, 2000);
}, 2000);
};
grow();
var anchors = document.querySelectorAll('.balloon');
function explode(e) {
var x = e.clientX
var y = e.clientY
var c = document.createElement('canvas')
var ctx = c.getContext('2d')
var ratio = window.devicePixelRatio
var particles = []
document.body.appendChild(c)
c.style.position = 'absolute'
c.style.left = (x - 100) + 'px'
c.style.top = (y - 100) + 'px'
c.style.pointerEvents = 'none'
c.style.width = 200 + 'px'
c.style.height = 200 + 'px'
c.width = 200 * ratio
c.height = 200 * ratio
function Particle() {
return {
x: c.width / 2,
y: c.height / 2,
radius: r(20, 30),
color: 'rgb(' + [r(0, 255), r(0, 255), r(0, 255)].join(',') + ')',
rotation: r(0, 360, true),
speed: r(8, 12),
friction: 0.9,
opacity: r(0, 0.5, true),
yVel: 0,
gravity: 0.1
}
}
for (var i = 0; ++i < 25;) {
particles.push(Particle())
}
console.log(particles[0])
function render() {
ctx.clearRect(0, 0, c.width, c.height)
particles.forEach(function(p, i) {
angleTools.moveOnAngle(p, p.speed)
p.opacity -= 0.01
p.speed *= p.friction
p.radius *= p.friction
p.yVel += p.gravity
p.y += p.yVel
if (p.opacity < 0) return
if (p.radius < 0) return
ctx.beginPath()
ctx.globalAlpha = p.opacity
ctx.fillStyle = p.color
ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, false)
ctx.fill()
})
}
;
(function renderLoop() {
requestAnimationFrame(renderLoop)
render()
})()
}
var angleTools = {
getAngle: function(t, n) {
var a = n.x - t.x,
e = n.y - t.y;
return Math.atan2(e, a) / Math.PI * 180
},
getDistance: function(t, n) {
var a = t.x - n.x,
e = t.y - n.y;
return Math.sqrt(a * a + e * e)
},
moveOnAngle: function(t, n) {
var a = this.getOneFrameDistance(t, n);
t.x += a.x, t.y += a.y
},
getOneFrameDistance: function(t, n) {
return {
x: n * Math.cos(t.rotation * Math.PI / 180),
y: n * Math.sin(t.rotation * Math.PI / 180)
}
}
};
function r(a, b, c) {
return parseFloat((Math.random() * ((a ? a : 1) - (b ? b : 0)) + (b ? b : 0)).toFixed(c ? c : 0));
}
body {
margin: 20px;
background: hsl(70, 31%, 85%);
}
.explosion {
position: absolute; // required if positioned on click else 'relative'
width: 600px;
height: 600px;
pointer-events: none; // make it clickable trhough
// particle styling
.particle {
position: absolute; // required
width: 10px;
height: 10px;
border-radius: 50%;
animation: pop 1s reverse forwards; // required
}
}
// animation for particle fly away from the cursor
@keyframes pop {
from {
opacity: 0;
}
to {
top: 50%;
left: 50%;
opacity: 1;
}
}
.balloon {
display: inline-block;
width: 103px;
height: 125px;
background: hsl(215, 50%, 65%);
border-radius: 80%;
position: relative;
box-shadow: inset -10px -10px 0 rgba(0, 0, 0, 0.07);
margin: 20px 30px;
transition: transform 0.5s ease;
z-index: 10;
animation: balloons 4s ease-in-out infinite;
transform-origin: bottom center;
}
@keyframes balloons {
0%,
100% {
transform: translateY(0) rotate(-4deg);
}
50% {
transform: translateY(-25px) rotate(4deg);
}
}
.balloon:before {
content: "▲";
font-size: 20px;
color: hsl(215, 30%, 50%);
display: block;
text-align: center;
width: 100%;
position: absolute;
bottom: -12px;
z-index: -100;
}
<div class="balloon"></div>