Невозможно обновить положение изображения в CSS с помощью JavaScript - PullRequest
1 голос
/ 10 октября 2019

В моей программе есть какой-то бегун (анимация-изображение), который перемещается из положения x в y при нажатии на кнопку пуска. Я хочу добавить кнопку (реверс) по завершении, чтобы при нажатии изображение перемещалось из y вx.

Вот ссылка на мою js-скрипку: https://jsfiddle.net/o6egL4qr/

Я добавил кнопку реверса, но при нажатии на нее изображение вообще не двигается.

class raceManager {
  raceCount = 0;
  races = [];

  addRace() {
    var mainContainer = document.getElementById('mainContainer');
    mainContainer.appendChild(document.createElement('br'));
    var race = new raceClass(this.raceCount);
    this.races.push(race);
    this.raceCount++;
  }
}

class raceClass {
  runners = [];
  count;
  runnerCount = 0;
  raceDiv = document.createElement('div');
  raceNum = document.createElement('div');
  startRaceButton = document.createElement('input');
  addRunnerButton = document.createElement('input');
  revRaceButton = document.createElement('input');
  tableDiv = document.createElement('div');
  tableNum = document.createElement('div');
  startInterval;
  startTime;
  revStartTime;
  reverseInterval;
  constructor(number) {

    // store the race no.
    this.count = number;

    // delcare the race div id
    this.raceNum.id = 'raceNum' + this.count;

    // delcare the table div id
    this.tableNum.id = 'tableNum' + this.count;

    // Add raceDiv to the race
    document.getElementById('races').appendChild(this.raceDiv);

    // Add tableDiv to the race
    document.getElementById('tables').appendChild(this.tableDiv);

    this.applyDivProperty();
    this.initializeButtons();
  }

  applyDivProperty() {
    // apply properties to the tableNum
    this.tableNum.style.display = "inline-block";

    // apply properties to the raceDiv
    this.raceDiv.id = "Race" + this.count;
    document.getElementById(this.raceDiv.id).classList.add("raceDivClass");
    this.raceDiv.appendChild(this.raceNum);
    document.getElementById(this.raceNum.id).innerHTML = '<p>Race: ' + this.count + '</p>';

    // append the add race button
    this.raceDiv.appendChild(this.addRunnerButton);

    // apply properties to the tableDiv
    this.tableDiv.id = "Table" + this.count;
    document.getElementById(this.tableDiv.id).classList.add("tableClass");
    this.tableDiv.appendChild(this.tableNum);
    document.getElementById(this.tableNum.id).innerHTML = '<p>Table: ' + this.count + '</p>';
  }

  initializeButtons() {
    // initialize add runner button
    this.addRunnerButton.type = 'Button';
    this.addRunnerButton.value = 'Add Runner';
    this.addRunnerButton.id = 'AddRunner' + this.count;
    this.addRunnerButton.onclick = this.addRunner.bind(this);

    // initialize start race buttton
    this.startRaceButton.type = 'Button';
    this.startRaceButton.value = 'Start Race';
    this.startRaceButton.id = "startRaceButton" + this.count;
    this.startRaceButton.onclick = this.startRace.bind(this);

    // initialize reverse race buttton
    this.revRaceButton.type = 'Button';
    this.revRaceButton.value = 'Reverse Race';
    this.revRaceButton.id = "revRaceButton" + this.count;
    this.revRaceButton.onclick = this.revRace.bind(this);
  }

  addRunner() {
    var track = new Runner(this); //Initialize the runner object 
    this.runners.push(track); //Store the runner object in runners array of Race class
    if (this.runnerCount > 0) {
      // append the start race button
      this.raceDiv.appendChild(this.startRaceButton);
    }
    this.runnerCount++;
  }

  startRace() {
    this.startTime = Date.now();
    this.startInterval = setInterval(() => {
      this.runners.forEach(function(element) {
        element.animate();
      });
      document.getElementById(this.startRaceButton.id).disabled = "true";
      document.getElementById(this.addRunnerButton.id).disabled = "true";
    }, 50);
  }

  stop() {
    clearInterval(this.startInterval);

    // append the start race button
    this.raceDiv.appendChild(this.revRaceButton);
  }

  revRace() {
    this.revStartTime = Date.now();
    this.reverseInterval = setInterval(() => {
      this.runners.forEach(function(element) {
        element.animateReverse();
      });
      document.getElementById(this.revRaceButton.id).disabled = "true";
    }, 50);
  }

  stopRev() {
    clearInterval(this.reverseInterval);
  }
}

class Runner {
  count = 0;
  parent;
  track;
  sprite;
  timeTaken;
  trackWidth;
  element;
  speed;
  table;
  printCount = 1;
  stepCount = 1;
  trackNum;
  tbl;
  lastStep;

