Работа с opacity и visibility

В формате Lottie прозрачность слоя описывается через параметр opacity, который в JSON-структуре анимации представлен как свойство o внутри блока трансформации ks. Значение задаётся в диапазоне от 0 до 100, где 0 означает полную прозрачность, а 100 — полную непрозрачность.

"ks": {
  "o": {
    "k": 100
  }
}

Если значение является анимированным, структура принимает форму массива ключевых кадров:

"o": {
  "k": [
    {
      "t": 0,
      "s": [100],
      "e": [0]
    },
    {
      "t": 20,
      "s": [0]
    }
  ]
}

В таком случае opacity становится временной функцией, управляемой кривыми интерполяции, заданными в After Effects и экспортированными в JSON.


Управление opacity через Lottie Web API

В библиотеке Lottie Web нет прямого публичного метода изменения opacity слоя в рантайме, так как вся анимация интерпретируется как заранее вычисленная система ключевых кадров. Контроль прозрачности реализуется косвенными методами.

Управление через временную шкалу

Одним из базовых способов влияния на визуальную прозрачность является управление прогрессом анимации:

const anim = lottie.loadAnimation({
  container: document.getElementById('box'),
  renderer: 'svg',
  loop: false,
  autoplay: false,
  path: 'animation.json'
});

anim.goToAndStop(10, true);

Изменяя кадр, можно фактически переключать состояние opacity, если оно заложено в ключевых кадрах композиции.


Программное влияние на прозрачность через SVG-рендер

При использовании renderer: "svg" каждая композиция превращается в набор DOM-элементов. Это позволяет вмешиваться в итоговый рендеринг через CSS.

Изменение opacity контейнера

Самый грубый и стабильный способ:

const container = document.getElementById('box');
container.style.opacity = 0.5;

Этот метод влияет на всю анимацию целиком, не затрагивая внутреннюю структуру Lottie.


Управление отдельными слоями

В SVG-режиме каждый слой получает отдельный g-элемент. Через инспектор DOM можно обнаружить структуру:

<g data-name="Layer 1"></g>

Далее возможно прямое изменение прозрачности:

const layer = document.querySelector('[data-name="Layer 1"]');
layer.style.opacity = 0.2;

Такой подход применим только при стабильной структуре экспорта и отсутствии динамического пересоздания DOM.


Системная логика visibility в Lottie

Параметр «видимость» в Lottie не существует как отдельное публичное свойство. Вместо него используется комбинация механизмов:

  • диапазон воспроизведения (ip и op)
  • скрытие слоёв на уровне After Effects (флаг visible)
  • отключение отрисовки через hidden слои (hd)
  • управление прозрачностью через o

Диапазон воспроизведения

Каждый слой имеет параметры начала и конца жизни:

"ip": 0,
"op": 60

Слой отображается только в пределах этого диапазона. За его пределами он фактически невидим.


Имитация visibility через управление слоями

В рантайме Lottie Web отсутствует стабильный API скрытия конкретного слоя, однако поведение можно имитировать несколькими способами.

1. Полное скрытие через opacity

function hideAnimation(anim) {
  anim.setSpeed(1);
  anim.goToAndStop(anim.currentFrame, true);
  anim.renderer.elements.forEach(el => {
    if (el?.updateDocumentData) {
      el.baseElement.style.opacity = 0;
    }
  });
}

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


2. Переключение видимости через пересоздание

let anim;

function show() {
  anim = lottie.loadAnimation({
    container: document.getElementById('box'),
    renderer: 'svg',
    loop: true,
    autoplay: true,
    path: 'animation.json'
  });
}

function hide() {
  anim.destroy();
  anim = null;
}

Такой подход полностью убирает DOM-структуру анимации, что эквивалентно visibility: hidden на уровне всей композиции.


Влияние Canvas-рендерера на прозрачность

При использовании renderer: "canvas" вся композиция отрисовывается на <canvas>, и управление opacity через DOM невозможно.

const anim = lottie.loadAnimation({
  container: document.getElementById('box'),
  renderer: 'canvas',
  loop: true,
  autoplay: true,
  path: 'animation.json'
});

document.getElementById('box').style.opacity = 0.3;

В этом режиме изменение opacity применяется только к canvas-элементу как к текстуре, без доступа к слоям.


HTML-рендерер и особенности visibility

Режим renderer: "html" создаёт структуру из DOM-блоков. В отличие от SVG, элементы чаще представлены <div>-контейнерами, что делает управление visibility более предсказуемым через CSS:

const anim = lottie.loadAnimation({
  container: document.getElementById('box'),
  renderer: 'html',
  loop: true,
  autoplay: true,
  path: 'animation.json'
});

document.querySelector('#box > div').style.visibility = 'hidden';

Различие между visibility: hidden и opacity: 0:

  • opacity: 0 сохраняет интерактивную область
  • visibility: hidden полностью исключает элемент из визуального потока

Анимация opacity в runtime

Хотя Lottie Web не предоставляет прямого метода для изменения keyframe opacity, можно эмулировать плавные переходы через внешнюю анимацию контейнера.

Плавное затухание через JavaScript

function fadeOut(element, duration) {
  let start = performance.now();

  function animate(time) {
    let progress = (time - start) / duration;
    if (progress > 1) progress = 1;

    element.style.opacity = 1 - progress;

    if (progress < 1) {
      requestAnimationFrame(animate);
    }
  }

  requestAnimationFrame(animate);
}

Применение:

const container = document.getElementById('box');
fadeOut(container, 500);

Связь opacity и производительности рендера

Изменение opacity на уровне контейнера или слоя влияет на compositing pipeline браузера:

  • SVG: пересчёт части DOM-дерева
  • Canvas: пересоздание пиксельного буфера
  • HTML: перерасчёт layout и paint для каждого слоя

Наиболее дешёвым с точки зрения производительности считается изменение opacity у контейнера, содержащего canvas, так как оно обрабатывается GPU-композитингом без пересчёта сцены.


Управление видимостью через сегменты анимации

В Lottie Web можно управлять видимостью косвенно через сегменты воспроизведения:

anim.playSegments([0, 30], true);

Или исключение части анимации:

anim.playSegments([30, 60], true);

Если ключевые кадры opacity заложены в определённые диапазоны, такой метод становится эквивалентом переключения видимости состояний.


Комбинированные стратегии контроля opacity и visibility

В реальных сценариях применяется комбинация нескольких уровней управления:

  • контейнерный opacity для глобального fade-in/fade-out
  • DOM-манипуляции для SVG слоёв
  • сегменты для логического скрытия частей композиции
  • destroy/reload для полной деактивации
function setAnimationState(anim, state) {
  const container = anim.wrapper;

  if (state === 'hidden') {
    container.style.opacity = 0;
  }

  if (state === 'visible') {
    container.style.opacity = 1;
  }

  if (state === 'disabled') {
    anim.destroy();
  }
}

Особенности поведения opacity при loop-анимациях

При зацикливании анимации (loop: true) opacity, заданный внутри JSON, будет повторяться синхронно с циклами. Это приводит к повторяющимся фазам:

  • fade-in на каждом цикле
  • fade-out в конце цикла
  • мгновенные переходы при reset timeline

Такое поведение важно учитывать при комбинировании с внешним CSS-opacity, так как итоговое значение становится произведением двух уровней прозрачности: внутреннего и внешнего.