[холст] Принципы закона анимации Гука

JavaScript Canvas

Первый взглядэффект сопротивления самолета:

а такжеВерсия с горизонтальным перетаскиванием:

Отметим, что этот эффект пружины был вдохновлен вторым справочником.

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

В этой статье будут подробно представлены конкретные принципы реализации.После того, как исследование будет понято, кинематика анимации должна считаться проходной.

1. Общие принципы кинематики

Начнем с основных принципов анимации движения.

Мы знаем, что анимацию можно получить, обновляя координаты мяча в реальном времени в соответствии с requestAnimationFrame.

ball.x += 3
ball.y += 4

В каждом кадре мяч перемещается на 3 пикселя вправо и на 4 пикселя вниз. Среди них 3 и 4 - характеристика скорости. Следовательно, их можно определить как горизонтальную скорость и вертикальную скорость соответственно.

vx = 3
vy = 4
ball.x += vx
ball.y += vy

Скорость в приведенном выше коде постоянна, поэтому движение является равномерным линейным движением. Если вы хотите ускорить движение, то вам нужно ввести ускорение:

ax = 0.5
ay = 1
vx += ax
vy += ay
ball.x += vx
ball.y += vy

Согласно второму закону крупного рогатого скота, сила пропорциональна ускорению.

f = m * a

Мы можем ввести силовую модель, предположив, что масса шара равна единице. Например, движение снаряда маленького мяча легко реализовать:

vx = 2.5
vy = -6
gravity = 0.1
vy += gravity
ball.x += vx
ball.y += vy

Эффектследующим образом:

Код класса small ball по-прежнему является обычной реализацией:

class Ball{
  constructor() {
    this.x = 0
    this.y = 0
    this.radius = 20
  }
  draw(context) {
    context.save()
    context.translate(this.x, this.y)
    context.fillStyle = 'red'
    context.beginPath()
    context.arc(0, 0, this.radius, 0, Math.PI * 2)
    context.fill()
    context.restore()
  }
}

Говоря о силах, для имитации движения объектов реального мира иногда мы также учитываем трение. Здесь мы предполагаем, что скорость движущегося объекта будет уменьшаться после каждого кадра. Здесь используется модель:

friction = 0.99
vx *= friction
vy *= friction
ball.x += vx
ball.y += vy

Скидка 0,99% на каждую частоту кадров. 0,99 выглядит близко к 1, но затухает экспоненциально. Браузеры обычно имеют частоту кадров около 60, поэтому 60-я степень 0,99 быстро падает до числа, близкого к 0.

Эффектследующим образом:

2. Закон Гука

С предвосхищением общих принципов кинематики следующим шагом является формальный анализ принципов вступительной анимации.

Среди них, кроме влияния силы тяжести и трения, маленький шарик также подвергается силе пружины.

Все мы учили закон Гука в средней школе: сила, действующая на пружину, пропорциональна величине деформации пружины.

F = k * x

где k — коэффициент пружины, который определяется самой пружиной. x - величина деформации пружины.

Согласно равенству силы и силы реакции, сила, действующая на шар, равна:

f = -k * x

Итак, ключевой код для горизонтального гармонического движения:

var x = ball.x -spring.x - initLength
var f = -k * x
vx += f
ball.x += vx
spring.length = ball.x - spring.x

где x - величина деформации пружины. f — сила пружины на мяче, а последние две строки кода обновляют скорость мяча и текущую длину пружины.

Здесь не добавляется трение, так что это будет продолжаться бесконечно.Эффектследующим образом:

Чтобы мяч мог двигаться, сначала его оттягивают на определенное расстояние. Это расстояние также является амплитудой пружины.

var amplitude = 70
ball.x += amplitude
var vx = 0

Пружина в основном моделируется квадратичной кривой Безье quadraticCurveTo.

