如何在 html 画布中获取动画方向?

Posted

技术标签:

【中文标题】如何在 html 画布中获取动画方向?【英文标题】:How to get animation direction in html canvas? 【发布时间】:2021-12-07 14:41:28 【问题描述】:

我想在 html 画布上制作一个矩形动画。当用户单击画布时,矩形将开始动画,并转到单击的位置。我使用 delta x 和 y 从矩形的 x 和 y 位置添加和减去像素。 但这个解决方案的问题是,我找不到让矩形以直线路径动画的方法。

我的代码:

'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 = `$heightpx`
canvas.style.width = `$widthpx`
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>

如果您在画布中单击,矩形将开始移动,但它会走一条奇怪的路径,我无法找到一种方法可以在单击的位置正确地直行。

在Github page查看演示

【问题讨论】:

math.stackexchange.com/questions/180418/… 这可能会帮助您进行搜索,例如,您需要公式来检测 0,2 和 50,20 之间的旋转;上面的帖子解释了一点,我相信还有更多。有趣的笑话,但这更像是数学而不是编程。 :) 【参考方案1】:

这是我不久前做过的数学示例... 有不懂的地方可以问

在您的代码中,它变得“奇怪”,因为您的 delta 值始终为 1 或 -1,没有分数,这限制了对象可以行进的方式,而是我们使用角度进行计算。

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()
&lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【讨论】:

我不明白“角度”的意思。请解释“Math.atan2”和你传递的参数。 @Mr.lindroid 是基本的三角学,我们需要获得给定两个点的角度,更多细节请看这里:math.stackexchange.com/a/1201367

以上是关于如何在 html 画布中获取动画方向?的主要内容,如果未能解决你的问题,请参考以下文章

如何在html5画布中逐步绘制线条动画

在画布上创建线条动画

如何优化画布上的动画? HTML 5

如何在一页上放置多个画布js动画。 (创建js)

如何使用 html5 画布扭曲图像以创建在风中飘扬的旗帜效果

HTML5 画布中的动画 GIF