Создавайте очень нестандартные анимации во флаттере - PullRequest
0 голосов
/ 19 декабря 2018

Я следовал различным учебным пособиям по анимации на flutter.io, (анимация, колебания, переходы и т. Д.) И все это здорово.

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

Давайте рассмотрим простой пример - анимация Пауза -> Воспроизведение.

Сначала у нас есть значок паузы, две вертикальные полосы.

Допустим, я бы хотел

  1. Вырастить правую полосу в треугольник, добавив дополнительный угол в центре крайней правой вертикальной стороны и переместив его вправо.
  2. После этого немного переместив этот треугольник с шага 1 влево, чтобы он теперь прилипал к крайнему левому вертикальному столбцу, в более крупный «треугольник» (на самом деле это был бы пятиугольник).

Это выглядело бы как кнопка воспроизведения, а не как кнопка паузы.

Как мне добиться такой анимации?Я предполагаю, что не могу работать с классом иконок.И я почти уверен, что не должен делать это с виджетами и просто перемещать их.

С чего бы мне начать исследовать такую ​​точность анимации?

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

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

Проблема в том, что анимация, о которой вы говоритеумеренно сложен с точки зрения того, как это на самом деле работает.Есть несколько элементов, которые меняются со временем и, возможно, даже становятся одним большим элементом.

Существует два подхода к решению этой проблемы.Первый - использовать внешний инструмент анимации для создания этой анимации, используя любые функции, которые инструмент анимации должен выполнять для изменения и слияния элементов.Затем, когда у вас есть анимация, которая работает к вашему удовольствию, вы должны как-то импортировать ее в свой проект.Вот тут-то и появляются плагины fluttie и flare_flutter - если вы использовали Aftereffects, вы используете Lottie для экспорта файла, а затем плагин fluttie для его отображения.Flare немного проще, так как он предназначен для флаттера, но вы все равно создаете анимацию извне, а затем добавляете файл в ваши активы для рендеринга.


Другой подход - сделать анимацию самостоятельно.Это влечет за собой три вещи:

  1. Создание виджета, содержащего анимацию.
  2. Создание CustomPainter для фактического рисования результата.
  3. Дополнительно, другой класс, который действует как контроллер для запуска / остановки / и т. Д. Анимации.

Виджет, содержащий анимацию, может также быть контроллером, если вы используете GlobalKey для доступаэто и выставить методы запуска / остановки, но это немного грязно.Лучше иметь внешний объект, который является контроллером - и вы могли бы даже использовать AnimationController как есть, хотя он был бы менее «чистым».

Если вы не передадите его, вы бывероятно, в вашем виджете есть AnimationController, который вы запускаете и останавливаете из своего контроллера или класса.По сути, он будет просто переходить от 0 к 1 и обратно и будет отвечать за перестройку CustomPainter (возможно, с использованием AnimatedBuilder).

Это очень простой пример, которому не нужен внешний контроллер в качестве жестаобнаружение происходит внутри виджета.Обратите внимание, что я не вызываю setState каждый раз, когда задан элемент «begin», потому что на самом деле я не хочу, чтобы он перестраивался при его изменении.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: StartStop(),
        ),
      ),
    );
  }
}

class StartStop extends StatefulWidget {
  @override
  StartStopState createState() {
    return new StartStopState();
  }
}

class StartStopState extends State<StartStop> with TickerProviderStateMixin<StartStop> {
  bool started = false;

  AnimationController animationController;

  @override
  void initState() {
    animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 300));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        started ? animationController.forward() : animationController.reverse();
        started = !started;
      },
      child: SizedBox(
        width: 100,
        height: 100,
        child: AnimatedBuilder(
          animation: animationController,
          builder: (context, child) {
            return CustomPaint(
              painter: StartStopPainter(animationController.value),
              size: Size.infinite,
              child: child,
            );
          },
        ),
      ),
    );
  }
}

class StartStopPainter extends CustomPainter {
  final double percentAnimated;

  StartStopPainter(this.percentAnimated) : assert(percentAnimated >= 0 && percentAnimated <= 1);

  @override
  void paint(Canvas canvas, Size size) {
    var pausePaint = Paint()..color = Colors.black.withOpacity(1 - percentAnimated);

    canvas.drawRect(Rect.fromLTRB(20, 10, 40, 90), pausePaint);
    canvas.drawRect(Rect.fromLTRB(60, 10, 80, 90), pausePaint);

    var playPaint = Paint()..color = Colors.black.withOpacity(percentAnimated);

    canvas.drawPath(Path()..addPolygon([Offset(20, 10), Offset(20, 90), Offset(80, 50)], true), playPaint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

Я оставлю фактическую пользовательскую частьанимация (где вы делаете прямоугольник изменится на треугольник и т. д.) для вас.Вместо того, чтобы использовать непрозрачность и несколько различных вызовов рисования, вы просто использовали бы ввод percentAnimated, чтобы решить, какой путь или многоугольник рисовать.

0 голосов
/ 20 декабря 2018

Существует 2 пакета анимации, которые могут помочь вам в этом: Flare и Lottie

Fluttie: требуется программное обеспечение для анимации, например, после эффектов.

Пакет: https://pub.dartlang.org/packages/fluttie

Flare: поставляется с собственным бесплатным программным обеспечением для анимации: https://www.2dimensions.com/about-flare Пакет: https://pub.dartlang.org/packages/flare_flutter

Flare действительно глючит прямо сейчас, если вы работаете не только в их редакторе, но, насколько я понимаю,Это работает более эффективно и Fluttie.Флатти более стабильный, но более дорогой.Выбирай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...