我正在用 flutter 编写,这是一个图像裁剪编辑器,我需要一个功能,让用户可以在缩放(捏缩放或鼠标滚动)时缩放和平移图像。我知道 Flutter 有像
InteractiveViewer
这样的小部件,但就我而言,我无法使用它。简化后的小部件如下所示:
Transform.scale(
scale: _zoomFactor,
alignment: Alignment.center,
child: Transform.translate(
offset: _translate,
child: Listener(
behavior: HitTestBehavior.translucent,
onPointerSignal: isDesktop ? _mouseScroll : null,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onScaleStart: _onScaleStart,
onScaleEnd: _onScaleEnd,
onScaleUpdate: _onScaleUpdate,
onDoubleTapDown: _handleDoubleTapDown,
onDoubleTap: _handleDoubleTap,
child: Image.network(
'https://picsum.photos/id/176/2000',
fit: BoxFit.contain,
),
),
),
),
);
现在的目标是,当用户缩放到某个点时,小部件应该缩放并变换到该点。 Transform.translate 部分有点棘手,感觉与其他图像编辑器相同。有谁知道这个函数应该是什么样子?如果有必要,您可以在 GitHub here 上查看完整代码和我当前的方法。
我终于自己找到了解决办法。我将其发布在下面,也许对其他人有帮助。
void _mouseScroll(PointerSignalEvent event) {
// Check if interaction is blocked
if (_blockInteraction) return;
if (event is PointerScrollEvent) {
// Define zoom factor and extract vertical scroll delta
double factor = 0.1;
double deltaY = event.scrollDelta.dy;
double startZoom = _userZoom;
double newZoom = _userZoom;
// Adjust zoom based on scroll direction
if (deltaY > 0) {
newZoom -= factor;
newZoom = max(1, newZoom);
} else if (deltaY < 0) {
newZoom += factor;
newZoom = min(7, newZoom);
}
// Get dimensions of the rendered image
double imgW = _renderedImgConstraints.maxWidth;
double imgH = _renderedImgConstraints.maxHeight;
// Calculate the transformed local position of the pointer
Offset transformedLocalPosition = event.localPosition * startZoom;
// Calculate the size of the transformed image
Size transformedImgSize = Size(
imgW * startZoom,
imgH * startZoom,
);
// Calculate the center offset point from the old zoomed view
Offset realHitPoint = Offset(
transformedLocalPosition.dx - transformedImgSize.width / 2,
transformedLocalPosition.dy - transformedImgSize.height / 2,
);
// Calculate the center offset point from the old zoomed view
Offset centerOffset = _translate + realHitPoint / startZoom;
// Calculate the center offset point from the new zoomed view
Offset centerZoomOffset = centerOffset * startZoom / newZoom;
// Update translation and zoom values
_translate -= centerOffset - centerZoomOffset;
_userZoom = newZoom;
// Set offset limits and trigger widget rebuild
_setOffsetLimits();
setState(() {});
}
}