Skip to content

Instantly share code, notes, and snippets.

@loic-hamdi
Last active January 30, 2022 19:03
Show Gist options
  • Save loic-hamdi/623531eef065a31470e85175c744c986 to your computer and use it in GitHub Desktop.
Save loic-hamdi/623531eef065a31470e85175c744c986 to your computer and use it in GitHub Desktop.
InteractiveViewerOverlay
import 'package:flutter/material.dart';
class InteractiveViewerOverlay extends StatefulWidget {
final Widget child;
final double maxScale;
const InteractiveViewerOverlay({
Key key,
@required this.child,
this.maxScale,
}) : super(key: key);
@override
_InteractiveViewerOverlayState createState() =>
_InteractiveViewerOverlayState();
}
class _InteractiveViewerOverlayState
extends State<InteractiveViewerOverlay>
with SingleTickerProviderStateMixin {
var viewerKey = GlobalKey();
Rect placeholder;
OverlayEntry entry;
var controller = TransformationController();
Matrix4Tween snapTween;
AnimationController snap;
@override
void initState() {
super.initState();
snap = AnimationController(vsync: this);
snap.addListener(() {
if (snapTween == null) return;
controller.value = snapTween.evaluate(snap);
if (snap.isCompleted) {
entry.remove();
entry = null;
setState(() {
placeholder = null;
});
}
});
}
@override
void dispose() {
snap.dispose();
super.dispose();
}
Widget buildViewer(BuildContext context) {
return InteractiveViewer(
key: viewerKey,
transformationController: controller,
panEnabled: false,
maxScale: widget.maxScale ?? 2.5,
child: widget.child,
onInteractionStart: (details) {
if (placeholder != null) return;
setState(() {
var renderObject =
viewerKey.currentContext.findRenderObject() as RenderBox;
placeholder = Rect.fromPoints(
renderObject.localToGlobal(Offset.zero),
renderObject
.localToGlobal(renderObject.size.bottomRight(Offset.zero)),
);
});
entry = OverlayEntry(
builder: (context) {
return Positioned.fromRect(
rect: placeholder,
child: buildViewer(context),
);
},
);
Overlay.of(context).insert(entry);
},
onInteractionEnd: (details) {
snapTween = Matrix4Tween(
begin: controller.value,
end: Matrix4.identity(),
);
snap.value = 0;
snap.animateTo(
1,
duration: Duration(milliseconds: 250),
curve: Curves.ease,
);
});
}
@override
Widget build(BuildContext context) {
var viewer = placeholder != null
? SizedBox.fromSize(size: placeholder.size)
: buildViewer(context);
return Card(
child: viewer,
clipBehavior: Clip.antiAlias,
);
}
}
@Lucho1976
Copy link

it doesn't do overlay, what can it be?

@alexrainman
Copy link

alexrainman commented Jan 30, 2022

It doesn't overlay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment