- 作者:老汪软件技巧
- 发表时间:2024-11-30 15:04
- 浏览量:86
前言
最近写flutter的时候,突然看到一个熟悉又陌生的组件,Magnifier 放大镜,没想到的是在使用flutter开发这一年半的时间里面都没用过一次,当即就去写了一个demo,发现Magnifier其实是调用了RawMagnifier 阅读了一下源码看到放大效果实现其实是用了Matrix4..scale(magnificationScale)..translate(dynamic x, [double y = 0.0, double z = 0.0, ])来进行放大和位移的。到这里我就想我能用自己的方式实现一个放大镜功能吗,那么让我们打开vscode开干吧。
先上实现后的效果
实现过程
获取屏幕坐标offset我们使用Listener的onPointerMove当手势在屏幕上移动时会触发该方法,我们就能知道坐标最新位置了
/// update pointer move event
void updatePointerMoveEvent(
PointerMoveEvent event, double maxHeight, double maxWidth) {
final offsetData = event.localPosition;
var dy = offsetData.dy > maxHeight ? maxHeight : offsetData.dy;
var dx = offsetData.dx > maxWidth ? maxWidth : offsetData.dx;
dy = dy < 0 ? 0 : dy;
dx = dx < 0 ? 0 : dx;
offset.value = Offset(dx, dy);
}
当获取的坐标大于我组件的大小时候,我们就需要让他不超过我们设定的大小。
获取坐标后,我们要实现放大镜跟随效果使用Transform.translate来设置坐标。这里设置的是放大镜的右下角为放大坐标
/// update magnifier offset
Offset updateMagnifierOffset(double dx, double dy, Size magnifierSize) {
var dxOffset = dx - magnifierSize.width;
var dyOffset = dy - magnifierSize.height;
dyOffset = dyOffset < 0 ? 0 : dyOffset;
dxOffset = dxOffset < 0 ? 0 : dxOffset;
return Offset(dxOffset, dyOffset);
}
如何做到放大倍数呢。我这里使用了Stack + Transform.scale
Stack第一层存放我们的原始内容,第二层放置我们使用Transform.scale 放大后的内容。接下来只需要进行区域裁切和修改第二层的坐标就能实现了
ClipRRect(
child: Transform.scale(
scale: widget.magnification,
child: Transform.translate(
offset: _updateTransformTranslateOffset(
dx: dx, dy: dy, childSize: childSize),
child: OverflowBox(
minWidth:
childSize.width + widget.magnifierSize.width / 2,
maxWidth:
childSize.width + widget.magnifierSize.width / 2,
minHeight:
childSize.height + widget.magnifierSize.width / 2,
maxHeight:
childSize.height + widget.magnifierSize.width / 2,
child: widget.child,
),
),
),
)
最后
不知不觉已经进入群聊 FlutterCandies 近一年这一年里面,学习到了好多新姿势(知识),尤其是群主说话又好听 FlutterCandies 全家桶又好用,我超喜欢在里面的。如果你也喜欢flutter那么加入我们,一起学习将会开挂一样的进步。
项目地址
/7-bit11/flu…