Большой разговор JavaScript-анимация

внешний интерфейс GitHub JavaScript анимация

задний план

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

Большой взрыв

Огромную внутреннюю силу было уже не сдержать, и она взорвалась в одно мгновение, она взорвалась! В мире есть время и пространство, и с течением времени образуются бесчисленные галактики, звезды, спутники, кометы. Земля, на которой мы живем, всего лишь маленькое небесное тело в огромной вселенной, возможно, по ту сторону далекой вселенной будут параллельные миры, возможно, там мы будем врачами, учителями и государственными служащими. Ученые говорят, что наша Вселенная расширяется с ускорением, темная энергия бесконечно поглощает темную материю, и будущий мир станет иллюзорным.

человеческое происхождение

Формирование вселенной приносит бесконечные возможности.Человеческие существа освобождают желание и ограничение.Желание вселенной зародилось в пятом веке до нашей эры.Древние вавилоняне предсказывали различные явления в мире,наблюдая за положением и внешним видом небесных тел. В далеком Древнем Риме люди тоже играли душой и отдавали свое безудержное воображение своему телу. Аним, происходящее от латыни, представляет душу и жизнь, а также представляет все, что рождается. Кажется, что все в мире связано, и вселенная и природа имеют души.

Формирование анимации

В каменном веке Цянь 25 000 лет назад аналитическая карта зверей, бегающих по пещере, является самым ранним свидетельством того, что люди начали пытаться улавливать движения. На картинах Леонардо да Винчи эпохи Возрождения две руки и две ноги используются для обозначения движений вверх и вниз, а на одной картине совершаются два движения в разное время. До 1906 года первый в мире мультфильм "смешной юмор"публично заявить.

Значит, анимация просто подключает несколько экранов для воспроизведения?

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

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

Так почему же мы видим непрерывное действие?

Постоянство зрения позволяет видеть непрерывную картину Скорость реакции зрительного нерва около 1/16 секунды Все люди разные, кто выше, кто ниже. Изображение последней передачи по зрительному нерву останется в мозгу до тех пор, пока не поступит следующий нервный сигнал. Википедия говорит, что дневные люминесцентные лампы гаснут примерно 100 раз в секунду, но вы этого не чувствуете.

Как правило, частота кадров в фильмах выше 24 кадров в секунду, как правило, мозг считает нормальным значение выше 30 кадров в секунду, игры, в которые мы играем, обычно имеют частоту кадров 30 кадров в секунду, а высокая частота кадров составляет 60 кадров в секунду.

Вы, должно быть, видели анимацию перелистывания страниц, когда были ребенком, вы можете посмотретьPage Turn Анимация-Эволюционная история Земли

Реализация фронтенд-анимации

Закон Этвуда: любое приложение, которое можно написать на JavaScript, в конечном итоге будет написано на JavaScript.

Во фронтенд-анимации нет ничего нового: начиная с эпохи jQuery и до наших дней фронтенд-анимация широко распространена.

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

Во внешнем мире браузер продолжаеткадр за кадромвыходное изображение. Выводится одно изображение на кадр.

Когда дело доходит до анимации, необходимо обсудить частоту кадров (FPS, Frame Per Second), которая представляет собой количество кадров в секунду на выходе, то есть сколько статических изображений отображает браузер в секунду.

DOM CSS3 анимация

CSS3-анимация сегодня является одним из самых популярных способов создания анимации в Интернете.Для мобильных устройств покрытие очень обширно и может использоваться в повседневной разработке. Анимации CSS3 можно анимировать, только управляя DOM путем изменения стилей CSS.

WebAnimation в анимации DOM

WebAnimation все еще находится на стадии черновика, вы можете попробовать его в Chrome. Мобильные устройства все еще довольно убогие, а iOS еще не начала их поддерживать.

Element Animation MDN

Can I Use

И CSS3, и WebAnimation могут воздействовать только на DOM, так что же нам делать, если мы хотим анимировать объекты на Canvas?

JavaScript

Теперь, когда мы знаем принцип анимации, она фактически позволяет пользователям видеть непрерывные изображения, и каждое изображение меняется.

Для вещей мы можем изменить их свойства, изменив определенные значения, и никогда не менять их внешний вид. Например, длина стороны квадрата, значение RGB цвета и положение тайфуна (мировые координаты), меняйте эти значения в каждом кадре и рисуйте объекты на экране по очереди согласно этим значениям , который будет генерировать анимацию.

Из приведенного выше описания мы знаем, что для реализации анимации значение изменяется со временем, а единицей времени является кадр.

Давным-давно JavaScript использовалсяsetIntervalСделайте синхронизированный вызов функции. Таким образом, вы можете использовать setInterval для изменения значения.

Для того, чтобы лучше позволить фронтенд братьям и сестрам делать анимацию, естьrequestAnimationFrame,requestAnimationFrameПолучите функцию, эта функция будет выполнена до рендеринга следующего кадра, то есть она не требует слишком много вычислений, пока мы изменяем значения, которые необходимо изменить, до рендеринга следующего кадра.requestAnimationFrameЧастота кадров зависит от оборудования и браузера, обычно 60 кадров в секунду (16,66666666 мс/кадр).

Используем анимированные презентации Дом -

движение элемента

создать блок

<div class=“box”></div>

Установить ширину и высоту и цвет фона

