我第一次制作了粒子画布,我想知道如何停止这个循环并只播放一次 我试图把setTimeout()但它继续播放仍然循环。也许我把setTimeout()放在错误的行中。
有谁知道如何停止循环?代码似乎很难阻止循环。如果有任何办法停止,请帮忙!
angular.module("particles", [])
.directive("explosion", ["$interval",
function($interval) {
return {
restrict: "C",
template: "<canvas></canvas",
replace: true,
transclude: true,
scope: {
particle: "@",
count: "=",
speed: "=",
size: "=",
colors: "=",
spawn: "="
},
link: function(scope, element, attrs) {
console.log("Starting canvas ", scope.particle);
var ctx = element[0].getContext('2d');
var particles = [];
var width, height;
var maxCount = scope.count || 100;
var maxSpeed = scope.speed || 150;
var maxSize = scope.size || 10;
var colors = scope.colors || ['#f00'];
var spawnTime = scope.spawn ? 1000 / scope.spawn : 10;
var resize = function() {
element.attr({
width: $('body').width(),
height: $('body').height()
});
width = element.attr('width');
height = element.attr('height');
console.log("Size ", width, "x", height);
};
var spawn = function() {
particles.push({
x: width / 2,
y: height / 2,
sx: width / 2,
sy: height / 2,
v: {
x: (maxSpeed << 1) * Math.random() - maxSpeed,
y: (maxSpeed << 1) * Math.random() - maxSpeed
},
s: Math.random() * maxSize,
rm: Math.floor( Math.random() * (80 + 1 - 10) ) + 10,
a: 1,
c: colors[Math.floor(Math.random() * colors.length)]
});
};
var draw = function() {
ctx.clearRect(0, 0, width, height);
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
ctx.beginPath();
ctx.globalAlpha = p.a;
ctx.fillStyle = p.c;
ctx.arc(p.x, p.y, p.s, 0, 2 * Math.PI);
ctx.fill();
ctx.beginPath();
drawStar(ctx, p.sx, p.sy, 8, p.rm, Math.ceil(p.rm*.1));
ctx.fill();
}
function drawStar(context, xCenter, yCenter, nPoints, outerRadius, innerRadius) {
ctx.beginPath();
for (var ixVertex = 0; ixVertex <= 2 * nPoints; ++ixVertex) {
var angle = ixVertex * Math.PI / nPoints - Math.PI / 2;
var radius = ixVertex % 2 == 0 ? outerRadius : innerRadius;
context.lineTo(xCenter + radius * Math.cos(angle), yCenter + radius * Math.sin(angle));
}
}
};
var lastSpawned = 0;
var update = function(delta) {
lastSpawned += delta;
while (lastSpawned > spawnTime) {
lastSpawned -= spawnTime;
spawn();
}
var particleOverflow = particles.length - maxCount;
if (particleOverflow > 0) {
particles.splice(0, particleOverflow);
}
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
p.x += p.v.x * delta / 1000;
p.y += p.v.y * delta / 1000;
p.a *= 0.99;
p.sx += p.v.x * delta / 600;
p.sy += p.v.y * delta / 600;
}
};
var finished = false;
var time;
var animate = function(elapsed) {
if (!time)
time = elapsed;
var delta = elapsed - time;
time = elapsed;
update(delta);
draw();
setTimeout(draw, 100);
if (!finished) window.requestAnimationFrame(animate);
};
resize();
$(window).on('resize', resize);
window.requestAnimationFrame(animate);
scope.$on("$destroy", function() {
finished = true;
});
}
};
}
]);
html {
height: 100%;
}
body {
background:#000;
overflow:hidden;
height:100%;
}
.canvas {
width:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="particles">
<div class="canvas explosion" particle="circle"
count="100" speed="200" size="40" spawn="10"
colors="['rgba(255,255,255,.6)', 'rgba(255,255,255,.4)', 'rgba(255,255,255,.2)', 'rgba(255,255,255,.3)']" ></div>
</div>