Меню обученияСодержание на этой странице

анимация

В первой части этой серии мы только начали знакомиться с Fabric.js. Мы рассмотрели причины использования Fabric, его объектную модель и иерархию объектов, различные типы сущностей, доступных в Fabric — простые формы, изображения и сложные пути. Мы также научились выполнять простые операции с объектами Fabric на холсте.

Теперь, когда с большинством основ покончено, давайте перейдем к некоторым интересным вещам!

Анимация

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

Помните, как легко было изменить свойство любого объекта? Мы только что вызвали метод set, передав соответствующие значения:

rect.set('angle', 45);

Что ж, анимировать объект так же просто. У каждого объекта Fabric есть метод animate, который... анимирует этот объект.

rect.animate('angle', 45, {
  onChange: canvas.renderAll.bind(canvas)
});

Первый аргумент — это свойство анимации. Второй аргумент — это конечное значение анимации. Если прямоугольник имеет угол -15°, а мы передаем 45, он будет анимирован от -15° до 45°. Третий аргумент — это необязательный объект, определяющий более мелкие детали анимации — продолжительность, обратные вызовы, плавность и т. д.

Одной из удобных особенностей animate является поддержка относительных значений. Например, если вы хотите анимировать свойство left объекта на 100 пикселей, вы можете сделать это следующим образом:

rect.animate('left', '+=100', { onChange: canvas.renderAll.bind(canvas) });

Аналогично, поворот объекта на 5 градусов против часовой стрелки можно выполнить следующим образом:

rect.animate('angle', '-=5', { onChange: canvas.renderAll.bind(canvas) });

Вам может быть интересно, почему мы всегда указываем здесь обратный вызов «onChange». Разве третий аргумент не является необязательным? Это так, но вызов Canvas.renderAll для каждого кадра анимации позволяет нам увидеть реальную анимацию! Видите ли, когда мы вызываем метод animate, он анимирует только значение свойства с течением времени, следуя определенному алгоритму (т. е. смягчению). Таким образом, rect.animate('angle', 45) изменит угол объекта, но не будет повторно отображать экран холста после каждого изменения угла. И нам, очевидно, нужен повторный рендеринг, чтобы увидеть настоящую анимацию.

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

Причина, по которой animate не выполняет автоматическую повторную визуализацию холста после каждого изменения, связана с производительностью. В конце концов, у нас могут быть сотни или тысячи анимационных объектов на холсте, и было бы нехорошо, если бы каждый из них пытался перерисовать экран. В случае большого количества объектов вы можете использовать что-то вроде цикла requestAnimationFrame (или другого цикла на основе таймера) для непрерывного рендеринга холста самостоятельно, без вызова renderAll для каждого объекта. Но в большинстве случаев вам, вероятно, придется явно указать Canvas.renderAll как обратный вызов onChange.

Итак, какие еще параметры мы можем передать в animate?

  • from: позволяет указать начальное значение анимируемого свойства (если мы не хотим, чтобы использовалось текущее значение).
  • продолжительность: по умолчанию 500 (мс). Может использоваться для изменения продолжительности анимации.
  • onComplete: обратный вызов, вызываемый в конце анимации.
  • easing: функция замедления.

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

По умолчанию animate использует для анимации функцию «easeInSine». Если это не то, что вам нужно, в разделе Fabric.util.ease доступно множество вариантов смягчения. Например, если мы хотим переместить объект вправо подпрыгивающим образом:

rect.animate('left', 500, {
  onChange: canvas.renderAll.bind(canvas),
  duration: 1000,
  easing: fabric.util.ease.easeOutBounce
});

Обратите внимание на Fabric.util.ease.easeOutBounce как на опцию замедления. Другие известные из них включают в себя easyInCubic, easyOutCubic, easyInElastic, easyOutElastic, easyInBounce и easyOutExpo.

Итак, это почти охватывает анимационную часть Fabric. Просто чтобы дать вам некоторое представление о том, что становится возможным — вы можете анимировать угол объекта, чтобы заставить его вращаться; анимировать свойства left/top, чтобы заставить его двигаться; анимировать ширину/высоту, чтобы она уменьшалась/увеличивалась; анимировать непрозрачность, чтобы она появлялась или исчезала; и так далее.

Fabric.runningАнимации

Если вам нужен доступ к анимациям, которые в данный момент выполняются в фабрике, используйте Fabric.runningAnimations. Это массив объектов, каждый из которых является объектом контекста анимации.

Удобные методы:

  • Fabric.runningAnimations.findAnimation(signature) — возвращает подпись соответствия контекста анимации, которая является функцией прерывания, возвращаемой Fabric.util.animate.
  • Fabric.runningAnimations.findAnimationIndex(signature) — то же, что и findAnimation, возвращает индекс.
  • Fabric.runningAnimations.findAnimationsByTarget(target) — возвращает все анимации, у которых свойство target равно target.
  • Fabric.runningAnimations.cancelAll() — отменяет все запущенные анимации.
  • Fabric.runningAnimations.cancelByTarget(target) — отменяет анимацию, свойство target которой равно target.
  • object.dispose() — все анимации, созданные объектом (object.animate(...)) отменяются. Если вы хотите добавить анимацию, используя Fabric.util.animate вместо object.animate(...), вы можете прикрепить ее к объекту, передав свойство target. Таким образом, анимация будет отменена после удаления объекта.
  let cancel = fabric.util.animate({...});
  let i = fabric.runningAnimations.findAnimationIndex(cancel);
  let context = fabric.runningAnimations.findAnimation(cancel);
  let cancelled = fabric.runningAnimations.cancelAll();
  
  //  the following statements are true
  cancelled[i] === context;
  cancelled[i].cancel === cancel;
  fabric.runningAnimations.length === 0;
Список комментариев
Загрузка..
Содержание на этой странице