full_svg_flutter 1.5: инспектор живых SVG в DevTools

С версии 1.4.2 у full_svg_flutter вышло пять релизов: два платформенных исправления, новый инструмент для разработчиков, большая работа над корректностью геометрии и релиз, с которым SVG со скриптами заработали на iOS. Ниже — что изменилось и почему это важно.

Инспектор FullSVG для DevTools (1.5.0)

Когда анимированный SVG в браузере выглядит правильно, а в приложении — нет, нужно увидеть, что на самом деле сделал рендерер. Начиная с версии 1.5.0 у full_svg_flutter есть официальное расширение для Flutter DevTools. Оно подключается к приложению, запущенному в debug-режиме, и заглядывает в настоящие рендереры: тот же документ, таймлайн анимации и пейнтер, которые рисуют ваш экран.

Что внутри:

  • Живые экземпляры. Каждый смонтированный рендерер показан отдельно, даже если один и тот же ассет смонтирован дважды; для каждого видны источник, состояние анимации и число DOM-узлов.
  • SVG DOM с ленивой загрузкой. Дочерние узлы подгружаются, только когда вы раскрываете строку, поэтому большие документы не тормозят. Выберите узел — и увидите его тег, id, классы, сырые и итоговые значения атрибутов, какие атрибуты анимируются прямо сейчас и какие SMIL- и CSS-анимации на него нацелены.
  • Управление воспроизведением. Запуск, пауза, перезапуск, перемотка и скорость от 0,25× до 2×. Всё это управляет собственными детерминированными часами рендерера, а не заводит второй таймлайн.
  • Подсветка узлов. Выбранный узел обводится прямо в запущенном приложении по своей реальной геометрии рендеринга; атрибуты SVG при этом не трогаются.
  • Честная статистика. Число DOM-узлов и анимаций, активные анимации, примитивы фильтров, маски, градиенты, контуры обрезки, наличие JavaScript, текущее время и длительность. Инспектор не выдумывает время парсинга и отрисовки, которое рендерер не измеряет.

Как открыть:

  1. Запустите приложение в debug-режиме.
  2. Откройте Flutter DevTools из IDE или по ссылке из вывода flutter run.
  3. Включите расширения DevTools, когда появится запрос.
  4. Выберите расширение full_svg_flutter. В интерфейсе инспектор называется FullSVG.

Настраивать ничего не нужно. Мост работает только в debug-режиме: релизные сборки не регистрируют рендереры, не держат в памяти DOM-деревья и не собирают данные для инспектора. Экземпляры отслеживаются через слабые ссылки и по жизненному циклу виджета, а после hot restart расширение переподключается.

Есть несколько ограничений, о которых стоит знать. Главный изолят должен работать, а не стоять на брейкпоинте. Наличие JavaScript инспектор показывает, но выполнять произвольный JavaScript намеренно не даёт. Вычисленные стили CSS, происхождение значений в каскаде, выбор отдельных экземпляров <use> и тайминги кадров — пока в планах.

Полное руководство — в документации инспектора (откроется в новой вкладке).

Геометрия как в браузере (1.5.1)

1.5.1 — релиз про корректность, и собран он в основном из пул-реквестов сообщества.

  • Проценты считаются от правильного вьюпорта. Базовые фигуры, геометрия <use> и вьюпорты его экземпляров, вложенные <svg>, координаты текста, области масок и хит-тестинг теперь используют правильный вьюпорт, включая корневой SVG без собственного размера: его вьюпорт — сам виджет.
  • Анимации не теряют единицы измерения. SMIL-анимации между процентными и абсолютными значениями сохраняют обе единицы при интерполяции, аддитивном сложении и тайминге calcMode="paced".
  • objectBoundingBox берёт правильную рамку. clipPathUnits, maskUnits и maskContentUnits используют геометрические границы объекта без учёта отрисовки, поэтому обводка больше не раздувает рамку, а текст учитывается по своим layout-границам и больше не обрезается целиком.
  • Анимированные области фильтров и масок теперь применяются. Анимированные проценты в областях <filter> и <mask> перечитываются по ходу анимации, а не парсятся один раз из исходника.
  • Тайминг для каждого экземпляра. Анимации в режиме paced внутри общего содержимого <symbol> вычисляются для вьюпорта каждого экземпляра <use>.

Если ваша графика опирается на длины в процентах — а для экспортированных и адаптивных SVG это обычное дело, — с этим релизом она рендерится гораздо ближе к тому, что показывает браузер.

Нативные сборки на всех платформах (1.4.3, 1.4.4, 1.5.2)

full_svg_flutter выполняет встроенные скрипты и экспорты SVGator через quickjs_engine — мой пакет с QuickJS-NG для Flutter. Три релиза ушли на то, чтобы этот нативный слой стал скучным:

  • 1.4.3, Windows. Чистые сборки под Windows падали: регистратор плагинов, который генерирует Flutter, вызывал несуществующий символ. Исправлено в quickjs_engine 0.1.4.
  • 1.4.4, универсальные сборки macOS. Универсальные приложения для macOS теперь поставляются с мостом QuickJS, в котором есть слайсы и для Apple Silicon, и для Intel.
  • 1.5.2, iOS, Swift Package Manager и Android Gradle Plugin 9. SVG со скриптами теперь инициализируются на iOS с CocoaPods. Прежние версии пода не экспортировали ни одной функции моста, поэтому любой SVG с <script> падал с ошибкой «Failed to lookup symbol 'jsNewRuntime'». Кроме того, Flutter больше не откатывается на CocoaPods из-за quickjs_engine, а Android-приложения на AGP 9 собираются со встроенным Kotlin.

Подробности о нативной части — в отдельной статье: quickjs_engine 0.1.6.

Как обновиться

dependencies:
  full_svg_flutter: ^1.5.2

Или выполните flutter pub upgrade full_svg_flutter. Пакету нужен Flutter 3.32 или новее, а ломающих изменений API между 1.4.2 и 1.5.2 в ченджлоге нет.

Спасибо

В четырёх из этих пяти релизов есть вклад сообщества: баг-репорты, примеры для воспроизведения и пул-реквесты. Спасибо @oierxjn (откроется в новой вкладке), @remtrik (откроется в новой вкладке), @dariyooo (откроется в новой вкладке), @OrPudding (откроется в новой вкладке), @sufiyansayyed (откроется в новой вкладке) и @DomingoMG (откроется в новой вкладке).

Если SVG рендерится не так, как в браузере, откройте инспектор, проверьте итоговые значения атрибутов и пришлите мне файл (откроется в новой вкладке). Это по-прежнему самый быстрый способ сделать рендерер лучше.

Полный ченджлог: pub.dev/packages/full_svg_flutter/changelog (откроется в новой вкладке)

Нужно создать, модернизировать или сдвинуть с места цифровой продукт?

Расскажите о реальной задаче: веб, мобильное приложение, работа команды или ИИ-процесс, который пора довести до продакшена.

Обсудить проект