Как анимировать изображения при наведении курсора мыши с помощью Flutter for Web?

Я разработчик JavaScript и новичок во Flutter. Я просто хочу анимировать набор изображений при наведении курсора мыши, например this, с помощью Flutter for Web. Он включает в себя преобразования масштабирования, непрозрачности и оттенков серого. Как это сделать во Flutter? Заранее спасибо.


person Giri    schedule 04.02.2020    source источник


Ответы (4)


Кроме анимационной части вашего вопроса. Аргумент onHover InkWell работает только в том случае, если вы сначала укажете аргумент onTap.

InkWell(
  child: SomeWidget(),
  onTap: () {
    //You can leave it empty, like that.
  }
  onHover: (isHovering) {
    if (isHovering) {
      //The mouse is hovering.
    } else {
      //The mouse is no longer hovering.
    }
  }
)

Из документации можно узнать о преимуществах boolean, которые передаются в обратный вызов onHover:

Значение, переданное обратному вызову, истинно, если указатель вошел в эту часть материала, и ложно, если указатель вышел из этой части материала.

person Tayan    schedule 24.03.2020
comment
Спасибо за инфу :), я уже задавался вопросом, почему не работает зависание Inkwell - person Georg Panteleev; 22.10.2020

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

Вот пример с сеткой. Его действующая версия доступна на этом блокноте.

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {  
  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: 3,      
      children: <Widget>[ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),],
    );
  }
}

class ImageHover extends StatefulWidget {
  @override
  _ImageHoverState createState() => _ImageHoverState();
}

class _ImageHoverState extends State<ImageHover> {
  double elevation = 4.0;
  double scale = 1.0;
  Offset translate = Offset(0,0);
  @override
  Widget build(context) {
    return InkWell(      
      onTap: (){},
      onHover: (value){
        print(value);
        if(value){
          setState((){
            elevation = 20.0;     
            scale = 2.0;
            translate = Offset(20,20);
          });
        }else{
          setState((){
            elevation = 4.0; 
            scale = 1.0;
            translate = Offset(0,0);
          });
        }
      },
      child: Transform.translate(
        offset: translate ,        
        child: Transform.scale(
          scale: scale,
          child: Material(        
            elevation: elevation,        
            child: Image.network(           
                'https://i.ytimg.com/vi/acm9dCI5_dc/maxresdefault.jpg',              
            ),
          ),
        ),
      ),
    );
  }
}
person Abhilash Chandran    schedule 04.02.2020
comment
Как я могу масштабировать это с помощью анимации - person Jayant Dhingra; 14.06.2021

Просто создайте расширение

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

extension HoverExtension on Widget {
  Widget get translateOnHover {
    return kIsWeb ? TranslateOnHover(child: this) : ThisContainer(child: this);
  }
}

class ThisContainer extends StatelessWidget {
  ThisContainer({this.child});
  final child;
  @override
  Widget build(BuildContext context) {
    return Container(child: child);
  }
}

class TranslateOnHover extends StatefulWidget {
  final Widget child;
  TranslateOnHover({required this.child});

  @override
  _TranslateOnHoverState createState() => _TranslateOnHoverState();
}

class _TranslateOnHoverState extends State<TranslateOnHover> {
  double scale = 1.0;
  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: (e) => _mouseEnter(true),
      onExit: (e) => _mouseEnter(false),
      child: TweenAnimationBuilder(
        duration: const Duration(milliseconds: 200),
        tween: Tween<double>(begin: 1.0, end: scale),
        builder: (BuildContext context, double value, _) {
          return Transform.scale(scale: value, child: widget.child);
        },
      ),
    );
  }

  void _mouseEnter(bool hover) {
    setState(() {
      if (hover)
        scale = 1.03;
      else
        scale = 1.0;
    });
  }
}

И используйте его где угодно, позвонив

yourWidget.translateOnHover
person Madhav Tripathi    schedule 27.05.2021

Вы можете использовать InkWell, передавая метод onHover вместе с Transform Widget внутри StatefulWidget. Ниже вы можете увидеть мой код. Это виджет, который зависает в зависимости от параметра bool canHover

person Evandro Junior    schedule 20.04.2021