Изучите интерфейсную анимацию с нуля — простой вход со спецэффектами

внешний интерфейс анимация CSS Canvas

Недавно я вдруг увлекся канвас-анимацией, а потом по наитию прочитал несколько статей и заранее заявил,Частично оригинал, я всего лишь портировщик кода. Сначала сделаю скриншот, а потом расскажу о своих мыслях.

[Мои мысли]: На самом деле, я хочу сделать вид, который очень популярен в Интернете. При вводе пароля я закрываю глаза руками, но простите меня за игривый человек. Я хочу сделать это при вводе Спецэффекты удара молотком по миньонам или молнии, оглушающей миньонов, лучше всего сопровождаются звуковыми эффектами. . . Но эффект от реализации не очень хороший, так себе можно использовать, но не идеально, потому что цель обучения и причины времени достигнуты, я не буду продолжать это делать, я могу сделать это, когда у меня будет время в будущем, или вы, гуру CSS, помогите мне завершить его. , не забудьте дать мне ссылку после завершения отличных спецэффектов~ Большое спасибо. Код ниже---

снежинка сцена

Опять же, я всего лишь портировщик кода, в первую очередь сцены падения снежинок. Для просмотра справочных статей нажмите здесь ——Холст понимает, что падает снег,Код выложен в статье,и его можно использовать напрямую,но комментариев нет.Поскольку это предварительная проработка канваса и анимации,комментариев нет вообще,и я действительно в этом не разбираюсь,поэтому Я проанализирую код здесь. Эффект следующий:

Подходящее фоновое изображение

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

Холст Focus 2 для рисования снежинок

  • Определить некоторые параметры сцены Во-первых, вам нужно определить некоторые параметры сцены, такие как скорость, положение и направление падения снежинок. код показывает, как показано ниже:
// 存储所有的雪花
const snows = [];
// 下落的加速度
const G = 0.015;
// 60是人眼所能见到流畅动画的最小阈值
const fps = 60; 
// 速度上限,避免速度过快
const SPEED_LIMIT_X = 1;
const SPEED_LIMIT_Y = 1;
  • Определить конструктор снежинок
 /**
   * 雪花对象
   * @param {x} x 
   * @param {y} y 
   * @param {半径或长宽} radius 
   */
  function Snow(x, y, radius) {
    this.x = x;
    this.y = y;
    // 如果是圆形就是半径,否则就是长宽相同的正方形
    this.radius = radius;
    // x方向的移动速度,可以向左也可以向右,范围在[-1, 1]
    this.speed_x = 0;
    // y方向的移动速度,只能向下,最快为1
    this.speed_y = 0;
    // 雪花自身旋转的角度
    this.deg = 0;
    // x方向,下落速度参数,飘落效果 > 0向左飘; < 0 向右飘 
    this.ax = Math.random() < 0.5 ? 0.005 : -0.005;
  }
  • генерировать снежинки
// 绘制新雪花,x位置为随机数,y为顶部0,半径为随机数随机生成大小不一的雪花
new Snow(Math.random() * W, 0, Math.random() * 15 + 5);
  • Методы добавления краски к снежинкам и обновления их положения
