android开发实战 接口测试 https dataframe swing audio xampp vue图表 鼠标失去焦点事件 matlab颜色代码 新手学c还是java python相对路径怎么写 matlab读入图片 random函数用法 java编程基础 java编程实例 java方法的调用 linux系统安装步骤 iphone滚动截屏 js图片上传 安卓刷机精灵 工信部手机入网查询 dnf瞎子传说套选择 php随机数函数 autocad2004迷你版 燃烧之血十字架 lol不能全屏 保留两位小数的函数 失心迷宫怎么打 k3刷机 ps怎么旋转图层 js观察者模式 keil5注册机下载 ps测量工具 ps原位粘贴 dns地址 cf兑换券 繁简体转换 yy打不开 php是什么文件
当前位置: 首页 > 学习教程  > 编程语言

flutter中实现3d效果的侧边栏

2021/1/28 23:56:14 文章标签:

先放效果 我在github上找到了这个的源码,https://github.com/papmodern/drawer3d 可以看到它是跟随drawer拉出的宽度,不断改变吉他的图片,这里有120张吉他不同角度的图片,营造出3d效果。 这里用到了一个flutter的工具叫做image…

先放效果
gif
我在github上找到了这个的源码,https://github.com/papmodern/drawer3d

可以看到它是跟随drawer拉出的宽度,不断改变吉他的图片,这里有120张吉他不同角度的图片,营造出3d效果。

这里用到了一个flutter的工具叫做image_sequence_animator,是用来显示连续的图片,做成一个gif的效果。

然后就是我试着运行这个项目,基本没有遇到什么困难,在配置pubspec.yaml的时候,没有写对位置,这里的规范实在太严谨了。
在这里插入图片描述
源码(记得配置好要用的图片):

import 'dart:math';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:image_sequence_animator/image_sequence_animator.dart';

class Drawer3D extends StatefulWidget {
  final Widget child;

