1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/CarGuo-GSYFlutterBook

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Flutter-N11.md 28 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 10.03.2025 00:06 5767d61

Реализация настоящего 3D анимационного эффекта в Flutter, создание стереоскопического Dash и 3D логотипа через чистый код

Я участвую в конкурсе "Креативное программирование", подробнее смотрите: Конкурс креативного программирования пришел!

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

❤️ Эта статья принимает участие в конкурсе, поэтому прошу вас проголосовать за неё, нажав на лайк и кнопки одобрения, ваш голос очень важен для нас!

В предыдущей статье "Потрясающие 3D карточки и эффект 360°", мы использовали жестовый код и угловое управление, чтобы реализовать псевдо-3D визуальный эффект на 2D холсте. Когда мне показалось, что это достаточно хорошо, один из моих коллег предложил ключевой вопрос: карточка не имеет толщины, то есть она не имеет 3D качества.

Действительно, как видно на следующем рисунке, в предыдущей реализации были две проблемы:

  • При повороте карточки на бок, она теряет "толщину" и даже исчезает
  • Текст на карточке имел видимость выпуклости, но сбоку он также теряет стереоскопическую глубину

Чтобы реализовать трехмерное качество на двумерной плоскости, я нашел фреймворк Zdog для фронтенд-разработки. Zdog — это псевдо-3D движок, использующий Canvas API для создания эффекта трехмерности.

Zdog как JavaScript фреймворк, он состоит всего из около 2800 строк кода, его минимальный размер составляет 28 КБ, что делает его очень легковесным.

Хотя Zdog является чистым JavaScript фреймворком, поскольку он использует логику Canvas, его можно легко адаптировать к Flutter, так как сам Flutter сильно зависит от Canvas API. В сообществе Flutter уже существует порт Zdog: zflutter. > Несмотря на то, что автор этого пакета уже два года не занимается его поддержкой и не выпускает версию с поддержкой null-safety в pub, это всё же открытый проект, поэтому можно самостоятельно сделать необходимые изменения. После "небольшой" адаптации, zflutter снова "ожил" в Flutter 3.0.

Сначала посмотрим на результат. После внедрения zflutter мы можем видеть, как эффект глубины карточек значительно улучшился:

  • Карточки теперь имеют ощущение объема, они не исчезают при повороте
  • Шрифт на карточках также имеет трёхмерный эффект при наклоне

ПримерПеред тем, как рассказать о реализации, нам следует ответить на вопрос: Как zflutter создаёт трёхмерный эффект на двумерной поверхности? Основная идея заключается в том, что матричная трансформация, вызванная жестами, применяется либо к холсту, либо к пути.Для начала рассмотрим пример. В следующем коде создается CustomPaint, а затем на нем отрисовываются четыре одинаковых красных линии. Далее три из этих линий преобразуются с помощью различных матричных поворотов канваса, как показано на рисунке 2. Можно заметить, что две красные линии исчезли:

  • Когда красная линия поворачивается вокруг оси Y на π / 2 (90 градусов), она становится перпендикулярной нашему зрению, и поэтому исчезает.
  • Когда красная линия поворачивается вокруг осей XY на π / 4, она образует угол 45 градусов относительно нашего зрения.
  • Когда красная линия поворачивается вокруг осей XY на π / 2 (90 градусов), она снова становится перпендикулярной нашему зрению, и поэтому исчезает.
Пример Пример

Если вам кажется, что вышеописанное слишком абстрактно, обратите внимание на следующие анимации. Они демонстрируют, как когда красная линия вращается вокруг осей XY, если канвас (Canvas) становится перпендикулярным нашему зрению (90 градусов), линия исчезает. Это связано с тем, что канвас является двумерной плоскостью, именно поэтому ранее созданные карточки не имели "толщины".| Анимация | Пример | | ------------------------------------------------------------------ | ------------------------------------------------------------ |А что если вместо применения матричного преобразования к Canvas, применять его непосредственно к пути Path? Вместо того чтобы вращать холст Canvas, мы будем вращать сам путь Path. Как показано ниже, при этом поворот происходит вокруг осей XY, но теперь это прямое преобразование путей с помощью path.transform, то есть угол поворота холста Canvas остаётся неизменным, а меняется только путь Path.|- Когда красная линия поворачивается вокруг оси Y на π / 2 (90 градусов), она становится красной точкой, так как её "голова" направлена прямо на нас.

  • Когда красная линия поворачивается вокруг осей XY на π / 4, она образует угол 45 градусов относительно нас.
  • Когда красная линия поворачивается вокруг осей XY на π / 2 (90 градусов), она направлена точно вертикально к нам.
image image

См. также анимацию ниже, которая демонстрирует эффект матричного преобразования пути Path:

анимация

