Click в canvas по нескольким элементам

325
15 августа 2017, 16:48

Хочу сделать кликабельными картинки-'спутники', вращающиеся вокруг десяти 'планет'. У всех 'планет' разное кол-во 'спутников'(из массива images)..)

Фрагмент кода:

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var W = window.innerWidth,
  H = window.innerHeight;
canvas.width = W;
canvas.height = H;
var angle = 0;
var currentAngle = 0;
var TO_RADIANS = Math.PI / 180;
var particles = [];
var Lradius = 20;
var radius = 80;
var images = [
  ['img/1', 'img/2', 'img/3', 'img/4', 'img/5'],
  ['img/6', 'img/7'],
  ['img/8', 'img/9', 'img/10', 'img/11'],
  ['img/12', 'img/13', 'img/14', 'img/15'],
  ['img/16', 'img/17', 'img/18'],
  ['img/19', 'img/20', 'img/21'],
  ['img/22', 'img/23', 'img/24'],
  ['img/26', 'img/25'],
  ['img/27', 'img/28'],
  ['img/29', 'img/31', 'img/32']
];
function Particle() {
  this.images = images[i];
  this.radius = 20;
  this.radis = 80;
  this.x = Math.floor((Math.random() * canvas.width / 2) +
    this.radius * 1.5);
  this.y = Math.floor((Math.random() * canvas.height / 2) +
    this.radius * 1.5);
  this.speedx = Math.round((Math.random() * 101) + 0) / 100;
  this.speedy = Math.round((Math.random() * 101) + 0) / 100;
  this.move = function() {

    context.beginPath();
    context.globalCompositeOperation = "source-over";
    //картинка - 'планета'
    context.save();
    context.translate(this.x, this.y);
    context.rotate(Gangle * TO_RADIANS);
    var image = new Image();
    image.src = 'img/bag.png';
    context.drawImage(image, 20, -20, 40, 40);
    context.restore();
    angle += 0.1;
    for (var m = 0; m < this.images.length; m++) {
      //картинки - "спутники" на каждую планету
      var satellit = new Image();
      satellit.src = this.images[m];
      var vx = Math.cos(m + currentAngle) * this.radius;
      var vy = Math.sin(m + currentAngle) * this.radius;
      this.Ax = (this.x - this.Lradius) + vx;
      this.Ay = (this.y - this.Lradius) + vy;
      context.drawImage(image2, this.Ax, this.Ay, 20, 20);
    }
  }
};
for (var i = 0; i < 10; i++) {
  var particle = new Particle();
  particles.push(particle);
}
function animate() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  for (var i = 0; i < particles.length; i++) {
    particles[i].move();
  }
  requestAnimFrame(animate);
}
animate();
canvas.addEventListener('mousedown', function(e) {
  // так получается кликнуть только по одному 'спутнику' каждой 'планеты', если их создавать совсем отдельными объектами - орбиты 'планет' и 'спутников' не совпадают..
  // Как сохранить сопряжение орбит и правильно перебрать 'спутники' каждой 'планеты'?

  var xCoord = e.offsetX;
  var yCoord = e.offsetY;
  for (var i = 0; i < particles.length; i++) {
    if ((xCoord >= particles[i].Ax - particles[i].Lradius && xCoord <= particles[i].Ax + particles[i].Lradius) && (yCoord >= particles[i].Ay - particles[i].Lradius && yCoord <= particles[i].Ay + particles[i].Lradius)) {
      alert('click');
    }
  }
});
Answer 1

Я бы предложил сделать так:

/** 
 * Спутник 
 * @param {Object} data 
 * @param {Planet} planet 
 * @constructor 
 */ 
function Satellite(data, planet) { 
  this.planet = planet; 
  this.x = data.x; 
  this.y = data.y; 
 
  this.move = function move() { 
    /* реализация движения спутника */ 
 
    // при этом здесь доступны данные планеты 
    this.planet.x; 
    this.planet.y; 
  } 
} 
 
/** 
 * Планета 
 * @param {Object} data 
 * @constructor 
 */ 
function Planet(data) { 
  this.radius = data.radius; 
  this.satellites = []; 
  this.x = data.x; 
  this.y = data.y; 
 
  for (var i = 0; i < data.satellites.length; i++) { 
    this.satellites.push(new Satellite(data.satellites[i], this)); 
  } 
 
  this.move = function move() { 
    /* реализация движения только планеты */ 
 
    // и запуск движения спутников 
    for (var i = 0; i < this.satellites.length; i++) { 
      this.satellites[i].move(); 
    } 
  } 
} 
 
// данные о планетах 
var data = [{ 
  name: 'Earth', 
  radius: 80, 
  x: 100, 
  y: 100, 
  satellites: [{ 
    name: 'Moon', 
    radius: 10, 
    x: 20, // относительно земли 
    y: 20 
  }] 
}, { 
  name: 'Mars', 
  radius: 40, 
  x: 160, 
  y: 180, 
  satellites: [{ 
    name: 'Satellite name', 
    radius: 1, 
    x: 14, // относительно земли 
    y: 18 
  }] 
}]; 
 
// здесь экземпляры планет 
var planets = []; 
 
// создаём планеты и сохраняем их в переменную planets 
for (var i = 0; i < data.length; i++) { 
  planets.push(new Planet(data[i])); 
}

В каждый момент времени любая планета знает о своих спутниках, а спутники знают о своих планетах.

READ ALSO
Рывки страницы при прокрутке к якорю

Рывки страницы при прокрутке к якорю

ПриветЕсть горизонтальное меню, которое прокручивается вместе с страницей вниз

242
Как получить обновления из csv файла - NodeJS

Как получить обновления из csv файла - NodeJS

Как получить обновления из файла csv без загрузки всего файла при каждом изменении , и если это невозможно, то какой из наиболее эффективных...

224
Uncaught TypeError: Cannot read property &#39;checked&#39; of null

Uncaught TypeError: Cannot read property 'checked' of null

В ЧЕМ ОШИБКАкак исправить?

194