Home > Software engineering >  How to get animation direction in html canvas?
How to get animation direction in html canvas?

Time:10-29

I want to animate a rectangle on html canvas. when the user will click the canvas, the rectangle will start it's animation, and go to the clicked position. I used delta x and y to add and subtract pixels from the x and y position of the rectangle. But the problem with this solution is, I can't find a way to make the rectangle animate in a straight path.

My code:

'use strict'

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const ratio = Math.ceil(window.devicePixelRatio)
let height = window.innerHeight
let width = window.innerWidth

canvas.height = height * ratio
canvas.width = width * ratio
canvas.style.height = `${height}px`
canvas.style.width = `${width}px`
ctx.setTransform(ratio, 0, 0, ratio, 0, 0)


let position = {
  x: 0,
  y: 0,
  deltaX: 0,
  deltaY: 0,
  size: 20
}

let move = {
  x: 0,
  y: 0,
}

function animate() {
  if (position.x === move.x && position.y === move.y) {
    cancelAnimationFrame()
  }
  if (position.x !== move.x) {
    ctx.fillRect(position.x, position.y, position.size, position.size)
    position.x  = position.deltaX
  }
  if (position.y !== move.y) {
    ctx.fillRect(position.x, position.y, position.size, position.size)
    position.y  = position.deltaY
  }
  requestAnimationFrame(animate)
}

function moveTo(x, y) {
  move.x = x
  move.y = y
  position.deltaX = position.x > x ? -1 : 1
  position.deltaY = position.y > y ? -1 : 1
  animate()
}

canvas.addEventListener('click', (event) => {
  moveTo(event.clientX, event.clientY)
})

ctx.fillRect(position.x, position.y, position.size, position.size)
<canvas id="canvas">
        </canvas>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

If you click in the canvas the rectangle will start moving but it'll go in a weird path, I can't find a way to properly go straight at the clicked position.

see demo at Github page

CodePudding user response:

Here is the sample Math from something I did a while ago...
If there is something you don't understand there ask

In your code it was moving "weird" because your delta values where always 1 or -1, no fractions, that limits the way the object can travel, instead we do our calculations using the angle.

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

let player = { 
  x: 0, y: 0, size: 10,
  delta: { x: 0, y: 0 }, 
  move: { x: 0, y: 0 } 
}

function animate() {
  let a = player.x - player.move.x;
  let b = player.y - player.move.y;
  if (Math.sqrt( a*a   b*b ) < 2) {
    player.delta = { x: 0, y: 0 }
  }
  player.x  = player.delta.x
  player.y  = player.delta.y
  ctx.fillRect(player.x, player.y, player.size, player.size)
  requestAnimationFrame(animate)
}

function moveTo(x, y) {
  player.move.x = x
  player.move.y = y
  let angle = Math.atan2(y - player.y, x - player.x)
  player.delta.x = Math.cos(angle)
  player.delta.y = Math.sin(angle)
}

canvas.addEventListener('click', (event) => {
  moveTo(event.clientX, event.clientY)
})

animate()
<canvas id="canvas"></canvas>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related