class Spring{
  constructor(length) {
    this.x = 0
    this.y = 0
    this.angle = 0
    this.length = length
  }
  draw(context) {
    context.save()
    context.translate(this.x, this.y)
    context.rotate(this.angle)
    context.strokeStyle = 'white'
    context.beginPath()
    context.moveTo(0, 0)
    var n = 16
    var h = 25
    var d = (this.length - 2 * h) / n
    context.lineTo(h, 0)
    for (var i = 0; i < n; i++) {
      var dir = i % 2 == 0 ? 1 : -1
      context.quadraticCurveTo(h + d * ( i + 0.5), 20 * dir,  h + d * (i + 1), 0)
    }
    context.lineTo(this.length, 0)
    context.stroke()
    context.restore()
  }
}

Ниже приводится анализ деталей, на которые необходимо обратить внимание при реализации открывающего эффекта.

3. Силовой синтез и декомпозиция

На основании вышеизложенного, добавив логику трения и перетаскивания, легко реализовать второе в началеЭффект. Здесь нет дальнейших объяснений.

Первый эффект немного сложнее. Во-первых, положение головки пружины обновляется каждый кадр.

spring.x = mouse.x
spring.y = mouse.y

Сила пружины, воспринимаемая мячом в этот момент, равна:

var dx = ball.x - spring.x
var dy = ball.y - spring.y
var x = Math.sqrt(dx * dx + dy * dy) - initLength
var f = -k * x

Для того, чтобы найти горизонтальное и вертикальное ускорение, требуется разложение силы в этот момент:

По треугольной зависимости:

var angle = Math.atan2(dy, dx)
var fx = f * Math.cos(angle)
var fy = f * Math.sin(angle)

Наконец, объединенная логика силы пружины, гравитации и силы трения:

vx += fx
vy += fy
vy += gravity
vx *= friction
vy *= friction
ball.x += vx
ball.y += vy

Еще один момент, который следует отметить, заключается в том, что после обновления положения шарика, поскольку положение шарика изменилось, в это время также необходимо рассчитать новую длину и направление пружины.

Нажмите, чтобы просмотреть окончательный эффект и полный код.

Спасибо, что вы здесь, надеюсь, это поможет.

Эта статья закончилась.



Ниже приводится введение в эту серию.

В конце 2019 года я установил флаг для изучения технологии анимации холста в 2020 году.

(QR-код на картинке — мой единственный идентификатор WeChat. Если вы хотите добавить его, обратите внимание на [самородки].)

В этой серии я хочу написать некоторые общие знания об анимации.Эта статья является четвертой, и ее длина может варьироваться. Для получения дополнительной информации, пожалуйста, проверьте мою личную страницу, или"Каталог серий".

Из-за проблемы с местом, по прошлому опыту, количество лайков будет не слишком большим, ведь всем нравится лайкать статьи, которые невозможно прочитать за короткое время. Ну мне кажется тоже так. ^_^

На самом деле написание статей в основном для себя, это свидетельство самосовершенствования. Может быть, лучше иметь такое отношение.

К тому же про технологию холста я прочитал 3 книги полностью. Это выше основ.

1.«Основная технология холста HTML5»

2.«Основы анимации HTML5+JavaScript»

3.Руководство по программированию WebGL

Некоторые статьи в этой серии могут ссылаться на систему знаний в ней.Для некоторых предметных знаний консенсуса, если есть частичное сходство, мы можем только сказать: "Я узнал это своими собственными навыками, как это может считаться плагиатом..." .

Шучу, источник идеи можно назвать одним предложением или одним предложением. Мне особенно нравится абзац в статье «Элитный дневной класс»:

Что касается содержания статьи, API холста, эту серию можно не вводить по одному, прошу прощения за новичков. У MDN он есть, очень подробный. При этом будет кратко упомянуто то, что встречается в статье. Основное ядро ​​состоит в том, чтобы объяснить некоторое личное понимание знаний на уровне навыков и принципов. Кроме того, я также планирую проанализировать принципы реализации некоторых крутых анимаций на codepen.Если будет время, я могу проанализировать несколько анимационных движков, конечно, все они 2D.

Еще раз спасибо, что дочитали до этого места. Увидимся в следующей статье.