Почему объект не перемещается по координатам? - PullRequest
0 голосов
/ 01 июля 2018

Я реализовал класс Circle со свойствами:

  • x - начальное значение координаты x
  • y - начальное значение координаты y
  • диаметр - значения ширины и высоты
  • цвет - цвет заливки

Метод: draw() - рисует на экране элемент, который описывается указанными свойствами.

Метод: move({x = 0, y = 0}) - перемещает нарисованный объект по вектору (x, y) - каждый период времени (100 мс) изменяет (добавляет \ вычитает) координаты на значения x и y в соответствии.

И внутренний метод update(), который изменяет положение нарисованного круга с соответствующими значениями цвета, x, y объекта.

Скажите, почему мой круг не движется с заданными координатами с интервалом в 1 секунду?

class Circle {
    constructor(options) {
        this.x = options.x;
        this.y = options.y;
        this.diameter = options.diameter;
        this.color = options.color;
    }

    draw() {
        let div = document.createElement('div');
        div.style.position = 'absolute';
        div.style.left = `${this.x}px`;
        div.style.top = `${this.y}px`;
        div.style.width = `${this.diameter}px`;
        div.style.height = `${this.diameter}px`;
        div.style.border = "1px solid;";
        div.style.borderRadius = "50%";
        div.style.backgroundColor = `${this.color}`;
        document.body.appendChild(div);
    }

    move({x = 0, y = 0}) {
        let circle = document.getElementsByTagName('div')[0];
        setInterval(function moved() {
            circle.style.left = circle.offsetLeft + x + "px";
            circle.style.top = circle.offsetTop + y + "px";
        }, 1000)
    }
    _update() {
        this.x = x.move;
        this.y = y.move;
    }
}
let options = {
    x: 100,
    y: 100,
    diameter: 100,
    color: 'red'
};
let circle = new Circle(options);
circle.draw();
circle.move({x: 200, y: 200});

1 Ответ

0 голосов
/ 01 июля 2018

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

Краткое изложение:

  • Пользователь устанавливает желаемые координаты экземпляра круга
  • Продолжительность анимации можно изменить, передав параметр duration методу move(...), например. move({x: 100, y: 100, duration: 2500})
  • Круг начнет тикер с setInterval, чтобы изменить положение круга
  • Фактические, в промежутке между x и y координатами будут рассчитываться на основе хода выполнения заданной duration
  • Когда анимация подходит к концу, координаты x и y будут установлены на первоначально заданные координаты через move(...), и все движение круга будет выполнено

Примечания:

  • Я знаю, что вы не просили анимацию , но Я осмелился предположить , что такая демонстрация будет более эффективной, чтобы помочь вам понять и / или получить ваши результаты.
  • Я извлек часть вашего кода, где вы устанавливаете положение круга, чтобы придерживаться принципа DRY .
  • Чтобы код был более наглядным, я уменьшил координаты до более низких значений, но он также будет работать и с большими значениями
  • Анимация чего-либо с setInterval в современных браузерах по многим причинам считается плохой практикой . Если вам нужен метод для улучшения анимации, прочитайте о функции window.requestAnimationFrame(). Я использовал setInterval здесь, потому что анимация не является основной темой этого вопроса .

class Circle {
  constructor(options) {
    Object.assign(this, 
      // the default options of the Circle constructor
      {      
        x: 10,
        y: 10,
        diameter: 50,
        color: 'red'
      }, 
      // the options, that were passed and will be used to override the default options
      options
    );
  
    // the circle's move/update animation interval in ms (similar to FPS in games)
    this.updateInterval = 100;
  }

  draw() {
    const div = document.createElement('div');
    div.style.position = 'absolute';
    div.style.width = `${this.diameter}px`;
    div.style.height = `${this.diameter}px`;
    div.style.border = "1px solid;";
    div.style.borderRadius = "50%";
    div.style.backgroundColor = `${this.color}`;
    document.body.appendChild(div);
    // store the reference to the div element for later use
    this.circle = div;
    // use the refacterd positioning function
    this._reposition();
  }

  move({x = 0, y = 0, duration = 1000}) {
    // store coordinates to use, when the circle will be moved
    this.initialX = this.x;
    this.initialY = this.y;
    this.destX = x,
    this.destY = y;
    
    // store the current time in ms
    this.startTime = Date.now();
    this.duration = duration
    
    // if a previous setInterval of this circle instance is still running, clear it (stop it)
    clearInterval(this.intervalId);
    // start the update (tick/ticker in games)
    this.intervalId = setInterval(this._update.bind(this), this.updateInterval);
  }
  
  _update() {
    // calculate the elapsed time
    const elapsed = Date.now() - this.startTime;    
    // calculate the progress according to the total given duration in percent
    let progress = elapsed / this.duration;
    // bound to [n..1]
    if (progress > 1) {
      progress = 1;
    }
    
    // set the x and y coordinates according to the progress...
    this.x = this.initialX + (this.destX * progress);
    this.y = this.initialY + (this.destY * progress);
    // ...and reposition the circle    
    this._reposition();
    console.log('update', this.x, this.y, progress);
    
    // stop the update, when the end is reached
    if (elapsed >= this.duration) {
      console.log('stopped', this.x, this.y, progress);
      clearInterval(this.intervalId);
    }
  }
  
  _reposition() {
    // set the position of the circle instance
    this.circle.style.left = `${this.x}px`;
    this.circle.style.top = `${this.y}px`;
  }
}

const options = {
  x: 10,
  y: 10,
  diameter: 50,
  color: 'red'
};

const circle = new Circle(options);
circle.draw();
circle.move({x: 300, y: 50});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...