Анимация «догоняющего» дротика при перетаскивании

#flutter #dart

#трепетание #дротик

Вопрос:

В настоящее время я создаю приложение flutter, в котором пользователь может перетаскивать круг по экрану. Я использую виджет слушателя, чтобы получить текущую позицию указателя, затем использую виджет преобразования, чтобы расположить его соответствующим образом.

Что я пытаюсь построить

 class _DraggingExample extends State<VelocityAnimations>{
  var offset = Offset(0, 0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
     // I get pointer-events here.
      body: Listener(
        onPointerMove: (e) {
          setState(() {
            // - 50 to center the container
            offset = e.localPosition - Offset(50, 50);
          });
        },
        behavior: HitTestBehavior.opaque,
        child: SizedBox.expand(
          child: Stack(
            children: [
              Center(child: Text('Hello, World!')),
              // I transform the container here.
              Transform.translate(
                offset: offset,
                child: Container(
                  width: 100,
                  height: 100,
                  decoration: BoxDecoration(
                    color: Colors.black,
                    borderRadius: BorderRadius.circular(50),
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
 

Это работает отлично. Но это очень мягко. Было бы намного приятнее, если бы при перемещении указателя / пальца контейнер постепенно догонял палец. Эффект, который я ищу, можно увидеть в этом codepen . Здесь черный круг постепенно догоняет мышь по мере ее перемещения.

Я пытался использовать симуляцию физики и простые анимации, но я не могу понять, как это сделать.

Ответ №1:

Вы можете попробовать использовать AnimatedPositioned, который неявно анимирует свою позицию.

Анимацию можно настроить с duration помощью и кривых, как вы хотите.

 AnimatedPositioned(
  left: offset.dx,
  top: offset.dy,
  curve: Curves.easeOutCirc,
  duration: Duration(milliseconds: 400),
  child: Container(
    // ...
  ),
),