每次我生成一个新粒子时,粒子速度(在 canvas 上)都会增加。是由于请求动画帧吗?
Speed of particle (on canvas) increases everytime I generate a new one. Is it due to requestanimationframe?
目的是使用 class 粒子创建粒子(在用户单击按钮时),一旦它成为 运行 应该的,让用户可以控制速度,重力和其他一些东西。问题是每次用户点击创建一个新的粒子时,速度都会增加。
我不确定为什么,但是当我在没有请求动画框架的情况下演示它时,它看起来像它应该的那样工作,但如果它没有动画就没用了。
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const gravitySlider = document.getElementById('gravity-slider')
const output = document.getElementById('value')
//GENERIC PARTICLE CREATION
class particle{
constructor(positionX, positionY, velocityX, velocityY, radius, color,){
this.positionX = Math.max(radius, Math.min(1024 - radius, positionX))
this.positionY = Math.min(768 - radius, positionY)
this.velocityX = velocityX
this.velocityY = velocityY
this.radius = radius
this.color = color
}
update() {
if (
this.positionX > 1024 - this.radius || this.positionX < this.radius
) {
this.velocityX *= -1
}
if (this.positionY >= 768 - this.radius || this.positionY < this.radius) {
this.velocityY *= -1
}
this.velocityX *= 0.999
this.velocityY += 1
this.positionX += this.velocityX;
this.positionY += this.velocityY;
this.positionY = Math.min(768 - this.radius, this.positionY)
}
drawParticle() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.positionX, this.positionY, this.radius, 0, Math.PI * 2);
ctx.fill();
}
}
//CREATE BUTTON INTERACTIVITY AND CLICK COUNTING VARIABLE
const newParticleButton = document.getElementById('new-particle-button')
newParticleButton.onclick = drawNewParticle
//Even listener for click counting
let clickCount = 0
const clickCounter = document.querySelector('#new-particle-button')
clickCounter.addEventListener('click' ,function(event){
clickCount+= 1 })
const particleArray = []
//DRAW NEW PARTICLES ON BUTTON PRESS
function drawNewParticle(){
//Generate particle and add to array of particles
generateParticle = particleArray.push (new particle(
Math.random() * 1014,
Math.random() * 758,
1,
1,
10,
'hsla(0, 0%, 0%, 1)'
)
)
// clear canvas
ctx.clearRect(0, 0, 1024, 768)
for(i=0; i< clickCount; i++){
particleArray[i].update()
particleArray[i].drawParticle()
}
requestAnimationFrame(drawNewParticle)
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Canvas Basics</title>
<link rel="stylesheet" href="styles/index.css">
<script src="scripts/canvas.js" defer></script>
</head>
<body>
<canvas id="canvas" width="1024" height="768" style="border: 1px dashed">
Canvas is not supported
</canvas>
<button class="new-particle-button" id="new-particle-button">NEW PARTICLE</button>
<div class="slidecontainer">
<label for="gravity-slider">GRAVITY</label>
<input type="range" min="0" max="10" value="0" class="slider" id="gravity-slider">
<p>Value: <span id="value"></span></p>
</div>
</body>
</html>
我会检查一下你是否经常 运行 drawNewParticle
作为你的动画函数,我会把这个(你的粒子创建函数):
particleArray.push (new particle(
Math.random() * 1014,
Math.random() * 758,
1,
1,
10,
'hsla(0, 0%, 0%, 1)'
)
);
在按钮的事件侦听器下,因为看起来您正在屏幕上创建一个粒子数组,每帧都会获得一个新项目。
如果这没有帮助,我很抱歉,也许我只是没有正确理解您的代码:\
您将要将动画循环与添加粒子函数分开。您需要在动画功能中做的就是清除 canvas 并更新和绘制对象。添加到数组应该是一个单独的函数。每次单击按钮时,都会再次调用 requestAnimationFrame
,从而编译其效果。
function drawNewParticle(){
//Generate particle and add to array of particles
generateParticle = particleArray.push (new particle(
Math.random() * 1014,
Math.random() * 758,
1,
1,
10,
'hsla(0, 0%, 0%, 1)'
)
)
}
function animate() {
ctx.clearRect(0, 0, 1024, 768)
for(i=0; i< clickCount; i++){
particleArray[i].update()
particleArray[i].drawParticle()
}
requestAnimationFrame(animate)
}
animate();
目的是使用 class 粒子创建粒子(在用户单击按钮时),一旦它成为 运行 应该的,让用户可以控制速度,重力和其他一些东西。问题是每次用户点击创建一个新的粒子时,速度都会增加。
我不确定为什么,但是当我在没有请求动画框架的情况下演示它时,它看起来像它应该的那样工作,但如果它没有动画就没用了。
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const gravitySlider = document.getElementById('gravity-slider')
const output = document.getElementById('value')
//GENERIC PARTICLE CREATION
class particle{
constructor(positionX, positionY, velocityX, velocityY, radius, color,){
this.positionX = Math.max(radius, Math.min(1024 - radius, positionX))
this.positionY = Math.min(768 - radius, positionY)
this.velocityX = velocityX
this.velocityY = velocityY
this.radius = radius
this.color = color
}
update() {
if (
this.positionX > 1024 - this.radius || this.positionX < this.radius
) {
this.velocityX *= -1
}
if (this.positionY >= 768 - this.radius || this.positionY < this.radius) {
this.velocityY *= -1
}
this.velocityX *= 0.999
this.velocityY += 1
this.positionX += this.velocityX;
this.positionY += this.velocityY;
this.positionY = Math.min(768 - this.radius, this.positionY)
}
drawParticle() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.positionX, this.positionY, this.radius, 0, Math.PI * 2);
ctx.fill();
}
}
//CREATE BUTTON INTERACTIVITY AND CLICK COUNTING VARIABLE
const newParticleButton = document.getElementById('new-particle-button')
newParticleButton.onclick = drawNewParticle
//Even listener for click counting
let clickCount = 0
const clickCounter = document.querySelector('#new-particle-button')
clickCounter.addEventListener('click' ,function(event){
clickCount+= 1 })
const particleArray = []
//DRAW NEW PARTICLES ON BUTTON PRESS
function drawNewParticle(){
//Generate particle and add to array of particles
generateParticle = particleArray.push (new particle(
Math.random() * 1014,
Math.random() * 758,
1,
1,
10,
'hsla(0, 0%, 0%, 1)'
)
)
// clear canvas
ctx.clearRect(0, 0, 1024, 768)
for(i=0; i< clickCount; i++){
particleArray[i].update()
particleArray[i].drawParticle()
}
requestAnimationFrame(drawNewParticle)
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Canvas Basics</title>
<link rel="stylesheet" href="styles/index.css">
<script src="scripts/canvas.js" defer></script>
</head>
<body>
<canvas id="canvas" width="1024" height="768" style="border: 1px dashed">
Canvas is not supported
</canvas>
<button class="new-particle-button" id="new-particle-button">NEW PARTICLE</button>
<div class="slidecontainer">
<label for="gravity-slider">GRAVITY</label>
<input type="range" min="0" max="10" value="0" class="slider" id="gravity-slider">
<p>Value: <span id="value"></span></p>
</div>
</body>
</html>
我会检查一下你是否经常 运行 drawNewParticle
作为你的动画函数,我会把这个(你的粒子创建函数):
particleArray.push (new particle(
Math.random() * 1014,
Math.random() * 758,
1,
1,
10,
'hsla(0, 0%, 0%, 1)'
)
);
在按钮的事件侦听器下,因为看起来您正在屏幕上创建一个粒子数组,每帧都会获得一个新项目。
如果这没有帮助,我很抱歉,也许我只是没有正确理解您的代码:\
您将要将动画循环与添加粒子函数分开。您需要在动画功能中做的就是清除 canvas 并更新和绘制对象。添加到数组应该是一个单独的函数。每次单击按钮时,都会再次调用 requestAnimationFrame
,从而编译其效果。
function drawNewParticle(){
//Generate particle and add to array of particles
generateParticle = particleArray.push (new particle(
Math.random() * 1014,
Math.random() * 758,
1,
1,
10,
'hsla(0, 0%, 0%, 1)'
)
)
}
function animate() {
ctx.clearRect(0, 0, 1024, 768)
for(i=0; i< clickCount; i++){
particleArray[i].update()
particleArray[i].drawParticle()
}
requestAnimationFrame(animate)
}
animate();