首页 > 解决方案 > 如何通过触摸旋转颤振小部件

问题描述

我正在开发一个设计应用程序。该应用程序包括将照片添加为贴纸,我想在贴纸的角落里给贴纸四个按钮,其中一个按钮在右上角,如下图所示,它的工作是旋转贴纸,我想要贴纸随触摸位置旋转

在此处输入图像描述

我的代码:

import 'dart:io';
  import 'dart:math';
  
  import 'package:flutter/cupertino.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter/painting.dart';
  import 'package:flutter/rendering.dart';
  import 'package:flutter/widgets.dart';
  import 'dart:async';
  import 'package:matrix4_transform/matrix4_transform.dart';
  import 'package:quotessec/myWidgets/background.dart';
  
  class stickerOne extends StatefulWidget {
    Map style;
    StreamController<Map> streamController = StreamController<Map>.broadcast();
    dynamic drag;
    List<Map> styles;
    Function onSubmit;
    Function onTap;
    Function onValueChange;
    Function onDelete;
  
    stickerOne(
        {@required Key key,
        @required this.style,
        @required this.drag,
        @required this.styles,
        @required this.onSubmit,
        @required this.onTap,
        @required this.onValueChange,
        @required this.onDelete})
        : super(key: key);
  
    get getIndex => style['index'];
    get gisHidden => style['isHidden'];
    get getChild => style['child'];
    get getOffset => style['offset'];
    get isDeleted => style['isDeleted'];
    get sty => style;
    get str => streamController;
    get delete {
      styles.remove(style);
      return drag.remove(this);
    }
  
    set isHidden(isHidden) {
      print('hidden');
      style['isHidden'] = isHidden;
      streamController.add(style);
    }
  
  //  set delete(deleted) {
  //    style['isDeleted'] = true;
  //    streamController.add(style);
  //    drag.remove(this);
  //  }
  
    @override
    _stickerOneState createState() => _stickerOneState(
          style: style,
        );
  }
  
  class _stickerOneState extends State<stickerOne> {
    Map style;
    var stream;
    _stickerOneState({@required this.style});
  
    List<dynamic> sizes = [];
    @override
    void initState() {
      stream = widget.streamController.stream;
      super.initState();
      stream.listen((sty) {
        mySetState(sty);
      });
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
        setState(() {
          imageSizes();
        });
      });
    }
  
    mySetState(Map sty) {
      if (this.mounted) {
        setState(() {
          style = sty;
        });
      }
    }
  
    imageSizes() async {
      File image = style['child'];
      var decodedImage = await decodeImageFromList(image.readAsBytesSync());
      sizes = [decodedImage.height, decodedImage.width];
      if (decodedImage.height * .2 >= 100 && decodedImage.height * .2 >= 100) {
        style['height'] = double.tryParse(decodedImage.height.toString()) * .2;
        style['width'] = double.tryParse(decodedImage.width.toString()) * .2;
      } else if (decodedImage.height * .3 >= 100 &&
          decodedImage.height * .3 >= 100) {
        style['height'] = double.tryParse(decodedImage.height.toString()) * .3;
        style['width'] = double.tryParse(decodedImage.width.toString()) * .3;
      } else if (decodedImage.height * .4 >= 100 &&
          decodedImage.height * .4 >= 100) {
        style['height'] = double.tryParse(decodedImage.height.toString()) * .4;
        style['width'] = double.tryParse(decodedImage.width.toString()) * .4;
      } else {
        style['height'] = double.tryParse(decodedImage.height.toString()) * .5;
        style['width'] = double.tryParse(decodedImage.width.toString()) * .5;
      }
      setState(() {});
    }
  
    double minHeight;
    double minWidth;
    bool rotating = true;
    _onDragUpdate(BuildContext context, DragUpdateDetails update) {
      //print(update.globalPosition.toString());
      RenderBox getBox = context.findRenderObject();
      var local = getBox.getTransformTo(getBox);
      print(local);
      //print(local.dx.toString() + "|" + local.dy.toString());
    }
  
    double angle = 0.0;
    @override
    Widget build(BuildContext context) {
  
      return !style['isHidden'] && !style['isDeleted']
          ? Positioned(
            top: style['offset'].dy,
            left: style['offset'].dx,
            child: GestureDetector(
              onTap: () {
                if (!style['lock']) {
                  style['isEditing'] = true;
                  widget.streamController.add(style);
                  widget.styles.forEach((
                    element,
                  ) {
                    if (element['index'] != style['index'] &&
                        element['isEditing'] == true) {
                      setState(() {
                        widget.styles[widget.styles.indexWhere(
                                (ele) => element['index'] == ele['index'])]
                            ['isEditing'] = false;
                        widget.drag.forEach((element2) {
                          if (element2.runtimeType != background &&
                              element2.sty['index'] == element['index']) {
                            widget
                                .drag[widget.drag.indexWhere((ele2) =>
                                    ele2.runtimeType != background &&
                                    element2.sty['index'] ==
                                        ele2.sty['index'])]
                                .str
                                .add(widget.styles[element['index']]);
                          }
                        });
                      });
                    }
                  });
                  widget.onTap(style, widget.streamController);
                }
              },
              onPanUpdate: (details) {
                if (!style['lock']) {
                  setState(() {
                    style['offset'] = Offset(
                        style['offset'].dx + details.delta.dx,
                        style['offset'].dy + details.delta.dy);
                    print(style['offset']);
                  });
                }
              },
              child:Transform.rotate(
                angle: angle,
                child: Column(
                  children: [
                    style['isEditing']
                        ? Container(
                      width:style['width'] + 50,
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              mainAxisSize: MainAxisSize.max,
                              children: [
                                Transform(
                                  alignment: Alignment.center,
                                  transform: Matrix4Transform()
                                      .rotateDegrees(-45)
                                      .matrix4,
                                  child: GestureDetector(
                                    child: Container(
                                      decoration: BoxDecoration(
                                          color: Theme.of(context)
                                              .primaryColor,
                                          borderRadius:
                                              BorderRadius.circular(25)),
                                      child: Icon(Icons.arrow_upward,
                                          color: Theme.of(context)
                                              .accentColor),
                                    ),
                                    onPanUpdate: (details) {
                                      setState(() {
                                        print(details.delta.direction);
                                        if (details.delta.direction > 0) {
                                          if (style['height'] > 0.01 &&
                                              style['width'] > 0.01) {
                                            print('shrinking');
                                            style['height'] =
                                                style['height'] -
                                                    (.1 * style['height']);
                                            style['width'] =
                                                style['width'] -
                                                    (.1 * style['width']);
                                            print(style['height']);
                                          }
                                        } else {
                                          style['height'] =
                                              style['height'] +
                                                  (.1 * style['height']);
                                          style['width'] = style['width'] +
                                              (.1 * style['width']);
                                        }
                                      });
                                      widget.onValueChange(style);
                                      widget.streamController.add(style);
                                    },
                                  ),
                                ),
                                GestureDetector(
                                  child: Container(
                                      decoration: BoxDecoration(
                                          color: Theme.of(context)
                                              .primaryColor,
                                          borderRadius:
                                          BorderRadius.circular(25)),
                                    child: Icon(Icons.rotate_left,color: Theme.of(context)
                                        .accentColor,)
                                  ),
                                  onPanUpdate: (details){
                                    //I tried this but it did not work correctly
                                    Offset centerOfGestureDetector = Offset(
                                        style['offset'].dx / 2, style['offset'].dy / 2);
                                    final touchPositionFromCenter =
                                        details.localPosition - centerOfGestureDetector;
                                    print(touchPositionFromCenter.direction * pi / 180);
                                    setState(
                                          () {
                                        angle = touchPositionFromCenter.direction;
                                      },
                                    );
                                  },
                                ),
                              ],
                            ),
                          )
                        : Container(width: style['width'] + 50, height: 25),
                    Container(
                      height: style['height'],
                      width: style['width'],
                      decoration: BoxDecoration(
                        border: style['isEditing'] ? Border.all() : null,
                      ),
                      child: style['color'][0] != null &&
                              style['color'][1] != null
                          ? ShaderMask(
                              shaderCallback: (rect) {
                                return LinearGradient(
                                  colors: [
                                    style['color'][0],
                                    style['color'][1]
                                  ],
                                  begin: style['beginGradient'],
                                  end: style['endGradient'],
                                ).createShader(rect);
                              },
                              blendMode: BlendMode.srcATop,
                              child: Image.file(style['child'],
                                  height: style['height'],
                                  width: style['width']),
                            )
                          : ColorFiltered(
                              colorFilter: ColorFilter.mode(
                                  style['soledColor'] != null
                                      ? style['soledColor']
                                      : Colors.white,
                                  BlendMode.modulate),
                              child: Image.file(style['child'],
                                  height: style['height'],
                                  width: style['width'])),
                    ),
                    style['isEditing']
                        ? Container(
                            width: style['width'] + 50,
                            child: Row(
                              mainAxisSize: MainAxisSize.max,
                              mainAxisAlignment:
                                  MainAxisAlignment.spaceBetween,
                              children: [
                                GestureDetector(
                                  child: Container(
                                    decoration: BoxDecoration(
                                        color:
                                            Theme.of(context).primaryColor,
                                        borderRadius:
                                            BorderRadius.circular(25)),
                                    child: Icon(
                                      Icons.check,
                                      color: Theme.of(context).accentColor,
                                    ),
                                  ),
                                  onTap: () {
                                    style['isEditing'] = false;
                                    widget.streamController.add(style);
                                    widget.onSubmit(null);
                                  },
                                ),
                                GestureDetector(
                                  child: Container(
                                    decoration: BoxDecoration(
                                        color:
                                            Theme.of(context).primaryColor,
                                        borderRadius:
                                            BorderRadius.circular(25)),
                                    child: Icon(
                                      Icons.control_camera,
                                      color: Theme.of(context).accentColor,
                                    ),
                                  ),
                                  onPanUpdate: (details) {
                                    setState(() {
                                      style['offset'] = Offset(
                                          style['offset'].dx +
                                              details.delta.dx,
                                          style['offset'].dy +
                                              details.delta.dy);
                                    });
                                    //print(style['offset']);
                                  },
                                ),
                              ],
                            ),
                          )
                        : Container(width: style['width'] + 50, height: 25)
                  ],
                ),
              ),
          ))
          : Container();
    }
  }

标签: flutterdartflutter-layout

解决方案


推荐阅读