我得到了这个 HTML5 canvas 项目,我正在为此苦苦挣扎。 基本上我试图在点击时添加一个新的粒子。 并将粒子插入粒子阵列,但是 粒子不显示。我可以看到粒子被推到带有鼠标坐标的数组中,但似乎并没有绘制出最后一个粒子。 我做错了什么?
参见示例。
// Request animation frame
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
// Canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Set full-screen
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Options
var num = 100; // Number of particles to draw
var size = 2; // Particle size
var color = '#dd64e6'; // Particle color
var min_speed = .3; // Particle min speed
var max_speed = 2; // Particle max speed
var dist = 100; // Max distance before line gets cut
var dist_sq = dist * dist; // Dist squared
var line_width = 2; // Line width
var background = '#181b23'; // Background color
var line_color = '#1d2631'; // Line color
var fps = 60;
var now, delta;
var then = Date.now();
var interval = 1000 / fps;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
num = 10;
fps = 29;
}
// Particles array
var particles = [];
for (var i = 0; i < num; i++) {
particles.push(
new create_particle(false, false)
);
}
// Lets animate the particle
function draw() {
// Loop
requestAnimationFrame(draw);
now = Date.now();
delta = now - then;
if (delta > interval) {
then = now - (delta % interval);
// Background
ctx.fillStyle = background;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Lets draw particles from the array now
draw_particles();
}
}
// Draw particles
function draw_particles() {
for (var t = 0; t < num; t++) {
// This particle
var p = particles[t];
for (var q = t + 1; q < num; q++) {
// Check X first, maybe we don't need to
// calculate Y
var x = particles[q].x - p.x;
if ((x *= x) < dist_sq) {
// Check passed, calculate Y
var y = particles[q].y - p.y;
if (x + (y * y) < dist_sq) {
// Check passed, draw line
draw_line(p.x, p.y, particles[q].x, particles[q].y);
}
}
}
// Color
ctx.fillStyle = color;
// Circle path
ctx.beginPath();
ctx.arc(p.x, p.y, p.radius, Math.PI * 2, false);
ctx.fill();
// Lets use the velocity now
p.x += p.vx;
p.y += p.vy;
// If there is only 1 particle
// show X, Y, and velocity
if (num === 1) {
ctx.fillText('Y:' + p.y, 20, 20);
ctx.fillText('X:' + p.x, 20, 40);
ctx.fillText('YV:' + p.vy, 20, 60);
ctx.fillText('XV:' + p.vx, 20, 80);
}
// To prevent the balls from moving out of the canvas
if (p.x < size) p.vx *= (p.vx / -p.vx);
if (p.y < size) p.vy *= (p.vy / -p.vy);
if (p.x > canvas.width - size) p.vx *= (-p.vx / p.vx);
if (p.y > canvas.height - size) p.vy *= (-p.vy / p.vy);
}
}
// Return a particle object
function create_particle(xPos, yPos) {
// Position
if (xPos == false && yPos == false) {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
} else {
this.x = xPos;
this.y = yPos;
}
// Velocity
this.vx = random_int_between(min_speed, max_speed);
this.vy = random_int_between(min_speed, max_speed);
// Size
this.radius = size;
console.log('particle created at: ' + this.x + ', ' + this.y);
}
// Returns an random integer, positive or negative
// between the given value
function random_int_between(min, max) {
var num = Math.floor(Math.random() * max) - min;
num *= Math.floor(Math.random() * 2) == 1 ? 1 : -1;
return num;
}
// Draw a line between 2 particles
// given the particles x and y position
function draw_line(p_x, p_y, p2_x, p2_y) {
ctx.beginPath();
ctx.lineWidth = line_width;
ctx.strokeStyle = line_color;
ctx.moveTo(p_x, p_y);
ctx.lineTo(p2_x, p2_y);
ctx.stroke();
}
// When the canvas is clicked
// add new particle
function clicked(e) {
var mouseXpos, mouseYpos;
if (e.offsetX) {
mouseXpos = e.offsetX;
mouseYpos = e.offsetY;
} else if (e.layerX) {
mouseXpos = e.layerX;
mouseYpos = e.layerY;
}
particles.push(
new create_particle(mouseXpos, mouseYpos)
);
}
canvas.addEventListener('click', function(e) {
clicked(e);
}, false);
draw();<!DOCTYPE html>
<html>
<head>
<style>
* {margin:0;padding:0;overflow:hidden;}
</style>
</head>
<body>
<canvas id="canvas">{{-- The background --}}</canvas>
</body>
</html>
最佳答案
好吧,除了在评论中没有其他人回答这个问题,我想我会回答这个问题,这样其他人可能不会对同样的事情感到疑惑。
问题是您使用变量“num”来保存粒子数。如果您改为使用“particles.length”,则可以
// Request animation frame
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
// Canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Set full-screen
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Options
var num = 100; // Number of particles to draw
var size = 2; // Particle size
var color = '#dd64e6'; // Particle color
var min_speed = .3; // Particle min speed
var max_speed = 2; // Particle max speed
var dist = 100; // Max distance before line gets cut
var dist_sq = dist * dist; // Dist squared
var line_width = 2; // Line width
var background = '#181b23'; // Background color
var line_color = '#1d2631'; // Line color
var fps = 60;
var now, delta;
var then = Date.now();
var interval = 1000 / fps;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
num = 10;
fps = 29;
}
// Particles array
var particles = [];
for (var i = 0; i < num; i++) {
particles.push(
new create_particle(false, false)
);
}
// Lets animate the particle
function draw() {
// Loop
requestAnimationFrame(draw);
now = Date.now();
delta = now - then;
if (delta > interval) {
then = now - (delta % interval);
// Background
ctx.fillStyle = background;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Lets draw particles from the array now
draw_particles();
}
}
// Draw particles
function draw_particles() {
for (var t = 0; t < particles.length; t++) {
// This particle
var p = particles[t];
for (var q = t + 1; q < particles.length; q++) {
// Check X first, maybe we don't need to
// calculate Y
var x = particles[q].x - p.x;
if ((x *= x) < dist_sq) {
// Check passed, calculate Y
var y = particles[q].y - p.y;
if (x + (y * y) < dist_sq) {
// Check passed, draw line
draw_line(p.x, p.y, particles[q].x, particles[q].y);
}
}
}
// Color
ctx.fillStyle = color;
// Circle path
ctx.beginPath();
ctx.arc(p.x, p.y, p.radius, Math.PI * 2, false);
ctx.fill();
// Lets use the velocity now
p.x += p.vx;
p.y += p.vy;
// If there is only 1 particle
// show X, Y, and velocity
if (num === 1) {
ctx.fillText('Y:' + p.y, 20, 20);
ctx.fillText('X:' + p.x, 20, 40);
ctx.fillText('YV:' + p.vy, 20, 60);
ctx.fillText('XV:' + p.vx, 20, 80);
}
// To prevent the balls from moving out of the canvas
if (p.x < size) p.vx *= (p.vx / -p.vx);
if (p.y < size) p.vy *= (p.vy / -p.vy);
if (p.x > canvas.width - size) p.vx *= (-p.vx / p.vx);
if (p.y > canvas.height - size) p.vy *= (-p.vy / p.vy);
}
}
// Return a particle object
function create_particle(xPos, yPos) {
// Position
if (xPos == false && yPos == false) {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
} else {
this.x = xPos;
this.y = yPos;
}
// Velocity
this.vx = random_int_between(min_speed, max_speed);
this.vy = random_int_between(min_speed, max_speed);
// Size
this.radius = size;
console.log('particle created at: ' + this.x + ', ' + this.y);
}
// Returns an random integer, positive or negative
// between the given value
function random_int_between(min, max) {
var num = Math.floor(Math.random() * max) - min;
num *= Math.floor(Math.random() * 2) == 1 ? 1 : -1;
return num;
}
// Draw a line between 2 particles
// given the particles x and y position
function draw_line(p_x, p_y, p2_x, p2_y) {
ctx.beginPath();
ctx.lineWidth = line_width;
ctx.strokeStyle = line_color;
ctx.moveTo(p_x, p_y);
ctx.lineTo(p2_x, p2_y);
ctx.stroke();
}
// When the canvas is clicked
// add new particle
function clicked(e) {
var mouseXpos, mouseYpos;
if (e.offsetX) {
mouseXpos = e.offsetX;
mouseYpos = e.offsetY;
} else if (e.layerX) {
mouseXpos = e.layerX;
mouseYpos = e.layerY;
}
particles.push(
new create_particle(mouseXpos, mouseYpos)
);
}
canvas.addEventListener('click', function(e) {
clicked(e);
}, false);
draw();<!DOCTYPE html>
<html>
<head>
<style>
* {margin:0;padding:0;overflow:hidden;}
</style>
</head>
<body>
<canvas id="canvas">{{-- The background --}}</canvas>
</body>
</html>
我敢于走出我们的问题范围,因为您可以通过使用 Array.prototype.forEach 来防止将来出现此类问题,并移动点的绘制并将它们约束到新函数。具有简化代码的额外好处。
// Draw particles
function draw_particles() {
particles.forEach(function(p,pi){
particles.forEach(function(p2,p2i){
if(pi === p2i){
return;
}
// Check X first, maybe we don't need to
// calculate Y
var x = p2.x - p.x;
if ((x *= x) < dist_sq) {
// Check passed, calculate Y
var y = p2.y - p.y;
if (x + (y * y) < dist_sq) {
// Check passed, draw line
draw_line(p.x, p.y, p2.x, p2.y);
draw_dot(p);
constrain(p);
}
}
});
});
}
// Draw particle
function draw_dot(p){
// Color
ctx.fillStyle = color;
// Circle path
ctx.beginPath();
ctx.arc(p.x, p.y, p.radius, Math.PI * 2, false);
ctx.fill();
ctx.closePath();
// Lets use the velocity now
p.x += p.vx;
p.y += p.vy;
// If there is only 1 particle
// show X, Y, and velocity
if (particles.length === 1) {
ctx.fillText('Y:' + p.y, 20, 20);
ctx.fillText('X:' + p.x, 20, 40);
ctx.fillText('YV:' + p.vy, 20, 60);
ctx.fillText('XV:' + p.vx, 20, 80);
}
}
// Constrain particle movement
function constrain(p){
// To prevent the balls from moving out of the canvas
if (p.x < size) p.vx *= (p.vx / -p.vx);
if (p.y < size) p.vy *= (p.vy / -p.vy);
if (p.x > canvas.width - size) p.vx *= (-p.vx / p.vx);
if (p.y > canvas.height - size) p.vy *= (-p.vy / p.vy);
}
使用 Array.prototype.length 和 Array.prototype.forEach 可以降低出现数组索引问题的风险。
关于javascript - Canvas onClick 添加到数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43413068/
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作