// 绘制雪花
Snow.prototype.draw = function () {
// 获取半径宽高
const radius = this.radius;
// 保存画布的当前状态,因为下面用到了变换坐标和旋转画布
ctx.save();
/**
 * 下面这两句变化也挺重要的,因为旋转是按照画布原点进行的
 * 因此,如果想让雪花旋转明显,就需要将画布坐标移动到雪花的坐标点
 * 如果不加上坐标转换,那么所有雪花都在左上角也就是坐标原点旋转,x, y也不会变,没有飘落效果
 */
// 将画布的坐标原点移动到(x, y)的位置,canvas默认是(0, 0)
ctx.translate(this.x, this.y);
// 将画布顺时针旋转的角度
ctx.rotate(this.deg * Math.PI / 180);
// 绘制雪花图像,因为画布坐标移动到了(x, y),所以从0,0开始就是(-radius, radius)
ctx.drawImage(snowImage, -radius, -radius, radius * 2 , radius * 2);
// 恢复canvas旋转、translate等操作的状态,一般与save配合使用就是恢复到上一个save的状态
// 如果不恢复上一个状态的话,话不旋转角度坐标都没变化,也就不会出现动画效果,必须恢复
ctx.restore();
}
// 更新雪花位置
Snow.prototype.update = function () {
// 雪花自身旋转的角度增值
const deltaDeg = Math.random() * 0.6 + 0.2;
// 不断变化x方向的移动速度
this.speed_x += this.ax;
// x向左或者向右速度过大的时候改变方向
if (this.speed_x >= SPEED_LIMIT_X || this.speed_x <= -SPEED_LIMIT_X) {
  this.ax *= -1;
}
// 雪花下落速度,最高是1
if (this.speed_y < SPEED_LIMIT_Y) {
  // 雪花下落速度不断增加
  this.speed_y += G;
}
// 角度不断变化
this.deg += deltaDeg;
// x坐标不断变化
this.x += this.speed_x;
// y坐标不断变化
this.y += this.speed_y;
}
  • Реализовать анимационный эффект падения и падения Для достижения эффекта падающей анимации здесь используется API requestAnimationFrame, предоставляемый браузером специально для анимации.Передав функцию цикла в качестве параметра, API будет непрерывно перерисовывать для формирования эффекта анимации.
/**
* 主循环函数, 生成雪花以及绘制更新雪花位置
*/
function loop() {
// 擦除当前画布内容,否则原有的雪花不会消失,新绘制的雪花不断覆盖看起来会像一条雪花白色实线在下降
ctx.clearRect(0, 0, W, H);
// 两个雪花之间的时间差,不能生成的太快,要不然就成了鹅毛大雪了^_^
const now = Date.now();
// 距离上一次绘制的时间差
deltaTime = now - lastTime;
// 重置结束时间
lastTime = now;
// 时间控制器,当timer > snowLevelTime的时候,才增加雪花,否则不增加雪花
timer += deltaTime;
/**
 * 不加控制的话雪花会特别多, 150~300之间都合适
 */
if (timer > snowLevelTime) {
  snows.push(
    // 绘制新雪花,x位置为随机数,y为顶部0,半径为随机数随机生成大小不一的雪花
    new Snow(Math.random() * W, 0, Math.random() * 15 + 5)
  );
  timer %= snowLevelTime;
}
const length = snows.length;
snows.map(function (s, i) {
  s.update();
  s.draw();
  if (s.y >= H) {
    snows.splice(i, 1);
  }
});
// 避免失真,浏览器页面每次重绘之前调用
requestAnimationFrame(loop);
}

Эффект миньонов

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

Эффект оглушения

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

  /* CSS */
 .circle-container {
      position: relative;
      width: 45px;
      height: 45px;
      transform: rotate(180deg);
    }
    .one-circle {
      position: absolute;
      width: 45px;
      height: 45px;
      background-color: #fff;
      border-left: 3px solid #333;
      border-top: 3px solid #333; 
      border-radius: 50%; 
    }
    .two-circle {
      position: absolute;
      top: 9px;
      width: 34px;
      height: 34px;
      background-color: #fff;
      border-right: 3px solid #333;
      border-bottom: 3px solid #333; 
      border-radius: 50%; 
    }
    .three-circle {
      position: absolute;
      bottom: 10px;
      left: 8px;
      width: 23px;
      height: 23px;
      background-color: #fff;
      border-top: 3px solid #333;
      border-left: 3px solid #333; 
      border-radius: 50%; 
    }
    .four-circle {
      position: absolute;
      bottom: 0px;
      right: 6px;
      width: 13px;
      height: 13px;
      background-color: #fff;
      border-bottom: 3px solid #333;
      border-right: 3px solid #333; 
      border-radius: 50%; 
    }
  /* Html */
  <div class='circle-container'>
    <div class="one-circle">
      <div class="two-circle">
        <div class="three-circle">
          <div class="four-circle"></div>
        </div>
      </div>
    </div>
  </div>