Кроме того, стоит отметить небольшой момент: в предыдущих примерах можно заметить использование методов leftTranslate и translate для изменения матрицы. Это необходимо для перемещения различных красных линий на разных позициях. Без использования этих методов центр каждой линии будет находиться в начальной точке, что приведёт к некорректному повороту. Например:- На рисунке 1 красная линия не повернута вокруг оси Z.

  • На рисунке 2 красная линия повёрнута вокруг оси Z на π / 2, но без применения методов leftTranslate и translate.
  • На рисунке 3 красная линия повёрнута вокруг оси Z на π / 2, и применяются методы leftTranslate и translate.

| | | |

| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |

Полный код доступен по адресу: https://github.com/CarGuo/gsy_flutter_demo/blob/master/lib/widget/transform_canvas_demo_page.dart

Адрес веб-эксперимента, не забудьте открыть режим мобильной версии браузера Chrome на компьютере: https://guoshuyu.cn/home/web/#Демонстрация canvas transform.Теперь обратимся к zflutter, в zflutter реализация аналогична трёхмерному эффекту, который достигается путём объединения различных графических объектов и линий, а затем применением матричных преобразований к Path, как показано на следующей фигуре 2 с примером стерео-квадрата, что соответствует нашим требованиям к увеличению толщины.

Сначала давайте кратко рассмотрим основные объекты, используемые в zflutter:- Класс ZIllustration выполняет роль холста, который можно настроить свойством zoom, чтобы регулировать масштаб холста;

  • Класс ZPositioned используется для конфигурации информации о положении и размерах, таких как свойства scale, translate, rotate и т.д. (На самом деле он просто передает полученные матричные параметры в ParentData и передает их потомкам);
  • Класс ZDragDetector используется для обработки информации о жестах, особенно для быстрого достижения эффекта 360° поворота при помощи настройки свойства rotate класса ZPositioned;
  • Класс ZGroup используется для объединения нескольких слоёв графических объектов;
  • Класс ZToBoxAdapter используется для вложения обычных Flutter компонентов;
  • Внутренние формы, такие как ZRect, ZRoundedRect, ZCircle, ZEllipse, ZPolygon, ZCone, ZCylinder, ZHemisphere и т.д., используются для создания различных геометрических форм, как показано ниже;
  • Класс ZShape работает аналогично Canvas и используется вместе с ZMove, ZLine, ZBezier, ZArc и другими для создания пользовательских форм.

Поэтому, чтобы достичь "истинного" трёхмерного эффекта для карточки, нам потребуется сделать следующее:

  • Добавить холст ZIllustration
  • Добавить детектор жестов ZDragDetector совместно с ZPositioned для обработки жестовых поворотов
  • Добавить группу ZGroup, внутри которой через ZToBoxAdapter добавить две PNG-картинки банковской карты — переднюю и заднюю стороны
  • Между двумя картинками добавить ZRoundedRect для создания границы, установив цвет Color(0x8A000000) для получения эффекта увеличенной толщины
  • Использовать ZShape для рисования цифр, что позволит создать цифрам видимость трёхмерности.| | | | | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | Как показано выше, можно заметить, что после обработки с помощью zflutter не только сам карточный элемент приобрёл эффект "толщины", но и текст стал выглядеть объёмно при наклоне. Даже в случае поворота до 90 градусов, как показано на рисунке 3, видна чёткая иерархия между картой и текстом.

Полный код доступен здесь: https://github.com/CarGuo/gsy_flutter_demo/blob/master/lib/widget/card_real_3d_demo_page.dart

Адрес веб-эксперимента, не забудьте открыть режим мобильной версии браузера Chrome: https://guoshuyu.cn/home/web/%E7%A1%AC%E6%A0%B8%203D%20%E5%8D%A1%E7%89%87%E6%97%8B%E8%BD%AC/Детальный исходный код можно найти по приведённым выше ссылкам. После знакомства с zflutter возникает вопрос: что ещё мы можем сделать с использованием zflutter? На самом деле, в официальных демонстрационных примерах есть очень типичный случай — это милашка Dash, символ Flutter. Следующим шагом будет рассмотрение того, как использовать zflutter для создания трёхмерного образа Dash.

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

Затем используем три разных ZEllipse эллипса, расположенные в различных местах и углах, чтобы создать волосы Dash. В действительности многие эффекты в zflutter создаются путём сочетания таких фигур.

После этого используем ZArc внутри ZShape для создания хвоста Dash различными углами. Ключевой момент заключается в том, что на оси z должны быть части, имеющие разницу высот, как показано ниже. Эти изображения демонстрируют видимость хвоста Dash при трёх различных углах.

| | | | ------------------------------------------------------------ | ------------------------------------------------------------ |Наконец, регулирование углов двух ZEllipse эллипсов позволяет создать эффект ручного рисования Dash. Здесь zflutter действительно проверяет способность разработчиков воспринимать пространство на плоскости через графические фигуры.| | | | ------------------------------------------------------------ | ------------------------------------------------------------ |

