Skip to content

Instantly share code, notes, and snippets.

@brianp
Created October 19, 2023 20:51
Show Gist options
  • Select an option

  • Save brianp/18230cc7244a3416b878e31132b7f690 to your computer and use it in GitHub Desktop.

Select an option

Save brianp/18230cc7244a3416b878e31132b7f690 to your computer and use it in GitHub Desktop.
fascinating-lantern-0546

fascinating-lantern-0546

Created with <3 with dartpad.dev.

import 'package:flutter/material.dart';
import '../common/logging.dart';
import 'dimension_preview.dart';
const _logTarget = "widget::scalable_dimension_wrapper";
class ScalableDimensionWrapper extends StatefulWidget {
final DimensionPreview child;
const ScalableDimensionWrapper({super.key, required this.child});
@override
_ScalableDimensionWrapperState createState() =>
_ScalableDimensionWrapperState();
}
class _ScalableDimensionWrapperState extends State<ScalableDimensionWrapper> {
double _scale = 1.0;
double _initialScale = 1.0; // Initial scale factor
Offset _position = const Offset(0.0, 0.0);
Offset _initialFocalPoint = const Offset(0.0, 0.0);
Offset _initialPosition = const Offset(0.0, 0.0);
// Define the bounding box for your containing area
double boundingBoxWidth = 200.0;
double boundingBoxHeight = 200.0;
@override
Widget build(BuildContext context) {
return Positioned(
left: _position.dx,
top: _position.dy,
child: Transform.scale(
scale: _scale,
child: GestureDetector(
onScaleStart: (details) {
_initialFocalPoint = details.localFocalPoint;
_initialPosition = _position;
},
onScaleUpdate: (ScaleUpdateDetails details) {
setState(() {
var key = widget.child.key as GlobalKey;
var box = key.currentContext!.findRenderObject() as RenderBox;
// Calculate the new scale based on the initial scale and the zoom factor
double newScale = _initialScale * details.scale;
// Ensure the scaling stays within a reasonable range
newScale = newScale.clamp(0.2, 2.0);
// Calculate the new position
Offset newPosition = _initialPosition +
(details.localFocalPoint - _initialFocalPoint);
// Calculate the effective size of the box considering scaling
double boxWidth = box.size.width * newScale;
double boxHeight = box.size.height * newScale;
// Ensure the item does not move outside the bounding box
newPosition = Offset(
newPosition.dx.clamp(0.0, boundingBoxWidth - boxWidth),
newPosition.dy.clamp(0.0, boundingBoxHeight - boxHeight),
);
// Update the scale factor and position
_scale = newScale;
_position = newPosition;
});
},
onScaleEnd: (details) {
logger.finest("$_logTarget updating position: '$_position'");
logger.finest("$_logTarget updating scale: '$_initialScale'");
// Save the current scale factor as the initial scale for the next interaction
_initialScale = _scale;
},
child: widget.child,
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment