放大后偏移的问题)

发布于 2025-02-08 07:37:06 字数 4118 浏览 0 评论 0原文

我使用transform.scale()窗口小部件和zum和draw函数的custompaint()窗口小部件。

我要放大或缩小并进行自定义绘画 但是,如果我更改缩放刻度以放大或缩小并绘制,则该线将在其他地方输出。

以下是当我在同一位置处采用默认缩放和2x缩放之间的偏移差。

Offset(595,417) // zoom x1.0
Offset(595,471) // zoom x2.0

随着远离屏幕中间,这种差异变得更大。 下图是缩放的,比例= 2。在该状态下,当我绘制(图像框)时,它是在我拖动的其他位置上打印的。

即使更改量表后,如何使偏移值保持恒定?

以下是我的代码

绘制屏幕窗口窗口

      // zoom and translate screen
      return Transform.translate(
        offset: offset + sessionOffset, // moving
        child: Transform.scale(
          scale: scale, 
          child: Stack(
            children: [
              // allLines
              buildAllPaths(allLines: allLines),

              // new drawing line (onUpdate)
              buildCurrentPath(
                allLines: allLines,
                currentLine: currentLine,
              ),
            ],
          ),
        ),
      );

代码

  Widget buildCurrentPath({
    required List<DrawingModel> allLines,
    DrawingModel? currentLine,
  }) {
    return GestureDetector(
      onScaleStart: (details) {
    RenderBox box = context.findRenderObject() as RenderBox;
    // zoom scale and session offset (moving offset)
    double scale = context.read<DrawProvider>().scale;
    Offset offset = context.read<DrawProvider>().offset;
    Offset sessionOffset = context.read<DrawProvider>().sessionOffset;
    Offset translateOffset = offset + sessionOffset;

    if (_isZoom) {
      context.read<DrawProvider>().onScaleStart(details);
    } else if (_isUseTool) {
      if (tool == Tool.pen) {
        Offset point = box.globalToLocal(details.focalPoint);
        // calculation moving offset
        point = Offset(
          (point.dx - translateOffset.dx), 
          (point.dy - translateOffset.dy),
        );

       // TODO add scale calculation
      }
    }
  },

  onScaleUpdate: (details) {
    RenderBox box = context.findRenderObject() as RenderBox;
    // zoom scale and session offset (moving offset)
    double scale = context.read<DrawProvider>().scale;
    Offset offset = context.read<DrawProvider>().offset;
    Offset sessionOffset = context.read<DrawProvider>().sessionOffset;
    Offset translateOffset = offset + sessionOffset;

    if (_isZoom) {
      context.read<DrawProvider>().onScaleUpdate(details);
    } else if (_isUseTool) {
      if (tool == Tool.pen) {
        Offset point = box.globalToLocal(details.focalPoint); 
        point = Offset(
          (point.dx - translateOffset.dx), 
          (point.dy - translateOffset.dy),
        );
      }
    }
  },

  onScaleEnd: (details) {
    if (_isZoom) {
      context.read<DrawProvider>().onScaleEnd(details);
    } 
  },

  child: RepaintBoundary(
    child: Container(
      width: 1200,
      height: 1200,
      decoration: BoxDecoration(
        color: Colors.transparent,
      ),
      child: StreamBuilder<Shape>(
          stream: currentLineStreamController.stream,
          builder: (context, snapshot) {
            // add null check
            // (shape != null
            if (snapshot.hasData) {
              return CustomPaint(
                painter: Sketcher(shapes),
              );
            }

            // Not yet Draw
            return Container();
          }),
    ),
  )

zoom函数

class DrawProvider extends ChangeNotifier {
  Offset _offset = Offset.zero;
  Offset _initialFocalPoint = Offset.zero;
  Offset _sessionOffset = Offset.zero;
  double _scale = 1.0;
  double _initialScale = 1.0;

  void onScaleStart(ScaleStartDetails details) {
  _initialFocalPoint = details.focalPoint;
  _initialScale = _scale;
  notifyListeners();
 }

  void onScaleUpdate(ScaleUpdateDetails details) {
    _sessionOffset = details.focalPoint - _initialFocalPoint;
    _scale = _initialScale * details.scale;
    notifyListeners();
  }

  void onScaleEnd(ScaleEndDetails details) {
    _offset += _sessionOffset; 
    _sessionOffset = Offset.zero;
    notifyListeners();
  }
}

getruestector 的一部分。

I use the Transform.scale() widget and the CustomPaint() widget for zoom and draw functions.

I'm going to zoom in or out and do custom painting
However, if I change the scale to Zoom In or Zoom Out and draw, the line is output elsewhere.

The following is the offset difference between the default zoom and the 2x zoom when I draw point is taken in the same position.

Offset(595,417) // zoom x1.0
Offset(595,471) // zoom x2.0

And this difference gets bigger as move away from the middle of the screen.
The image below is Zoom In with scale = 2. And in that state, when I drawing(the box of images), it is printed on a different position I dragged.

How can I keep the offset value constant even after changing the scale?

The following is part of my code

draw screen widget

      // zoom and translate screen
      return Transform.translate(
        offset: offset + sessionOffset, // moving
        child: Transform.scale(
          scale: scale, 
          child: Stack(
            children: [
              // allLines
              buildAllPaths(allLines: allLines),

              // new drawing line (onUpdate)
              buildCurrentPath(
                allLines: allLines,
                currentLine: currentLine,
              ),
            ],
          ),
        ),
      );

GestureDetector code

  Widget buildCurrentPath({
    required List<DrawingModel> allLines,
    DrawingModel? currentLine,
  }) {
    return GestureDetector(
      onScaleStart: (details) {
    RenderBox box = context.findRenderObject() as RenderBox;
    // zoom scale and session offset (moving offset)
    double scale = context.read<DrawProvider>().scale;
    Offset offset = context.read<DrawProvider>().offset;
    Offset sessionOffset = context.read<DrawProvider>().sessionOffset;
    Offset translateOffset = offset + sessionOffset;

    if (_isZoom) {
      context.read<DrawProvider>().onScaleStart(details);
    } else if (_isUseTool) {
      if (tool == Tool.pen) {
        Offset point = box.globalToLocal(details.focalPoint);
        // calculation moving offset
        point = Offset(
          (point.dx - translateOffset.dx), 
          (point.dy - translateOffset.dy),
        );

       // TODO add scale calculation
      }
    }
  },

  onScaleUpdate: (details) {
    RenderBox box = context.findRenderObject() as RenderBox;
    // zoom scale and session offset (moving offset)
    double scale = context.read<DrawProvider>().scale;
    Offset offset = context.read<DrawProvider>().offset;
    Offset sessionOffset = context.read<DrawProvider>().sessionOffset;
    Offset translateOffset = offset + sessionOffset;

    if (_isZoom) {
      context.read<DrawProvider>().onScaleUpdate(details);
    } else if (_isUseTool) {
      if (tool == Tool.pen) {
        Offset point = box.globalToLocal(details.focalPoint); 
        point = Offset(
          (point.dx - translateOffset.dx), 
          (point.dy - translateOffset.dy),
        );
      }
    }
  },

  onScaleEnd: (details) {
    if (_isZoom) {
      context.read<DrawProvider>().onScaleEnd(details);
    } 
  },

  child: RepaintBoundary(
    child: Container(
      width: 1200,
      height: 1200,
      decoration: BoxDecoration(
        color: Colors.transparent,
      ),
      child: StreamBuilder<Shape>(
          stream: currentLineStreamController.stream,
          builder: (context, snapshot) {
            // add null check
            // (shape != null
            if (snapshot.hasData) {
              return CustomPaint(
                painter: Sketcher(shapes),
              );
            }

            // Not yet Draw
            return Container();
          }),
    ),
  )

Zoom Functions

class DrawProvider extends ChangeNotifier {
  Offset _offset = Offset.zero;
  Offset _initialFocalPoint = Offset.zero;
  Offset _sessionOffset = Offset.zero;
  double _scale = 1.0;
  double _initialScale = 1.0;

  void onScaleStart(ScaleStartDetails details) {
  _initialFocalPoint = details.focalPoint;
  _initialScale = _scale;
  notifyListeners();
 }

  void onScaleUpdate(ScaleUpdateDetails details) {
    _sessionOffset = details.focalPoint - _initialFocalPoint;
    _scale = _initialScale * details.scale;
    notifyListeners();
  }

  void onScaleEnd(ScaleEndDetails details) {
    _offset += _sessionOffset; 
    _sessionOffset = Offset.zero;
    notifyListeners();
  }
}

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

御弟哥哥 2025-02-15 07:37:07

发生的事情将更有帮助,

如果您能在该问题上放一些图片,我认为了解最终

请参见https://api.flutter.dev/flutter.flutter/widgets/interactiveviewer-- class.html“ rel =” nofollow noreferrer“> InteractiveViewer

if u can put some pic's of that issue i think it will be more helpful to understand what's go's on

in the end see this may help u

InteractiveViewer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文