zoukankan      html  css  js  c++  java
  • Flutter 手指放大 平移 旋转 Widget

    import 'package:dart_printf/dart_printf.dart';
    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      double _scale = 1.0;
      double _baseScale = 0;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              onScaleStart: (ScaleStartDetails scaleStartDetails) {
                _baseScale = _scale;
              },
              onScaleUpdate: (ScaleUpdateDetails scaleUpdateDetails) {
                double _ns = _baseScale * scaleUpdateDetails.scale;
                printf('[scale]: %f %f', [scaleUpdateDetails.scale, _ns]);
                if (_ns <= 1.0) return;
                setState(() {
                  _scale = _ns;
                });
              },
              child: Transform.scale(
                scale: _scale,
                child: Container(
                   300,
                  height: 300,
                  color: Colors.red,
                ),
              ),
            ),
          ),
        );
      }
    }
    

    移动它

    class _HomePageState extends State<HomePage> {
      double _scale = 1.0;
      double _baseScale = 0;
      Offset _to = Offset(0, 0);
      Offset _baseTo = Offset(0, 0);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              onDoubleTap: () {
                setState(() {
                  _scale = 1.0;
                  _to = Offset(0, 0);
                  _baseTo = Offset(0, 0);
                });
              },
              onScaleStart: (ScaleStartDetails d) {
                _baseScale = _scale;
                _baseTo = d.localFocalPoint;
              },
              onScaleUpdate: (ScaleUpdateDetails d) {
                double _ns = _baseScale * d.scale;
                if (_ns > 1.0) {
                  setState(() {
                    _scale = _ns;
                  });
                }
    
                setState(() {
                  _to = d.localFocalPoint;
                });
              },
              child: Transform(
                transform: Matrix4.identity()
                  ..scale(_scale, _scale, 1.0)
                  ..translate(_to.dx - _baseTo.dx, _to.dy - _baseTo.dy),
                alignment: Alignment.center,
                child: Container(
                   200,
                  height: 200,
                  color: Colors.red,
                ),
              ),
            ),
          ),
        );
      }
    }
    

    简单的碰撞检测

    class _HomePageState extends State<HomePage> {
      double _scale = 1.0;
      double _baseScale = 0;
      Offset _to = Offset(0, 0);
      Offset _baseTo = Offset(0, 0);
      GlobalKey stickyKey = GlobalKey();
    
      @override
      Widget build(BuildContext context) {
        Size window = MediaQuery.of(context).size;
        return Scaffold(
          body: Center(
            child: GestureDetector(
              onDoubleTap: () {
                setState(() {
                  _scale = 1.0;
                  _to = Offset(0, 0);
                  _baseTo = Offset(0, 0);
                });
              },
              onScaleStart: (ScaleStartDetails d) {
                _baseScale = _scale;
                _baseTo = d.localFocalPoint;
              },
              onScaleUpdate: (ScaleUpdateDetails d) {
                double _ns = _baseScale * d.scale;
                if (_ns > 0.8) {
                  setState(() {
                    _scale = _ns;
                  });
                }
    
                Offset lfp = d.localFocalPoint;
                var _box = stickyKey.currentContext.findRenderObject() as RenderBox;
                Offset _pos = _box.localToGlobal(Offset.zero);
                var _boxsize = _box.size * _ns;
    
                if (_boxsize.width <= window.width) {
                  if (!(_pos.dx <= 0 && lfp.dx < _to.dx ||
                      _pos.dx + _boxsize.width >= window.width && lfp.dx > _to.dx ||
                      _pos.dy <= 0 && lfp.dy < _to.dy ||
                      _pos.dy + _boxsize.height >= window.height &&
                          lfp.dy > _to.dy)) {
                    setState(() {
                      _to = d.localFocalPoint;
                    });
                  }
                } else {
                  if (!(_pos.dx >= 0 && lfp.dx > _to.dx ||
                      _pos.dx + _boxsize.width <= window.width && lfp.dx < _to.dx ||
                      _pos.dy >= 0 && lfp.dy > _to.dy ||
                      _pos.dy + _boxsize.width <= window.height &&
                          lfp.dy < _to.dy)) {
                    setState(() {
                      _to = d.localFocalPoint;
                    });
                  }
                }
              },
              child: Transform(
                transform: Matrix4.identity()
                  ..scale(_scale, _scale)
                  ..translate(_to.dx - _baseTo.dx, _to.dy - _baseTo.dy),
                alignment: Alignment.center,
                child: Image.network(
                  'https://i.loli.net/2020/01/14/w1dcNtf4SECG6yX.jpg',
                  key: stickyKey,
                ),
              ),
            ),
          ),
        );
      }
    }
    

    Z轴旋转

    class _HomePageState extends State<HomePage> {
      double _rotation = 0.0;
      double _lastRotation = 0.0;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              onScaleUpdate: (ScaleUpdateDetails d) {
                printf('[rotation] %f', [d.rotation]);
                setState(() {
                  _rotation = d.rotation;
                });
              },
              onScaleEnd: (_) {
                _lastRotation += _rotation;
              },
              child: Transform(
                transform: Matrix4.identity()..rotateZ(_lastRotation + _rotation),
                alignment: Alignment.center,
                child: Image.network(
                  'https://i.loli.net/2020/01/14/w1dcNtf4SECG6yX.jpg',
                ),
              ),
            ),
          ),
        );
      }
    }
    

    保存上一次的移动偏移

    class _HomePageState extends State<HomePage> {
      Offset pos = Offset(0, 0);
      Offset basePos = Offset(0, 0);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              onScaleStart: (ScaleStartDetails d) {
                basePos = d.localFocalPoint - pos;
              },
              onScaleUpdate: (ScaleUpdateDetails d) {
                setState(() {
                  pos = d.localFocalPoint - basePos;
                });
              },
              child: Transform(
                transform: Matrix4.identity()..translate(pos.dx, pos.dy),
                alignment: Alignment.center,
                child: Container(
                   200,
                  height: 200,
                  color: Colors.red,
                ),
              ),
            ),
          ),
        );
      }
    }
    
  • 相关阅读:
    postgreSQL 时间线
    Using CSV-Format Log Output
    Understanding postgresql.conf : log*
    UNDERSTANDING POSTGRESQL.CONF: CHECKPOINT_SEGMENTS, CHECKPOINT_TIMEOUT, CHECKPOINT_WARNING
    PgSQL · 追根究底 · WAL日志空间的意外增长
    caffe源码学习
    Git 常用命令学习
    Linux系统的目录结构
    NMS 原理 了解
    nvidia-smi 查看GPU信息字段解读
  • 原文地址:https://www.cnblogs.com/ajanuw/p/13766881.html
Copyright © 2011-2022 走看看