Как получить промежуточное значение атрибута элемента d3 во время перехода? - PullRequest
1 голос
/ 30 мая 2019

Я пытаюсь создать простую игру SVG, чтобы поймать движущийся круг.Есть кнопка catchCircle, движущаяся preyCircle и Catch Me .catchCircle начинает двигаться вертикально от нижней части экрана, пересекает preyCircle и исчезает вверху.Идея состоит в том, чтобы нажать кнопку, когда preyCircle перекрывает catchCircle.В этом случае мне просто нужно проверить, меньше ли расстояние cy атрибутов обоих кругов, чем сумма их radius.

Проблема, с которой я здесь сталкиваюсь, заключается в получении атрибута cycatchCircle пока идет переход.Если я пытаюсь получить preyCircle.attr('cy') изнутри onclick метода события, появляется сообщение об ошибке: «Uncaught Error: слишком поздно; уже выполняется»

<div id="canvas"></div>
<button id="catchMe"> Catch Me </button>
<span id="msg"></span>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
const width = 200, height = 300, radius = 10;
const svg = d3.select('#canvas')
    .append('svg')
    .attr('width', width)
    .attr('height', height);

const catchCircle = svg.append('circle')
  .attr('r', radius)
  .attr('cx', width / 2)
  .attr('cy', 100)
  .attr('stroke', 'red')
  .attr('stroke-width', 3)
  .attr('fill', 'none');

const preyCircle = svg.append('circle')
  .attr('r', radius)
  .attr('cx', width / 2)
  .attr('cy', height - radius)
  .attr('fill', 'red')
  .transition()
    .duration(5000)
    .delay(1000)
    .attr('cy', radius)
    .remove();

d3.select('#catchMe')
  .on('click', () => {
    catched = false;

    // Need to get if catchCircle and preyCircle overlapped while clicking
    // I am stuck here!!!

    const msgSpan = d3.select('#msg');
    msgSpan.node().textContent = catched? "Perfect! :)" : "Oh no! :(";
  });
</script>

Мой код работает на https://jsfiddle.net/avi5102005/uh627zt5/62/.

Может ли кто-нибудь вести меня так, как я должен был подойти?Заранее спасибо.

1 Ответ

1 голос
/ 30 мая 2019

Сначала добавьте Id в свои круги

const catchCircle = svg.append('circle')
    .attr('r', radius)
  .attr('cx', width / 2)
  .attr('cy', 100)
  .attr("id", "catch") //add ID
  .attr('stroke', 'red')
  .attr('stroke-width', 3)
  .attr('fill', 'none');

const preyCircle = svg.append('circle')
    .attr('r', radius)
  .attr('cx', width / 2)
  .attr('cy', height - radius)
  .attr('fill', 'red')
  .attr("id", "prey") //add ID 
  .transition()
    .duration(5000)
    .delay(1000)
    .attr('cy', radius)
    .remove();

затем нажмите на кнопку do:

d3.select('#catchMe')
    .on('click', () => {
    catched = false;
     let py = d3.select("#prey").attr("cy"); // get prey's y
     let px = d3.select("#prey").attr("cx"); // get prey's x
     let pr = +d3.select("#prey").attr("r"); // get prey's radius

     let cy = d3.select("#catch").attr("cy");
     let cx = d3.select("#catch").attr("cx");
     let cr = +d3.select("#catch").attr("r");

     //Pythagoras distance formula
     let distance = Math.pow(px-cx, 2) + Math.pow(py-cy, 2);
     catched = Math.sqrt(distance) < cr + pr; //check if overlap

    const msgSpan = d3.select('#msg');
    msgSpan.node().textContent = catched? "Perfect! :)" : "Oh no! :(";
  });

рабочий код здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...