Логирование событий

Логирование в контексте работы с библиотекой mo.js представляет собой систематический сбор и вывод информации о ходе выполнения анимаций, состоянии объектов и последовательности событий. Это важный инструмент при разработке сложных интерфейсов, где визуальные эффекты зависят от множества параметров и взаимодействий.

Основные задачи логирования:

  • отслеживание жизненного цикла анимации;
  • диагностика ошибок и некорректного поведения;
  • анализ производительности;
  • контроль пользовательских взаимодействий.

Событийная модель в mo.js

Библиотека mo.js активно использует событийную модель, в которой объекты (например, Tween, Timeline, Burst, Shape) генерируют события в процессе выполнения.

Ключевые события:

  • onStart — вызывается при запуске анимации;
  • onUpdate — срабатывает при каждом обновлении кадра;
  • onComplete — вызывается после завершения;
  • onRepeat — при повторении анимации.

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


Базовые подходы к логированию

Использование console.log

Простейший способ — вывод информации в консоль:

const tween = new mojs.Tween({
  duration: 1000,
  onStart() {
    console.log('Анимация началась');
  },
  onUpdate(progress) {
    console.log(`Прогресс: ${progress}`);
  },
  onComplete() {
    console.log('Анимация завершена');
  }
});

Такой подход удобен на этапе отладки, но быстро становится неудобным при увеличении объёма данных.


Структурированное логирование

Для более сложных проектов рекомендуется использовать структурированные сообщения:

onUpdate(progress) {
  console.log({
    event: 'update',
    progress: progress,
    timestamp: Date.now()
  });
}

Преимущества:

  • удобство фильтрации;
  • возможность экспорта логов;
  • интеграция с внешними системами.

Логирование параметров анимации

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

const shape = new mojs.Shape({
  radius: { 0: 100 },
  duration: 2000,
  onStart() {
    console.log('Параметры:', this.props);
  }
});

Поле this.props содержит текущие настройки объекта, включая динамические значения.


Логирование в Timeline

При использовании Timeline логирование становится особенно полезным:

const timeline = new mojs.Timeline({
  onStart() {
    console.log('Timeline стартовал');
  },
  onComplete() {
    console.log('Timeline завершён');
  }
});

timeline.add(tween1, tween2);

Позволяет контролировать синхронизацию нескольких анимаций.


Централизованная система логирования

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

const logger = {
  log(event, data) {
    console.log(`[${event}]`, data);
  }
};

Использование:

onStart() {
  logger.log('start', { id: this._id });
}

Преимущества:

  • единый формат сообщений;
  • возможность отключения логов;
  • интеграция с аналитикой.

Уровни логирования

Разделение логов по уровням:

const logger = {
  debug(msg) { console.debug(msg); },
  info(msg) { console.info(msg); },
  warn(msg) { console.warn(msg); },
  error(msg) { console.error(msg); }
};

Применение:

  • debug — технические детали;
  • info — основные события;
  • warn — потенциальные проблемы;
  • error — критические сбои.

Логирование пользовательских событий

mo.js часто используется в интерфейсах, реагирующих на действия пользователя:

button.addEventListener('click', () => {
  console.log('Кнопка нажата');
  burst.play();
});

Комбинирование пользовательских и анимационных логов помогает восстановить цепочку событий.


Отладка производительности

Частое логирование в onUpdate может снижать производительность. Для анализа используется выборочная запись:

let frame = 0;

onUpdate(progress) {
  if (frame % 10 === 0) {
    console.log('Прогресс:', progress);
  }
  frame++;
}

Или измерение времени:

const start = performance.now();

onComplete() {
  console.log('Время выполнения:', performance.now() - start);
}

Использование группировки логов

Для улучшения читаемости:

onStart() {
  console.group('Анимация');
  console.log('Старт');
}

onComplete() {
  console.log('Завершение');
  console.groupEnd();
}

Логирование ошибок

Обработка исключений:

try {
  tween.play();
} catch (error) {
  console.error('Ошибка анимации:', error);
}

Или внутри обработчиков:

onUpdate() {
  try {
    // логика
  } catch (e) {
    console.error(e);
  }
}

Интеграция с внешними системами

Логи могут отправляться на сервер:

function sendLog(data) {
  fetch('/logs', {
    method: 'POST',
    body: JSON.stringify(data)
  });
}

Использование:

onComplete() {
  sendLog({
    event: 'complete',
    time: Date.now()
  });
}

Отключение логирования в продакшене

Часто логирование отключается:

const isDev = process.env.NODE_ENV === 'development';

if (isDev) {
  console.log('Отладка');
}

Или через переопределение:

const logger = isDev ? console : {
  log: () => {},
  error: () => {}
};

Практика: трассировка полной анимации

Пример комплексного логирования:

const tween = new mojs.Tween({
  duration: 1500,
  onStart() {
    console.log('[START]', Date.now());
  },
  onUpdate(p) {
    console.log('[UPDATE]', p.toFixed(2));
  },
  onComplete() {
    console.log('[END]', Date.now());
  }
});

Позволяет полностью восстановить ход выполнения.


Рекомендации по использованию

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

Типичные ошибки

Частый вызов console.log в onUpdate → приводит к просадке FPS.

Отсутствие структуры → сложно анализировать данные.

Логирование без контекста → сообщения теряют смысл.

Игнорирование ошибок → сложнее находить проблемы.


Расширенные техники

Привязка ID к анимациям

const id = Math.random().toString(36);

onStart() {
  console.log(`Анимация ${id} старт`);
}

Логирование состояний

onUpdate(p) {
  console.log({
    state: 'running',
    progress: p
  });
}

Таймстемпы

console.log(new Date().toISOString());

Связь логирования с тестированием

Логи могут использоваться для:

  • автоматического тестирования анимаций;
  • проверки последовательности событий;
  • сравнения ожидаемых и фактических результатов.

Выводы по архитектуре

Грамотно организованное логирование в mo.js:

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

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