И код, и реализация достаточно просты, но оригинальны, ну или выпишите, O(∩_∩)О ха-ха~

Переплетаясь, как гора, я обнаружил, что даже передняя часть имеет так много ответвлений. Это действительно так, как представил себя учитель Чжан Синьсюй. Передняя часть - это фронт-инженер. Я думаю, что каждое направление бизнеса заслуживает углубленного изучения. учиться, но я Этот этап все еще мешанина из него. Так как меня интересует анимация и я закончил использовать canvas, я также хочу узнать о нескольких других методах реализации.Кстати, давайте изучим его вкратце.Следующий опыт обучения.

Поговорим о нескольких способах реализации браузерной анимации:

setTimeout и setInterval

Самый примитивный метод — использовать window.setTimout() или window.setInterval() для достижения анимации путем непрерывного обновления состояния и положения элементов и т. д., при условии, что частота обновления экрана должна достигать 60 раз в секунду, чтобы позволить невооруженным глазом можно увидеть эффект плавной анимации.

Я не буду публиковать код для этого. Честно говоря, никто не должен реализовывать анимацию таким образом. Если есть, беспокойтесь о производительности вашей веб-страницы ~

Свойства перехода и трансформации CSS3

Переход можно понимать как переход, непрерывное изменение между двумя точками. Под преобразованием понимается преобразование.Обычно используются перемещение, вращение и т. д. Трансформация + переход совмещены, то есть переход + преобразование будут образовывать простую анимацию. Правило перехода для достижения анимации заключается в определении соответствующих свойств.Например, если я хочу изменить ширину, то определяю свойство как ширину, продолжительность изменения, то есть, как долго должно выполняться преобразование, и, наконец, изменить определенное значение свойства в указанном событии.

// 实现鼠标放到篮球上篮球放大
.ball {
width: 128px;
height: 128px;
transition-property: width,height;
transition-duration: 2s;
-moz-transition-property: width,height; /* Firefox 4 */
-moz-transition-duration: 2s; /* Firefox 4 */
-webkit-transition-property: width,height; /* Safari and Chrome */
-webkit-transition-duration: 2s; /* Safari and Chrome */
-o-transition-property: width,height; /* Opera */
-o-transition-duration: 2s; /* Opera */
}
.ball:hover {
width: 256px;
height: 256px;
}

CSS3 анимации и ключевые кадры

В отличие от перехода и преобразования, анимацию можно понимать непосредственно как анимацию, и я лично считаю, что эта функция более мощная. Как упоминалось выше, анимация создается с помощью CSS для анимации. Он может в основном дополнять большинство простых эффектов анимации. Ему необходимо определить имя специального эффекта анимации, а затем определить эффект специального эффекта через ключевой кадр. Ниже я просто реализовал эффект свободного падения баскетбольного мяча, очень грубо, простая демонстрация:

.ball-animation {
  position: absolute;
  width: 128px;
  height: 128px;
  transform: rotate(0);
  animation: ball-drop 6s linear;
  animation-fill-mode: forwards;
  -webkit-animation: ball-drop 6s linear;
  -webkit-transform: rotate(0);
  -webkit-animation-fill-mode: forwards;
}
@keyframes ball-drop {
  0% {
    transform: rotate(0);
    top: 0
  }
  10% {
    transform: rotate(60);
    top: calc(var(--height) * 1px );
  }
  20% {
    transform: rotate(120);
    top: 40px;
  }
  30% {
    transform: rotate(240);
    top: calc(var(--height) * 1px );
  }
  40% {
    transform: rotate(300);
    top: 80px;
  }
  50% {
    transform: rotate(360);
    top: calc(var(--height) * 1px );
  }
  60% {
    transform: rotate(60);
    top: 160px;
  }
  70% {
    transform: rotate(120);
    top: calc(var(--height) * 1px );
  }
  80% {
    transform: rotate(180);
    top: 380px;
  }
  90% {
    transform: rotate(240);
    top: calc((var(--height) - 20) * 1px );
  }
  100% {
    transform: rotate(260);
    top: calc(var(--height) * 1px );
  }
}

