【问题标题】:How to animate images on mouse hover using Flutter for Web?如何使用 Flutter for Web 在鼠标悬停时为图像设置动画?
【发布时间】:2020-05-20 10:34:57
【问题描述】:

我是一名 JavaScript 开发人员,并且是 Flutter 的新手。我只想使用 Flutter for Web 在鼠标悬停时为一组图像设置动画,例如 this。它包括缩放、不透明度和灰度转换。如何在 Flutter 中实现这一点? 提前致谢。

【问题讨论】:

    标签: flutter flutter-animation flutter-web


    【解决方案1】:

    除了您问题的动画部分。 InkWellonHover 参数仅在您先指定 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.
        }
      }
    )
    

    documentation,这里是boolean 的好处,它被传递给onHover 回调:

    如果指针已经进入这部分,则传递给回调的值为真 材质,如果指针已退出材质的这一部分,则返回 false。

    【讨论】:

    • 感谢您提供的信息 :),我已经想知道为什么 Inkwell 悬停不起作用
    【解决方案2】:

    这只是一个演示,显示您可以使用onHoverInkwell 小部件来完成任务。您必须想出逻辑来决定应该使用多少偏移量和比例以及如何定位小部件。在我的示例中,我使用了网格视图。您也许可以使用堆栈根据悬停设置当前活动的小部件。

    这里是一个网格视图的例子。此dartpad 中提供了此版本的实时版本。

    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',              
                ),
              ),
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 我如何用动画来缩放它
    【解决方案3】:

    只需创建一个扩展程序

    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
    

    【讨论】:

      【解决方案4】:

      您可以使用 InkWell 将 onHover 方法与 StatefulWidget 内的 Transform Widget 一起传递。 在下面你可以看到我的一些代码。这是一个根据 bool 参数悬停的小部件canHover

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-18
        • 2020-07-12
        • 2021-05-26
        • 1970-01-01
        • 1970-01-01
        • 2012-05-04
        • 1970-01-01
        • 2013-03-20
        相关资源
        最近更新 更多