Я участвую в конкурсе "Креативное программирование", подробнее смотрите: Конкурс креативного программирования пришел!
В этой статье вы узнаете о более впечатляющих анимационных эффектах и узнаете, как реализовать стереоскопическое изображение мультяшечки 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. Можно заметить, что две красные линии исчезли:
π / 2
(90 градусов), она становится перпендикулярной нашему зрению, и поэтому исчезает.π / 4
, она образует угол 45 градусов относительно нашего зрения.π / 2
(90 градусов), она снова становится перпендикулярной нашему зрению, и поэтому исчезает.![]() |
![]() |
---|
Если вам кажется, что вышеописанное слишком абстрактно, обратите внимание на следующие анимации. Они демонстрируют, как когда красная линия вращается вокруг осей XY, если канвас (Canvas
) становится перпендикулярным нашему зрению (90 градусов), линия исчезает. Это связано с тем, что канвас является двумерной плоскостью, именно поэтому ранее созданные карточки не имели "толщины".| |
|
| ------------------------------------------------------------------ | ------------------------------------------------------------ |А что если вместо применения матричного преобразования к
Canvas
, применять его непосредственно к пути Path
? Вместо того чтобы вращать холст Canvas
, мы будем вращать сам путь Path
. Как показано ниже, при этом поворот происходит вокруг осей XY, но теперь это прямое преобразование путей с помощью path.transform
, то есть угол поворота холста Canvas
остаётся неизменным, а меняется только путь Path
.|- Когда красная линия поворачивается вокруг оси Y на π / 2
(90 градусов), она становится красной точкой, так как её "голова" направлена прямо на нас.
π / 4
, она образует угол 45 градусов относительно нас.π / 2
(90 градусов), она направлена точно вертикально к нам.![]() |
![]() |
---|
См. также анимацию ниже, которая демонстрирует эффект матричного преобразования пути Path
:
Кроме того, стоит отметить небольшой момент: в предыдущих примерах можно заметить использование методов leftTranslate
и translate
для изменения матрицы. Это необходимо для перемещения различных красных линий на разных позициях. Без использования этих методов центр каждой линии будет находиться в начальной точке, что приведёт к некорректному повороту. Например:- На рисунке 1 красная линия не повернута вокруг оси Z.
π / 2
, но без применения методов leftTranslate
и translate
.π / 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
для рисования цифр, что позволит создать цифрам видимость трёхмерности.| Полный код доступен здесь: 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 )