  constructor(race) {
    // initialize the divs
    this.parent = race;
    this.track = document.createElement('div');
    this.sprite = document.createElement('div');
    this.table = document.createElement('table');

    // assigns #id to table and track corresponding with parent div.
    this.table.id = race.tableNum.id + '_Table_' + this.parent.runnerCount;
    this.track.id = race.raceNum.id + '_Track_' + this.parent.runnerCount;

    this.createUI();

    this.timeTaken = ((Math.random() * 5) + 3);

    this.speed = this.trackWidth / (this.timeTaken * 1000);

    console.log(this.trackWidth, this.timeTaken);
    console.log(this.timeTaken * 100);
  }

  createUI() {
    this.count = this.parent.runnerCount;
    this.createTable();
    this.createTrack();
    this.createSprite();
  }

  createTable() {
    var parentDiv1 = document.getElementById(this.parent.tableNum.id);
    parentDiv1.appendChild(this.table);
    this.table.setAttribute = "border"
    this.table.border = "1";
    document.getElementById(this.table.id).classList.add("tableClass");

    this.tbl = document.getElementById(this.table.id);
    this.addRow("Track " + (this.count + 1), "");
    this.addRow("Time", "Distance");
  }

  addCell(tr, val) {
    var td = document.createElement('td');
    td.innerHTML = val;
    tr.appendChild(td)
  }

  addRow(val_1, val_2) {
    var tr = document.createElement('tr');
    this.addCell(tr, val_1);
    this.addCell(tr, val_2);
    this.tbl.appendChild(tr)
  }

  createTrack() {
    var parentDiv = document.getElementById(this.parent.raceNum.id);
    parentDiv.appendChild(this.track);
    this.track.appendChild(this.sprite);
    document.getElementById(this.track.id).classList.add("trackClass");
    this.trackWidth = this.track.getBoundingClientRect().width;
  }

  createSprite() {
    this.sprite.id = this.track.id + "_Runner";
    document.getElementById(this.sprite.id).classList.add("spriteClass");
    this.element = document.getElementById(this.sprite.id);
  }

  animate() {
    // declare time variables
    var timeNow = Date.now();
    var timespent = timeNow - this.parent.startTime;
    var diff = Math.floor(this.timeTaken * 100);

    // step is position of sprite.
    var step = timespent * this.speed;

    // Print table for all tracks with 10 laps.
    if ((Math.round(timespent / 50) * 50) == (Math.round(((diff - 25) * this.printCount) / 50) * 50)) {
      this.addRow(this.printCount + ": " + timespent, (Math.floor(step)));
      this.printCount++;
    }

    // check condition to stop
    if (step > this.trackWidth - 23) {
      document.getElementById(this.parent.raceNum.id).innerHTML += 'Winner: Runner' + (this.count + 1);
      this.parent.stop();
    }

    this.element.style.left = step + 'px';

    // ------------sprite animation----------------

    // start position for the image slicer
    var position = (3 - (Math.floor(step / 6.5) % 4)) * 25;

    // we use the ES6 template literal to insert the variable "position" 
    this.element.style.backgroundPosition = `${position}px 0px`;
  }

  animateReverse() {
    // declare time variables
    var timeNow = Date.now();
    var timespent = timeNow - this.parent.revStartTime;
    var diff = Math.floor(this.timeTaken * 100);
    console.log(this.count + " position of step " + this.element.style.left);

    while (this.stepCount < 2) {
      this.lastStep = parseFloat(this.element.style.left);
      this.stepCount++;
    }
    console.log(this.count + " this is lastStep " + this.lastStep);

    // step is position of sprite.
    var step = this.lastStep - (this.speed * timespent);

    // Print table for all tracks with 10 laps.
    if ((Math.round(timespent / 50) * 50) == (Math.round(((diff - 25) * this.printCount) / 50) * 50)) {
      this.addRow(this.printCount + ": " + timespent, (Math.floor(step)));
      this.printCount++;
    }

    // check condition to stop
    if (step < 25) {
      document.getElementById(this.parent.raceNum.id).innerHTML += 'Winner: Runner' + (this.count + 1);
      this.parent.stopRev();
    }

    this.element.style.left = step + 'px';

    // ------------sprite animation----------------

    // start position for the image slicer
    //var position = (3 - (Math.floor(step / 6.5) % 4)) * 25;

    //this.element.style.backgroundPosition = position + 'px 0px';
  }
}
manager = new raceManager();
#tableContainer {
  float: left;
}

#addRaces {
  text-align: center;
}

.raceDivClass {
  margin: 1% auto;
  width: 60%;
  text-align: center;
  border: 1px solid;
}

.tableClass {
  text-align: center;
  border: 1px solid;
  margin: 5px;
  float: left;
}

.trackClass {
  background-color: black;
  height: 30px;
  width: 98%;
  margin: 1%;
  position: relative;
}

