如何在颤动中从元素中心旋转堆栈?

时间:2020-10-14 05:14:24

标签: flutter dart transform

我有以下代码:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:math' as math;

void main() {
  debugPaintSizeEnabled = true;
  return runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.grey,
        body: SafeArea(
          child: ImageRotate(),
        ),
      ),
    );
  }
}

class ImageRotate extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Transform.rotate(
      angle: (math.pi / 180) * 45,
      child: Stack(
        children: [
          Positioned(
            top: 100,
            left: 50,
            child: Image.network(
              "https://via.placeholder.com/300x200",
              height: 200,
              width: 300,
            ),
          ),
        ],
      ),
    );
  }
}

现在我期望的是像这样从图像中心执行旋转,

enter image description here

相反,它像这样旋转

enter image description here

我还尝试研究变换原点。但是我自己弄不清原点的偏移量。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

尝试获取图像的位置时方向正确(您还需要它的大小才能旋转 center 的功能)。

为此,颤动的经典方法是使用键。 这是您使用此方法的问题:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:math' as math;

void main() {
  debugPaintSizeEnabled = true;
  return runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: Scaffold(
          backgroundColor: Colors.grey,
          body: ImageRotate(),
        ),
      ),
    );
  }
}

class ImageRotate extends StatefulWidget {
  @override
  _ImageRotateState createState() => _ImageRotateState();
}

class _ImageRotateState extends State<ImageRotate> {
  final GlobalKey imageKey = GlobalKey();
  Size imageSize = Size(0, 0);
  Offset imagePos = Offset.zero;

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      imageSize = (imageKey.currentContext.findRenderObject() as RenderBox).size;
      imagePos =
          (imageKey.currentContext.findRenderObject() as RenderBox).localToGlobal(Offset.zero);
      setState(() {});
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    print(imagePos);
    print(imageSize);
    return Transform.rotate(
      angle: imagePos == Offset.zero ? 0 : (math.pi / 180) * 45,
      origin:
          -Offset(MediaQuery.of(context).size.width, MediaQuery.of(context).size.height) / 2 +
              (imagePos + Offset(imageSize.width / 2, imageSize.height / 2)),
      child: Stack(
        children: [
          Positioned(
            top: 200,
            left: 300,
            child: Image.network(
              "https://via.placeholder.com/300x200",
              key: imageKey,
              height: 100,
              width: 100,
            ),
          ),
        ],
      ),
    );
  }
}

微积分的解释:原点是中心的偏移量。这就是为什么您必须将其移动-Offset(MediaQuery.of(context).size.width, MediaQuery.of(context).size.height)/2。它将中心放置在屏幕的左上方。然后移动到图像的中心,因此在这里使用从GlobalKey获得的尺寸:(imagePos + Offset(imageSize.width / 2, imageSize.height / 2))

imagePos == Offset.zero ? 0 : (math.pi / 180) * 45说明:当图像不旋转时,您必须首先获取图像的位置,因此首先将旋转度设置为零,然后计算imagePos,然后您可以应用所需的旋转角度。