Затем с помощью ZCone можно быстро реализовать рот Dash.

Эта часть, вероятно, понятна всем без использования кода — это создание глаз Dash путём объединения нескольких объектов ZEllipse и ZCircle.

Наконец, соединив все компоненты вместе и настроив циклические анимационные параметры, получаем живого и трёхмерного Dash.

Полный код доступен здесь: https://github.com/CarGuo/gsy_flutter_demo/blob/master/lib/widget/dash_3d_demo_page.dart

Адрес веб-приложения для просмотра: https://guoshuyu.cn/home/web/#3D%20Dash. Для просмотра на компьютере используйте режим мобильной версии браузера Chrome.Сравнение с реальным Dash показывает, что Dash, реализованный с использованием zflutter, выглядит довольно точно. При этом сам zflutter имеет размер около 82 кБ, что делает его сверхлёгковесным псевдо-трёхмерным анимационным фреймворком. Он обеспечивает необходимый визуальный эффект для работы в трёхмерном пространстве при минимальных затратах на внедрение. Основной ключевой момент заключается в том, что матричное преобразование применяется либо к холсту, либо к пути.

Понимая принцип действия, мы можем использовать три простых ZShape, объединённые с помощью ZMove и ZLine, чтобы создать логотип с трёхмерным эффектом, где параметры можно прямым образом отобразить из SVG-пути. | | | | |

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

Полный код доступен здесь: https://github.com/CarGuo/gsy_flutter_demo/blob/master/lib/widget/juejin_3d_logo_demo_page.dart

Адрес веб-приложения для просмотра, запустите его в режиме мобильной версии браузера Chrome на компьютере: https://guoshuyu.cn/home/web/%D0%A1%D0%B0%D0%BC%D0%BE%D0%B5%203d%20%D0%BB%D0%BE%D0%B3%D0%BE%D1%82%D0%BE%D0%BF%D0%B0

Конечно, кто-то может сказать, что этот логотип всё ещё недостаточно трёхмерен, так как он слишком плоский. Да, действительно, из-за влияния параметров stroke, трёхмерность сбоку несколько ограничена. Чтобы повысить трёхмерность, мы можем использовать компонент ZBoxToBoxAdapter из библиотеки zflutter.В zflutter компонент ZBoxToBoxAdapter позволяет настроить внешний вид каждой из шести граней прямоугольного параллелепипеда через параметры front, rear, left, right, top, bottom. Само собой, он создаёт трёхмерный прямоугольник на основе параметров width, height, depth, как показано на рисунке 1 ниже.| Пример | Изображение | Анимация | | ------------------------------------------------------------ | -------------------------------------------------------- | -------------------------------------------------------- |

Затем мы используем уголомер на рисунке 2 для определения угла логотипа Juejin, после чего, используя различные положения и углы, мы объединяем различные прямоугольники с помощью ZBoxToBoxAdapter, чтобы создать трёхмерный логотип Juejin, как показано на рисунке 3.

Пример Пример Пример

Полный код доступен здесь: https://github.com/CarGuo/gsy_flutter_demo/blob/master/lib/widget/juejin_3d_box_logo_demo_page.dart> Адрес веб-приложения для просмотра, запустите его в режиме мобильной версии браузера Chrome на компьютере: https://guoshuyu.cn/home/web/%D0%9A%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BA%D0%B0%D1%86%D0%B8%D1%8F%203d%20%D0%BB%D0%BE%D0%B3%D0%BE%D1%82%D0%BE%D0%BF%D0%B0
Можно заметить, что zflutter, хотя и не так мощен и удобен, как Rive для быстрого добавления анимации логотипу JiGuang, тем не менее, он достаточно компактный, не требует загрузки каких-либо ресурсов и позволяет реализовать различные трехмерные анимации чисто через код, что делает его более управляемым для программистов, поскольку ему не требуется зависеть от каких-либо сторонних дизайнерских инструментов. Однако скорость разработки с использованием zflutter действительно ниже, чем при работе с Rive, и требуются навыки пространственного воображения.Итак, заключение статьи о спецэффектах здесь и сейчас. Если у вас есть какие-либо идеи или предложения, пожалуйста, оставьте свои комментарии. Благодарю всех за ваше терпеливое чтение, и прошу вас, дорогие читатели, если вам понравилось, не забудьте поставить лайк и сделать "три в одном" — это будет очень полезно!

Опубликовать ( 0 )

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

1
https://api.gitlife.ru/oschina-mirror/CarGuo-GSYFlutterBook.git
git@api.gitlife.ru:oschina-mirror/CarGuo-GSYFlutterBook.git
oschina-mirror
CarGuo-GSYFlutterBook
CarGuo-GSYFlutterBook
master