.box {
    width: 100px;
    height: 100px;
    background: red;
}
const box = document.querySelector('.box') // 获取方块元素
let value = 0 // 设置初始值
// 创建每一帧渲染之前要执行的方法
const add = () => {
    requestAnimationFrame(add) // 下一帧渲染之前继续执行 add 方法
    value += 5 // 每帧加数值增加5
    box.style.transform = `translateX(${value}px)` // 将数值设置给 方块 的 css 属性 transform 属性可以控制元素在水平方向上的位移
}
requestAnimationFrame(add) // 下一帧渲染之前执行 add 方法

Таким образом, квадрат перемещается на 5 пикселей вправо каждый кадр, каждую секунду.60*5=300Пиксели не прыгают каждую секунду, а перемещаются равномерно в пределах 300 пикселей в секунду.

промежуточная анимация

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

Поэтому нам просто нужно рассчитать значение на основе процента времени, затраченного на движение.

Сохранить прежний HTML и CSS без изменений

/**
 *  执行补间动画方法
 *
 * @param      {Number}    start     开始数值
 * @param      {Number}    end       结束数值
 * @param      {Number}    time      补间时间
 * @param      {Function}  callback  每帧的回调函数
 */
function animate(start, end, time, callback) {
    let startTime = performance.now() // 设置开始的时间戳
    let differ = end - start // 拿到数值差值
    // 创建每帧之前要执行的函数
    function loop() {
        raf = requestAnimationFrame(loop) // 下一阵调用每帧之前要执行的函数
        const passTime = performance.now() - startTime // 获取当前时间和开始时间差
        let per = passTime / time // 计算当前已过百分比
        if (per >= 1) { // 判读如果已经执行
              per = 1 // 设置为最后的状态
              cancelAnimationFrame(raf) // 停掉动画
        }
        const pass = differ * per // 通过已过时间百分比*开始结束数值差得出当前的数值
        callback(pass) // 调用回调函数,把数值传递进去
    }
    let raf = requestAnimationFrame(loop) // 下一阵调用每帧之前要执行的函数
}

Давайте вызовем анимацию движения и позволим значению измениться от 0 до 400 с постоянной скоростью через 1 секунду.

let box = document.querySelector()
animate(0, 400, 1000, value => {
    box.style.transform = `translateX(${value}px)` // 将数值设置给 方块 的 css 属性 transform 属性可以控制元素在水平方向上的位移
})

Мы делаем простую равномерную анимацию движения.

неравномерная анимация

В случае, если эта анимация не является неравномерной, например, дрожание, дрожание, что мне делать?

Конечно, тоже процент затраченного времени для расчета значений

Время однородно, а значение нет. Если значение регулярно меняется, то мы можем использовать время для представления значения, создать метод, который получает соотношение времени (процент текущего времени) и возвращает соотношение текущей позиции (процент текущей позиции) .

Мы называем этот метод методом смягчения.

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

Формулаrate = time ^ 2

Соответствующая функция должна быть

function  easeIn(time) { // 接收一个当前的时间占总时间的百分比比
    return time ** 2
}

Этот эффект реализации прекращения джиттера после ускорения представляет собой формулу, когда время меньше 0,6, и другую формулу, когда время больше 0,6.

Когда время

Когда время > 0,6: скорость = Math.sin((Time-0,6) * ((3 * Math.PI) / 0,4)) * 0,2 + 1

Последняя реализованная функция

function shake(time) {
    if (time < 0.6) {
        return (time / 0.6) ** 2
    } else {
        return Math.sin((time-0.6) * ((3 * Math.PI) / 0.4)) * 0.2 + 1
    }
}

Давайте переделаем предыдущийanimateФункция, которая принимает метод смягчения.

/**
 *  执行补间动画方法
 *
 * @param      {Number}    start     开始数值
 * @param      {Number}    end       结束数值
 * @param      {Number}    time      补间时间
 * @param      {Function}  callback  每帧回调
 * @param      {Function}  easing    缓动方法,默认匀速
 */
function animate(start, end, time, callback, easing = t => t) {
    let startTime = performance.now() // 设置开始的时间戳
    let differ = end - start // 拿到数值差值
    // 创建每帧之前要执行的函数
    function loop() {
        raf = requestAnimationFrame(loop) // 下一阵调用每帧之前要执行的函数
        const passTime = performance.now() - startTime // 获取当前时间和开始时间差
        let per = passTime / time // 计算当前已过百分比
        if (per >= 1) { // 判读如果已经执行
            per = 1 // 设置为最后的状态
            cancelAnimationFrame(raf) // 停掉动画
        }
        const pass = differ * easing(per) // 通过已过时间百分比*开始结束数值差得出当前的数值
        callback(pass)
    }
    let raf = requestAnimationFrame(loop) // 下一阵调用每帧之前要执行的函数
}

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

Ускорить движение

let box = document.querySelector('.box')
animate(0, 500, 400, value => {
    box.style.transform = `translateX(${value}px)` // 将数值设置给 方块 的 css 属性 transform 属性可以控制元素在水平方向上的位移
}, easeIn)

Трясет после разгона

let box = document.querySelector('.box')
animate(0, 500, 400, value => {
    box.style.transform = `translateX(${value}px)` // 将数值设置给 方块 的 css 属性 transform 属性可以控制元素在水平方向上的位移
}, shake)

Суммировать

Это только основы основ анимации JavaScript.После понимания принципов анимации анимация будет более удобной.

На рынке существует множество библиотек JS-анимации, которые вы можете использовать «из коробки». Некоторые из них предназначены для манипулирования DOM, а некоторые — для объектов JavaScript. Вы уже поняли принцип реализации.

Приведенный выше код был опубликован на Github:GitHub.com/Фан Минфэй/...

Две другие мои статьи по анимации: