最终我想知道在画布中点击了哪个对象,我编写了脚本:
dist.push(Math.abs(x-ball1.x-88.5) + Math.abs(y-ball1.y-110));
dist.push(Math.abs(x-ball2.x-88.5) + Math.abs(y-ball2.y-110));
dist.push(Math.abs(x-ball3.x-88.5) + Math.abs(y-ball3.y-110));
function sortNumber(a,b) {
return a - b;
}
dist.sort(sortNumber);
显然这只给我一些数字,但我需要它与ball1,ball2和ball3连接。我想我可以为此嵌套一个阵列,但我还没有想出逻辑...
或者我的方法可能从一开始就错了?
P.S。,显然如果我只有三个球,我可以这样做:
var b1d = Math.abs(x-ball1.x-88.5) + Math.abs(y-ball1.y-110);
var b2d = Math.abs(x-ball1.x-88.5) + Math.abs(y-ball1.y-110);
var b3d = Math.abs(x-ball1.x-88.5) + Math.abs(y-ball1.y-110);
dist.push(b1d, b2d, b3d);
function sortNumber(a,b) {
return a - b;
}
dist.sort(sortNumber);
if (dist[0] == b1d) {
alert('b1');
} else if (dist[0] == b2d) {
alert('b2');
} else if (dist[0] == d3d) {
alert('b3');
} else {
alert('####');
}
但如果我有数百个球,这可能不是最好的方式......
答案 0 :(得分:2)
你的搜索方式取决于你对球的处理方式,以及你如何放置它们。
这是一个简单的示例,您可以单击一个球并将其置于前台。 我们创造了200个球。
为了找到正确的球,我们开始搜索一次排序的数组,基于球的z-index(从背面的球到叶子上的球),因为你不能点击球在后面,我们从数组的最后一个元素开始搜索。
在这个例子中,这是一个很好的解决方案,但在你的应用程序中它可能不是,它取决于许多事情,比如球是否重叠,或者如果不是随机的。
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var getRandomColor = function() {
// Code from : http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
var createRandomBall = function(){
// The ball object
var ball = {};
// Random radius (min 5 max 30)
ball.radius = Math.floor((Math.random() * 25) + 5);
ball.radius2 = Math.pow(ball.radius, 2);
// Random x position
ball.x = Math.floor((Math.random() * (canvas.width - ball.radius*2)) + ball.radius);
// Random y position
ball.y = Math.floor((Math.random() * (canvas.height - ball.radius*2)) + ball.radius);
// Random color
ball.color = getRandomColor();
return ball;
}
// Create many balls
var ballList = [];
var tmp_ball;
for (var i = 0; i < 200; i++) {
// Make a random ball
tmp_ball = createRandomBall();
// Add to the list
ballList.push(tmp_ball);
}
// Render the balls
var renderBalls = function(){
var ball;
// For each ball
for (var i = 0; i < ballList.length; i++) {
ball = ballList[i];
// Stroke ball
context.beginPath();
context.arc(ball.x, ball.y, ball.radius - 1, 0, 2 * Math.PI, false);
context.fillStyle = ball.color;
context.fill();
context.lineWidth = 1;
context.strokeStyle = '#000000';
context.stroke();
}
}
// Render balls
renderBalls();
// Add click event
canvas.addEventListener('click', function(event){
// Get x and y of click
var click = {
x : event.clientX - canvas.offsetLeft,
y : event.clientY - canvas.offsetTop
};
var ball = null;
// Find clicked ball
// we search the array from the back,
// because on the back balls are over the frond balls
for (var i = ballList.length - 1; i >= 0; i--) {
if( Math.pow(click.x - ballList[i].x, 2) + Math.pow(click.y - ballList[i].y, 2) <= ballList[i].radius2 ){
ball = i;
break;
}
}
// If no ball found return
if(ball == null){
console.log("No ball clicked");
return;
}
// else ball found
ball = ballList.splice(ball, 1)[0];
// Else position ball on the frond
ballList.push(ball);
// Re-render
renderBalls();
}, false);
*{
padding: 0px;
margin: 0px;
}
#myCanvas{
position: absolute;
top: 10px;
right: 10px;
bottom: 10px;
left: 10px;
}
<canvas id="myCanvas" width="600" height="200"></canvas>
一般的解决方案是制作地图表,画布的网格,并在每个单元格上添加相应的球,以便您可以匹配单击的网格框并检查较小的一组球。 / p>
因此,举例来说,当你点击时,你想要的是,点击下的所有球都会改变颜色。这是一个将球映射到较小组的示例,我们制作了10列和5行的网格。每个球可能超过1组。我们创造了400个球。
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var getRandomColor = function() {
// Code from : http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
var gridSize = {x:10, y:5};
var gridList = [];
// Rows
for (var i = 0; i < gridSize.y; i++) {
gridList.push([]);
// Columns
for (var j = 0; j < gridSize.x; j++) {
gridList[i].push([]);
}
}
var createRandomBall = function(){
// The ball object
var ball = {};
// Random radius (min 5 max 30)
ball.radius = Math.floor((Math.random() * 25) + 5);
ball.radius2 = Math.pow(ball.radius, 2);
// Random x position
ball.x = Math.floor((Math.random() * (canvas.width - ball.radius*2)) + ball.radius);
// Random y position
ball.y = Math.floor((Math.random() * (canvas.height - ball.radius*2)) + ball.radius);
// Random color
ball.color = getRandomColor();
// Map ball - find cells that the circle overlap
grid = {
x : {
min : Math.floor((ball.x - ball.radius)*gridSize.x/canvas.width),
max : Math.floor((ball.x + ball.radius)*gridSize.x/canvas.width)
},
y : {
min : Math.floor((ball.y - ball.radius)*gridSize.y/canvas.height),
max : Math.floor((ball.y + ball.radius)*gridSize.y/canvas.height)
}
}
for (var y = grid.y.min; y <= grid.y.max; y++) {
for (var x = grid.x.min; x <= grid.x.max; x++) {
gridList[y][x].push(ball);
}
}
return ball;
}
// Create many balls
var ballList = [];
var tmp_ball;
for (var i = 0; i < 400; i++) {
// Make a random ball
tmp_ball = createRandomBall();
// Add to the list
ballList.push(tmp_ball);
}
// Render the balls
var renderBalls = function(){
var ball;
// For each ball
for (var i = 0; i < ballList.length; i++) {
ball = ballList[i];
// Stroke ball
context.beginPath();
context.arc(ball.x, ball.y, ball.radius - 1, 0, 2 * Math.PI, false);
context.fillStyle = ball.color;
context.fill();
context.lineWidth = 1;
context.strokeStyle = '#000000';
context.stroke();
}
for (var i = 0; i < gridSize.x + 1; i++) {
context.beginPath();
context.moveTo((canvas.width/gridSize.x)*i, 0);
context.lineTo((canvas.width/gridSize.x)*i, canvas.height);
context.stroke();
}
for (var i = 0; i < gridSize.y + 1; i++) {
context.beginPath();
context.moveTo(0, (canvas.height/gridSize.y)*i);
context.lineTo(canvas.width, (canvas.height/gridSize.y)*i);
context.stroke();
}
}
// Render balls
renderBalls();
// Add click event
canvas.addEventListener('click', function(event){
// Get x and y of click
var click = {
x : event.clientX - canvas.offsetLeft,
y : event.clientY - canvas.offsetTop
};
var grid = {
x : Math.floor(click.x*gridSize.x/canvas.width),
y : Math.floor(click.y*gridSize.y/canvas.height)
};
var ball = 0;
var smallerList = gridList[grid.y][grid.x];
// Find clicked ball
for (var i = smallerList.length - 1; i >= 0; i--) {
if( Math.pow(click.x - smallerList[i].x, 2) + Math.pow(click.y - smallerList[i].y, 2) <= smallerList[i].radius2 ){
ball++;
smallerList[i].color = getRandomColor();
}
}
console.log("Group["+grid.y+"]["+grid.x+"], " + smallerList.length + " balls in group, clicked " + ball + " balls");
// If no ball found return
if(ball == 0){
return;
}
// Re-render
renderBalls();
}, false);
*{
padding: 0px;
margin: 0px;
}
#myCanvas{
position: absolute;
top: 10px;
right: 10px;
bottom: 10px;
left: 10px;
}
<canvas id="myCanvas" width="600" height="200"></canvas>