Как сделать паузу для canvas анимации?
Вот canvas анимация(код ниже). как сделать ,чтобы по нажатию на на кнопку pause. Элементы анимации (облака) останавливались на месте ,как бы становясь на паузу. Спасибо!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #F3F6FF;
}
canvas{
display: block;
}
.button-c{
position: fixed;
z-index: 10;
top: 50%;
left: 50%;
}
.pause{
position: fixed;
z-index: 10;
top: 10%;
left: 50%;
}
</style>
</head>
<body>
<button class="button-c">click</button>
<button class="pause">pause</button>
<canvas id="canvas"></canvas>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script type="text/javascript">
function Particles(){
//particle colors
this.colors = [
'255, 255, 255'
]
//adds gradient to particles on true
//adds white border
this.border = false;
//particle radius min/max
this.minRadius = 10;
this.maxRadius = 50;
//particle opacity min/max
this.minOpacity = 1;
this.maxOpacity = 1;
//particle speed min/max
this.minSpeed = .05;
this.maxSpeed = .5;
//frames per second
this.fps = 60;
//number of particles
this.numParticles = 20;
//required canvas variables
this.canvas = document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
}
/**
* Initializes everything
* @method init
*/
Particles.prototype.init = function(){
this.render();
this.createCircle();
}
/**
* generates random number between min and max values
* @param {number} min value
* @param {number} max malue
* @return {number} random number between min and max
* @method _rand
*/
Particles.prototype._rand = function(min, max){
return Math.random() * (max - min) + min;
}
/**
* Sets canvas size and updates values on resize
* @method render
*/
Particles.prototype.render = function(){
var self = this,
wHeight = $(window).height(),
wWidth = $(window).width();
self.canvas.width = wWidth;
self.canvas.height = wHeight;
$(window).on('resize', self.render);
}
/**
* Randomly creates particle attributes
* @method createCircle
*/
Particles.prototype.createCircle = function(){
var particle = [];
for (var i = 0; i < this.numParticles; i++) {
var self = this,
color = self.colors[~~(self._rand(0, self.colors.length))];
particle[i] = {
radius : self._rand(self.minRadius, self.maxRadius),
xPos : self._rand(0, canvas.width),
yPos : self._rand(0, canvas.height),
xVelocity : self._rand(self.minSpeed, self.maxSpeed),
yVelocity : self._rand(self.minSpeed, self.maxSpeed),
color : 'rgba(' + color + ',' + self._rand(self.minOpacity, self.maxOpacity) + ')'
}
//once values are determined, draw particle on canvas
self.draw(particle, i);
}
//...and once drawn, animate the particle
self.animate(particle);
}
/**
* Draws particles on canvas
* @param {array} Particle array from createCircle method
* @param {number} i value from createCircle method
* @method draw
*/
Particles.prototype.draw = function(particle, i){
var self = this,
ctx = self.ctx;
if (self.blurry === true ) {
//creates gradient if blurry === true
var grd = ctx.createRadialGradient(particle[i].xPos, particle[i].yPos, particle[i].radius, particle[i].xPos, particle[i].yPos, particle[i].radius/1.25);
grd.addColorStop(1.000, particle[i].color);
grd.addColorStop(0.000, 'rgba(34, 34, 34, 0)');
ctx.fillStyle = grd;
} else {
//otherwise sets to solid color w/ opacity value
ctx.fillStyle = particle[i].color;
}
if (self.border === true) {
ctx.strokeStyle = '#fff';
ctx.stroke();
}
ctx.beginPath();
ctx.arc(particle[i].xPos, particle[i].yPos, particle[i].radius, Math.PI, 0, false);
ctx.fill();
}
/**
* Animates particles
* @param {array} particle value from createCircle & draw methods
* @method animate
*/
Particles.prototype.animate = function(particle){
var self = this,
ctx = self.ctx;
setInterval(function(){
//clears canvas
self.clearCanvas();
//then redraws particles in new positions based on velocity
for (var i = 0; i < self.numParticles; i++) {
particle[i].xPos += particle[i].xVelocity;
//if particle goes off screen call reset method to place it offscreen to the left/bottom
if (particle[i].xPos > self.canvas.width + particle[i].radius || particle[i].yPos > self.canvas.height + particle[i].radius) {
self.resetParticle(particle, i);
} else {
self.draw(particle, i);
}
}
}, 1000/self.fps);
}
/**
* Resets position of particle when it goes off screen
* @param {array} particle value from createCircle & draw methods
* @param {number} i value from createCircle method
* @method resetParticle
*/
Particles.prototype.resetParticle = function(particle, i){
var self = this;
var random = self._rand(0, 1);
if (random > .5) {
// 50% chance particle comes from left side of window...
particle[i].xPos = -particle[i].radius;
particle[i].yPos = self._rand(0, canvas.height);
} else {
//... or bottom of window
particle[i].xPos = self._rand(0, canvas.width);
particle[i].yPos = canvas.height + particle[i].radius;
}
//redraw particle with new values
self.draw(particle, i);
}
/**
* Clears canvas between animation frames
* @method clearCanvas
*/
Particles.prototype.clearCanvas = function(){
this.ctx.clearRect(0, 0, canvas.width, canvas.height);
}
// go go go!
$(".button-c").on("click", function(){
var particle = new Particles().init();
});
</script>
</html>
Ответы (1 шт):
Автор решения: Darth
→ Ссылка
function Particles(){
this.pause = false;
//particle colors
this.colors = [
'255, 255, 255'
]
//adds gradient to particles on true
//adds white border
this.border = false;
//particle radius min/max
this.minRadius = 10;
this.maxRadius = 50;
//particle opacity min/max
this.minOpacity = 1;
this.maxOpacity = 1;
//particle speed min/max
this.minSpeed = .05;
this.maxSpeed = .5;
//frames per second
this.fps = 60;
//number of particles
this.numParticles = 20;
//required canvas variables
this.canvas = document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
}
/**
* Initializes everything
* @method init
*/
Particles.prototype.init = function(){
this.render();
this.createCircle();
}
/**
* generates random number between min and max values
* @param {number} min value
* @param {number} max malue
* @return {number} random number between min and max
* @method _rand
*/
Particles.prototype._rand = function(min, max){
return Math.random() * (max - min) + min;
}
/**
* Sets canvas size and updates values on resize
* @method render
*/
Particles.prototype.render = function(){
var self = this,
wHeight = $(window).height(),
wWidth = $(window).width();
self.canvas.width = wWidth;
self.canvas.height = wHeight;
$(window).on('resize', self.render);
}
/**
* Randomly creates particle attributes
* @method createCircle
*/
Particles.prototype.createCircle = function(){
var particle = [];
for (var i = 0; i < this.numParticles; i++) {
var self = this,
color = self.colors[~~(self._rand(0, self.colors.length))];
particle[i] = {
radius : self._rand(self.minRadius, self.maxRadius),
xPos : self._rand(0, canvas.width),
yPos : self._rand(0, canvas.height),
xVelocity : self._rand(self.minSpeed, self.maxSpeed),
yVelocity : self._rand(self.minSpeed, self.maxSpeed),
color : 'rgba(' + color + ',' + self._rand(self.minOpacity, self.maxOpacity) + ')'
}
//once values are determined, draw particle on canvas
self.draw(particle, i);
}
//...and once drawn, animate the particle
self.animate(particle);
}
/**
* Draws particles on canvas
* @param {array} Particle array from createCircle method
* @param {number} i value from createCircle method
* @method draw
*/
Particles.prototype.draw = function(particle, i){
var self = this,
ctx = self.ctx;
if (self.blurry === true ) {
//creates gradient if blurry === true
var grd = ctx.createRadialGradient(particle[i].xPos, particle[i].yPos, particle[i].radius, particle[i].xPos, particle[i].yPos, particle[i].radius/1.25);
grd.addColorStop(1.000, particle[i].color);
grd.addColorStop(0.000, 'rgba(34, 34, 34, 0)');
ctx.fillStyle = grd;
} else {
//otherwise sets to solid color w/ opacity value
ctx.fillStyle = particle[i].color;
}
if (self.border === true) {
ctx.strokeStyle = '#fff';
ctx.stroke();
}
ctx.beginPath();
ctx.arc(particle[i].xPos, particle[i].yPos, particle[i].radius, Math.PI, 0, false);
ctx.fill();
}
/**
* Animates particles
* @param {array} particle value from createCircle & draw methods
* @method animate
*/
Particles.prototype.animate = function(particle){
var self = this,
ctx = self.ctx;
setInterval(function(){
if(self.pause) return;
//clears canvas
self.clearCanvas();
//then redraws particles in new positions based on velocity
for (var i = 0; i < self.numParticles; i++) {
particle[i].xPos += particle[i].xVelocity;
//if particle goes off screen call reset method to place it offscreen to the left/bottom
if (particle[i].xPos > self.canvas.width + particle[i].radius || particle[i].yPos > self.canvas.height + particle[i].radius) {
self.resetParticle(particle, i);
} else {
self.draw(particle, i);
}
}
}, 1000/self.fps);
}
/**
* Resets position of particle when it goes off screen
* @param {array} particle value from createCircle & draw methods
* @param {number} i value from createCircle method
* @method resetParticle
*/
Particles.prototype.resetParticle = function(particle, i){
var self = this;
var random = self._rand(0, 1);
if (random > .5) {
// 50% chance particle comes from left side of window...
particle[i].xPos = -particle[i].radius;
particle[i].yPos = self._rand(0, canvas.height);
} else {
//... or bottom of window
particle[i].xPos = self._rand(0, canvas.width);
particle[i].yPos = canvas.height + particle[i].radius;
}
//redraw particle with new values
self.draw(particle, i);
}
/**
* Clears canvas between animation frames
* @method clearCanvas
*/
Particles.prototype.clearCanvas = function(){
this.ctx.clearRect(0, 0, canvas.width, canvas.height);
}
var particle = new Particles();
// go go go!
$(".button-c").on("click", function(){
particle.init();
});
$(".pause").on("click", function(){
particle.pause = !particle.pause;
});
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #F3F6FF;
}
canvas{
display: block;
}
.button-c{
position: fixed;
z-index: 10;
top: 50%;
left: 50%;
}
.pause{
position: fixed;
z-index: 10;
top: 10%;
left: 50%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
</head>
<body>
<button class="button-c">click</button>
<button class="pause">pause</button>
<canvas id="canvas"></canvas>
</body>
</html>