Хотя реализация очень грубая, я все же написал такие вещи, как тени, так что это считается отвлечением, ха-ха. Не буду вдаваться в детали подробного введения, думаю, достаточно прочитать статью г-на Чжан Синьсюя, в которой легко разобраться.портал

requestAnimationFrame

Поскольку самое важное в использовании холста для достижения анимации — это этот API, поэтому давайте поместим его в конец. Об этом есть такая выделенная заметка в MDN:若您想要在下次重绘时产生另一个动画画面,您的回调例程必须调用 requestAnimationFrame(). Иными словами, если вы хотите постоянно перерисовывать для создания анимационных эффектов, вы должны вызывать этот API.

Метод window.requestAnimationFrame() сообщает браузеру, что вы хотите выполнить анимацию, и просит браузер вызвать указанную функцию для обновления анимации перед следующей перерисовкой. Этот метод принимает в качестве параметра функцию обратного вызова, которая будет вызываться перед перерисовкой браузера. Вообще говоря, если человеческий глаз хочет видеть плавную анимацию, он должен обновляться не менее 60 раз в секунду.Конечно, вы также можете контролировать количество обновлений.В то же время, requestAnimationFrame() вернет идентификатор фигуры, через который вы можете вызвать команду cancelAnimationFrame (ID) для остановки анимации с помощью следующего кода:

let timeoutId;
let animateId;
const fps = 20; // 比如我每秒就想刷新20次
window.requestAnimationFrame = (function () {
    return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function (callback) {
        timeoutId = setTimeout(callback, 1000 / fps);
      }
  })();
}
function loop() {
  // 执行动画代码
  animateId = requestAnimaitonFrame(loop);
}

// 停止动画,先停止timeout再停止requestAnimationFrame
clearTimeout(timeoutId);
cancleAnimationFrame(animateId);

Это также js для достижения эффектов анимации. Поскольку этот API специально используется для достижения анимации в браузере, браузер также оптимизировал его. По сравнению с формами setTimeout и setInterval, requestAnimationFrame() имеет лучшую производительность. В большинстве браузеров, когда работающие на фоновой вкладке или скрытые, вызовы requestAnimationFrame() приостанавливаются для повышения производительности и времени автономной работы.

Сравнение анимации и requestAnimationFrame

На самом деле не обязательно знать, что тот же эффект анимации можно реализовать чистыми CSS3 и js типа requestAnimationFrame, да и производительность CSS3 должна быть выше. Ниже приведена та же анимация, которую я сделал, и время рендеринга двух сравнивается: анимация:

requestAnimationFrame

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

Сильное утверждение: я просто сравниваю результаты, я не имею в виду, кто выше, а кто ниже, я думаю, что это должно использоваться в соответствии со сценой~

области для улучшения

Есть много вещей, которые можно улучшить в окончательно реализованном коде. Запишите это здесь. Что, если какой-нибудь великий бог будет в хорошем настроении и изменит его для меня, O(∩_∩)О, ха-ха~.

  • Молоток можно нарисовать с помощью CSS3, а затем ударить по голове миньона, чтобы получить звук удара и головокружения.
  • Когда снежинки падают и сталкиваются с препятствиями, когда маленький желтый человечек и поле ввода, они должны остановиться, это более реально
  • Снежинки должны упасть на землю, чтобы образовался снег, но слишком много снега влияет на производительность и он не добавляется.Добавить очень просто.Достаточно оценить положение снежинки и указать снежинку не перерисовывая.
  • Простите, что не сделал мобильную адаптацию, постарайтесь не открывать демку ниже мобильным телефоном. . . Пэд может быть в порядке, O(∩_∩)O, ха-ха~

Суммировать

Я мельком посмотрел анимацию за последние два дня, и чувствую, что передняя часть глубока, как море.Текущий план - побаловаться со всеми интересующимися, а потом потихоньку выбирать направление~ Код адреса:Анимированная демонстрация Луффи ЧжоуПриветствуем всех, чтобы высказать больше мнений и дать больше STAR

Просто клонировать и не звездить не интересно, я прокляну тебя в душе ^_^