  Drawer3D({this.child});

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

class _Drawer3DState extends State<Drawer3D>
    with SingleTickerProviderStateMixin {
  var _maxSlide = 0.75;
  var _extraHeight = 0.1;
  double _startingPos;
  var _drawerVisible = false;
  AnimationController _animationController;
  Size _screen = Size(0, 0);
  CurvedAnimation _animator;
  CurvedAnimation _objAnimator;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 800),
    );
    _animator = CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOutQuad,
      reverseCurve: Curves.easeInQuad,
    );
    _objAnimator = CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
      reverseCurve: Curves.easeIn,
    );
  }

  @override
  void didChangeDependencies() {
    _screen = MediaQuery.of(context).size;
    _maxSlide *= _screen.width;
    _extraHeight *= _screen.height;
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: GestureDetector(
        onHorizontalDragStart: _onDragStart,
        onHorizontalDragUpdate: _onDragUpdate,
        onHorizontalDragEnd: _onDragEnd,
        child: Stack(
          overflow: Overflow.visible,
          children: <Widget>[
            //Space color - it also makes the empty space touchable
            Container(color: Color(0xFFaaa598)),
            _buildBackground(),
            _build3dObject(),
            _buildDrawer(),
            _buildHeader(),
            _buildOverlay(),
          ],
        ),
      ),
    );
  }

  void _onDragStart(DragStartDetails details) {
    _startingPos = details.globalPosition.dx;
  }

  void _onDragUpdate(DragUpdateDetails details) {
    final globalDelta = details.globalPosition.dx - _startingPos;
    if (globalDelta > 0) {
      final pos = globalDelta / _screen.width;
      if (_drawerVisible && pos <= 1.0) return;
      _animationController.value = pos;
    } else {
      final pos = 1 - (globalDelta.abs() / _screen.width);
      if (!_drawerVisible && pos >= 0.0) return;
      _animationController.value = pos;
    }
  }

  void _onDragEnd(DragEndDetails details) {
    if (details.velocity.pixelsPerSecond.dx.abs() > 500) {
      if (details.velocity.pixelsPerSecond.dx > 0) {
        _animationController.forward(from: _animationController.value);
        _drawerVisible = true;
      } else {
        _animationController.reverse(from: _animationController.value);
        _drawerVisible = false;
      }
      return;
    }
    if (_animationController.value > 0.5) {
      {
        _animationController.forward(from: _animationController.value);
        _drawerVisible = true;
      }
    } else {
      {
        _animationController.reverse(from: _animationController.value);
        _drawerVisible = false;
      }
    }
  }

  void _toggleDrawer() {
    if (_animationController.value < 0.5)
      _animationController.forward();
    else
      _animationController.reverse();
  }

  _buildMenuItem(String s, {bool active = false}) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 5),
      child: InkWell(
        onTap: () {},
        child: Text(
          s.toUpperCase(),
          style: TextStyle(
            fontSize: 25,
            color: active ? Color(0xffbb0000) : null,
            fontWeight: FontWeight.w900,
          ),
        ),
      ),
    );
  }

  _buildFooterMenuItem(String s) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 5),
      child: InkWell(
        onTap: () {},
        child: Text(
          s.toUpperCase(),
          style: TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.w900,
          ),
        ),
      ),
    );
  }

  _buildBackground() => Positioned.fill(
    top: -_extraHeight,
    bottom: -_extraHeight,
    child: AnimatedBuilder(
      animation: _animator,
      builder: (context, widget) => Transform.translate(
        offset: Offset(_maxSlide * _animator.value, 0),
        child: Transform(
          transform: Matrix4.identity()
            ..setEntry(3, 2, 0.001)
            ..rotateY((pi / 2 + 0.1) * -_animator.value),
          alignment: Alignment.centerLeft,
          child: widget,
        ),
      ),
      child: Container(
        color: Color(0xffe8dfce),
        child: Stack(
          overflow: Overflow.visible,
          children: <Widget>[
            //Fender word
            Positioned(
              top: _extraHeight + 0.1 * _screen.height,
              left: 80,
              child: Transform.rotate(
                angle: 90 * (pi / 180),
                alignment: Alignment.centerLeft,
                child: Text(
                  "FENDER",
                  style: TextStyle(
                    fontSize: 100,
                    color: Color(0xFFc7c0b2),
                    shadows: [
                      Shadow(
                        color: Colors.black26,
                        blurRadius: 5,
                        offset: Offset(2.0, 0.0),
                      ),
                    ],
                    fontWeight: FontWeight.w900,
                  ),
                ),
              ),
            ),
            // Shadow
            Positioned(
              top: _extraHeight + 0.13 * _screen.height,
              bottom: _extraHeight + 0.24 * _screen.height,
              left: _maxSlide - 0.41 * _screen.width,
              right: _screen.width * 1.06 - _maxSlide,
              child: Column(
                children: <Widget>[
                  Flexible(
                    child: FractionallySizedBox(
                      widthFactor: 0.2,
                      child: Container(
                        decoration: BoxDecoration(
                          boxShadow: [
                            BoxShadow(
                              blurRadius: 50,
                              color: Colors.black38,
                            )
                          ],
                          borderRadius: BorderRadius.circular(50),
                        ),
                      ),
                    ),
                  ),
                  Flexible(
                    child: Container(
                      decoration: BoxDecoration(
                        boxShadow: [
                          BoxShadow(
                            blurRadius: 50,
                            color: Colors.black26,
                          )
                        ],
                        borderRadius: BorderRadius.circular(50),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            AnimatedBuilder(
              animation: _animator,
              builder: (_, __) => Container(
                color: Colors.black.withAlpha(
                  (150 * _animator.value).floor(),
                ),
              ),
            ),
          ],
        ),
      ),
    ),
  );

  _buildDrawer() => Positioned.fill(
    top: -_extraHeight,
    bottom: -_extraHeight,
    left: 0,
    right: _screen.width - _maxSlide,
    child: AnimatedBuilder(
      animation: _animator,
      builder: (context, widget) {
        return Transform.translate(
          offset: Offset(_maxSlide * (_animator.value - 1), 0),
          child: Transform(
            transform: Matrix4.identity()
              ..setEntry(3, 2, 0.001)
              ..rotateY(pi * (1 - _animator.value) / 2),
            alignment: Alignment.centerRight,
            child: widget,
          ),
        );
      },
      child: Container(
        color: Color(0xffe8dfce),
        child: Stack(
          overflow: Overflow.visible,
          children: <Widget>[
            Positioned(
              top: 0,
              bottom: 0,
              right: 0,
              child: Container(
                width: 5,
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    colors: [Colors.transparent, Colors.black12],
                  ),
                ),
              ),
            ),
            Positioned.fill(
              top: _extraHeight,
              bottom: _extraHeight,
              child: SafeArea(
                child: Container(
                  width: _maxSlide,
                  child: Padding(
                    padding: const EdgeInsets.all(40.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        Row(
                          children: <Widget>[
                            Container(
                              width: 25,
                              height: 25,
                              decoration: BoxDecoration(
                                border: Border.all(
                                  color: Colors.black26,
                                  width: 4,
                                ),
                                shape: BoxShape.circle,
                              ),
                            ),
                            Transform.translate(
                              offset: Offset(-15, 0),
                              child: Text(
                                "STRING",
                                style: TextStyle(
                                  fontSize: 12,
                                  backgroundColor: Color(0xffe8dfce),
                                  fontWeight: FontWeight.w900,
                                  fontStyle: FontStyle.italic,
                                ),
                              ),
                            )
                          ],
                        ),
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            _buildMenuItem("Guitars", active: true),
                            _buildMenuItem("Basses"),
                            _buildMenuItem("Amps"),
                            _buildMenuItem("Pedals"),
                            _buildMenuItem("Others"),
                          ],
                        ),
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            _buildFooterMenuItem("About"),
                            _buildFooterMenuItem("Support"),
                            _buildFooterMenuItem("Terms"),
                            _buildFooterMenuItem("Faqs"),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
            AnimatedBuilder(
              animation: _animator,
              builder: (_, __) => Container(
                width: _maxSlide,
                color: Colors.black.withAlpha(
                  (150 * (1 - _animator.value)).floor(),
                ),
              ),
            ),
          ],
        ),
      ),
    ),
  );

  _build3dObject() => Positioned(
    top: 0.1 * _screen.height,
    bottom: 0.22 * _screen.height,
    left: _maxSlide - _screen.width * 0.5,
    right: _screen.width * 0.85 - _maxSlide,
    child: AnimatedBuilder(
      animation: _objAnimator,
      builder: (_, __) => ImageSequenceAnimator(
        "assets/guitarSequence", //folderName
        "", //fileName
        1, //suffixStart
        4, //suffixCount
        "png", //fileFormat
        120, //frameCount
        fps: 60,
        isLooping: false,
        isBoomerang: true,
        isAutoPlay: false,
        frame: (_objAnimator.value * 120).ceil(),
      ),
    ),
  );

  _buildHeader() => SafeArea(
    child: AnimatedBuilder(
        animation: _animator,
        builder: (_, __) {
          return Transform.translate(
            offset: Offset((_screen.width - 60) * _animator.value, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                SizedBox(
                  width: 50,
                  height: 50,
                  child: InkWell(
                    onTap: _toggleDrawer,
                    child: Icon(Icons.menu),
                  ),
                ),
                Opacity(
                  opacity: 1 - _animator.value,
                  child: Text(
                    "PRODUCT DETAIL",
                    style: TextStyle(fontWeight: FontWeight.w900),
                  ),
                ),
                SizedBox(width: 50, height: 50),
              ],
            ),
          );
        }),
  );

  _buildOverlay() => Positioned(
    top: 0,
    bottom: 50,
    left: 0,
    right: 0,
    child: AnimatedBuilder(
      animation: _animator,
      builder: (_, widget) => Opacity(
        opacity: 1 - _animator.value,
        child: Transform.translate(
          offset: Offset((_maxSlide + 50) * _animator.value, 0),
          child: Transform(
            transform: Matrix4.identity()
              ..setEntry(3, 2, 0.001)
              ..rotateY((pi / 2 + 0.1) * -_animator.value),
            alignment: Alignment.centerLeft,
            child: widget,
          ),
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 50.0),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.end,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            Text(
              "Fender\nAmerican\nElite Strat",
              style: TextStyle(
                fontSize: 30,
                fontWeight: FontWeight.w900,
              ),
            ),
            Row(
              children: <Widget>[
                Text(
                  "SPEC",
                  style: TextStyle(fontWeight: FontWeight.w600),
                ),
                Icon(Icons.keyboard_arrow_down),
              ],
            ),
          ],
        ),
      ),
    ),
  );
}

本文链接: http://www.dtmao.cc/news_show_650329.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?