.spriteClass {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGgAAAAeCAYAAADAZ1t9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAASwSURBVGhD7Zq/axRBFMfv9u4MxATUSgsVm3QWigYbexuxUkiaKIqNoIUiwRSJoJLCxpSCaJoEYimo/4AgQVRIZxdBEIREYwzc5X74vndvlrm5mdnZ3dm9oPnAsDubu52Z93373pvNFQsJOXO9NUKHsU4vZPH90+IXPt/FA2kEmqbDTKcX8pza7K5I/vAtEJghge7zeSrwlDYbtYlmfWuILxWC8uBmUNoz/784wY4WaPRq9SGJcY+7Mt7GEOzUkB0pkGHi4Ci1K53TEK8h7tTE+pPywL6b3JXJQqBcQ7arQwR87AE34ElPUsPE1ZapODsErFHnnD7AfVWb9oylFYjVFcKoQuQC5kD55hB3Qxrbf17RYbHT+/fpCXGSOEmEaYcevofwhkRxXM0/VCi8azXr3+q1Xw8+LRxZ4cte4PneoHaQ2iVck0gVThVbyOhSRM9YOoFMyR9eW6KmLkAGYW6Vmjx47AViUfSkPC5V9p7nS23q1Z9zH+b33+KuF9iAOocUa0lcKFjubQJ2h51D5zbmIAVM9gc1mzgAE0kdFlFaq+JkQYQBV+FYOYoDGy9Tw3dgQ7QxnUBQUHxAtJfUhqllDhbWam4f525mJDCgMynufZFa13d6BILHsOeEjS6PUjMNtsRHFXgExI2V0PN6egiEkTzFMdlJgM/3zMd1H2Tzhjlqa53TLhLFbsvep9Cob70uFsuffbxJoHWZcq1A5CCZyDUZ7gtxotKDCsafdRHIZSFe9j9wBl1xoIJSuxhUVpIK5eB0JiILHo29EouDtVmLBF4IKjIbWOQkfzYVruENn+ESXFe+upBJeDMQVfWiyXQ5fFQV57oQLyLJL0VlsAfi06yJyhMuIOci7Efdqy0ENzxxonVFI22IY0NDHN1mykaX+nHAmKbw1qhtLLVaze8U1o6Jv9OmdaEYlI1lsLQGGVGwmMKbKZ8KXHIQxnUJn062CgVSFmQTRjySpr8n2nlb3lxTztl8W6+u3x0YOlylrpij1Vi0Hl3uxNx/U9MWIYSPtwZxclukSG2B4qreOTV+3skzBBgbuafVrJ0sVYbO8eUe4r5FMAgEbEnbSSC2l/p0grgRB1jHDGKqjt019kkwvoid4okS4D7O+Qji4MmxiQMonI2cGP/qYwMbt6LSAXFEzpCbyYaJcxuKBAwWJQ5EwATCTScLBeUhVGKRTIWBCgQsVYavcdcF8UZEnVveYPwXfIwNBMJCdF/GNeEZCFnahMzX1A0dgEi6MJALigP1SyiMCdu9wZH7sZBzkGpM5zcBljAZGdNPX964UAhKt0vlwbN8SQs2p/Xq2lTSfzU4hvK0OUily4b0PV1etI4Z+SbBFYMBrIPjO1QuT1N+GedLbVC1FYM9Hyk31fgScHYYE5JhD1Dz/r+fKPoqEJAMILAa1VRaU+HwaPnZwBR3vWJwJCDCUSonsKERKHJMrwLFAYbSbUwRyujanawMZfBikPXTEzvCgKhXPZmhe+/W2ZCuTWXpxQbgyWGFmhGILLb8p6V/AmnKa+Qd3783cCDz0JaGvgmEX4jyaRu8W6N8NM/dPGlvvvk8T5ye2r7mIIQ5PEl5/pyXc4FzIeOLZOMWCn8Bh1eBvOSZzIIAAAAASUVORK5CYII=');
  position: absolute;
  height: 30px;
  width: 25px;
}
<!DOCTYPE html>
<html>

<head>
</head>

<body>

  <div id="mainContainer">
    <div id="addRaces">
      <input type="Button" value="Add Race" onclick="manager.addRace()">
    </div>
    <div id="races">

    </div>
    <br>
  </div>
  <div id="tableContainer">
    <div id="tables"></div>
  </div>

</body>

</html>

Я ожидаю, что он переместится от y к x после нажатия кнопки реверса, но он не двигается.

1 Ответ

0 голосов
/ 10 октября 2019

Когда вы запускаете функцию реверса, элементы больше не ссылаются на элементы dom. Я на самом деле не уверен, почему это так, может быть, кто-то другой может подключиться.

В любом случае, это решит вашу проблему:

Замените this.element.style.left = step + 'px';

на: document.getElementById(this.element.id).style.left = step + 'px';

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