Rytm animacji w canvas

0

Cześć

Chciałbym w canvas zasymulować ruch takiego kwadratu jak w tym przykładzie:
https://www.w3schools.com/css[...]p?filename=trycss3_animation3

Mam taki kwadratowy obrazek

const square = {
  img: "",
  x: 100,
  y: 100,
  width: 100
}

Chciałbym stworzyć funkcje która wykona na obiekcie podobną animację.
Chciałbym wykorzystać do tego https://developer.mozilla.org[...]/window/requestAnimationFrame.
Szczególnie zastanawiam się jak zrobić żeby ten ruch nie był liniowy.

Czy wiecie jak się za to zabrać? :-)

0

Canvas nie jest najlepszym miejscem do robienia animacji, bo żeby to zrobić musisz policzyć i narysować każdą klatkę po kolei.

0

Taka animacja składa się z 3 części:

  1. Przyśpieszanie od 0 do X
  2. Osiągnięcie prędkości X
  3. Zwalnianie do 0

Więc zakładając, że masz do przebycia drogę A = 100, i chcesz osiągnąc maksymalną prędkość P = 10 to:

  1. Prędkość = 0 -> 10 (długość 50), wzrost prędkości jest liniowy
  2. 10 (osięgnięta max prędkość)
  3. 10 -> 0 (długośc 50), spadek prędkości liniowy
0

A wiecie jak można by zaimplementować funkcję cubic-bezier() z CSS'owych animacji?

1

Szczególnie zastanawiam się jak zrobić żeby ten ruch nie był liniowy.

ja używałem bibliotek do tego, np.
https://www.npmjs.com/package/d3-ease
(to zapewnia ci same easingi między liczbowymi wartościami, czyli można to łatwo połączyć z istniejącym kodem, gdzie animacje itp. robisz sam, a potrzeba ci tylko easingu).

Pewnie też można samemu coś takiego napisać, ale mi się nie chciało czytać/kombinować jak. Ale to też pewnie jakieś równanie matematyczne albo coś takiego, tak przypuszczam.

No, nawet jak się spojrzy na kod źródłowy, to widać, że coś tam liczą po prostu https://github.com/d3/d3-ease/tree/master/src

1

Tu masz podstawowy przykład dla prostego przyspieszenia:

const canvas = document.getElementById("game");

const square = {
  x: 10,
  y: 10,
  sizeX: 20,
  sizeY: 20,
  velocityX: 0,
  velocityY: 0,

  draw(ctx) {
    this.x += this.velocityX
    this.y += this.velocityY
    ctx.fillStyle = "#FF5599";
    ctx.fillRect(this.x, this.y, this.sizeX, this.sizeY);
  },

  calculateVelocity() {
    const maxDistance = 210
    const acceleration = 0.05

    this.velocityX += this.x > maxDistance / 2 ? -acceleration : acceleration
    return this
  }
};

const ctx = canvas.getContext("2d");

const render = () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  square.calculateVelocity().draw(ctx)
  requestAnimationFrame(render)
}

render()

CodePen: https://codepen.io/caderek/pen/abvEKRN?editors=0010

1

Jeśli to do gry, to proponował bym użyć biblioteki do tego.
CreateJS, Pixi.js, Phazer.io
Te biblioteki powinny mieć już wbudowane takie mechanizmy i wiele więcej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0