editor: dynamic padding
This commit is contained in:
parent
8fe267d345
commit
5c297c1daf
2 changed files with 48 additions and 8 deletions
|
@ -90,7 +90,7 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
|
||||||
|
|
||||||
void _registerWidget(Cropper widget) {
|
void _registerWidget(Cropper widget) {
|
||||||
_subscriptions.add(widget.magnifierController.stateStream.listen(_onViewStateChanged));
|
_subscriptions.add(widget.magnifierController.stateStream.listen(_onViewStateChanged));
|
||||||
_subscriptions.add(widget.magnifierController.scaleBoundariesStream.map((v) => v.viewportSize).listen(_onViewportSizeChanged));
|
_subscriptions.add(widget.magnifierController.scaleBoundariesStream.map((v) => v.viewportSize).distinct().listen(_onViewportSizeChanged));
|
||||||
_subscriptions.add(widget.transformController.activityStream.listen(_onTransformActivity));
|
_subscriptions.add(widget.transformController.activityStream.listen(_onTransformActivity));
|
||||||
_subscriptions.add(widget.transformController.transformationStream.map((v) => v.orientation).distinct().listen(_onOrientationChanged));
|
_subscriptions.add(widget.transformController.transformationStream.map((v) => v.orientation).distinct().listen(_onOrientationChanged));
|
||||||
_subscriptions.add(widget.transformController.transformationStream.map((v) => v.straightenDegrees).distinct().listen(_onStraightenDegreesChanged));
|
_subscriptions.add(widget.transformController.transformationStream.map((v) => v.straightenDegrees).distinct().listen(_onStraightenDegreesChanged));
|
||||||
|
@ -454,13 +454,41 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
|
||||||
if (boundaries != null) {
|
if (boundaries != null) {
|
||||||
magnifierController.setScaleBoundaries(
|
magnifierController.setScaleBoundaries(
|
||||||
boundaries.copyWith(
|
boundaries.copyWith(
|
||||||
padding: const EdgeInsets.all(double.infinity),
|
padding: _getBoundariesPadding,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_showRegion();
|
_showRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EdgeInsets _getBoundariesPadding(double scale) {
|
||||||
|
// TODO TLAD handle orientation
|
||||||
|
if (transformation.orientation != TransformOrientation.normal) {
|
||||||
|
return const EdgeInsets.all(double.infinity);
|
||||||
|
}
|
||||||
|
// TODO TLAD handle straightening
|
||||||
|
if (transformation.straightenDegrees != 0) {
|
||||||
|
return const EdgeInsets.all(double.infinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
final viewState = _getViewState();
|
||||||
|
if (viewState != null) {
|
||||||
|
final viewportSize = viewState.viewportSize;
|
||||||
|
final contentSize = viewState.contentSize;
|
||||||
|
if (viewportSize != null && contentSize != null) {
|
||||||
|
final fullRegion = CropRegion.fromRect(Offset.zero & contentSize);
|
||||||
|
final fullOutline = _containingOutlineFromRegion(viewState, fullRegion);
|
||||||
|
final cropOutline = _outlineNotifier.value;
|
||||||
|
|
||||||
|
final paddingWidth = max(0.0, (min(fullOutline.width, viewportSize.width) - cropOutline.width) / 2);
|
||||||
|
final paddingHeight = max(0.0, (min(fullOutline.height, viewportSize.height) - cropOutline.height) / 2);
|
||||||
|
return EdgeInsets.symmetric(vertical: paddingHeight, horizontal: paddingWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EdgeInsets.zero;
|
||||||
|
}
|
||||||
|
|
||||||
ViewState? _getViewState() {
|
ViewState? _getViewState() {
|
||||||
final scaleBoundaries = magnifierController.scaleBoundaries;
|
final scaleBoundaries = magnifierController.scaleBoundaries;
|
||||||
if (scaleBoundaries == null) return null;
|
if (scaleBoundaries == null) return null;
|
||||||
|
@ -560,6 +588,16 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
|
||||||
return clampedRegion;
|
return clampedRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect _containingOutlineFromRegion(ViewState viewState, CropRegion region) {
|
||||||
|
final regionToOutlineMatrix = _getRegionToOutlineMatrix(viewState);
|
||||||
|
final points = region.corners.map(regionToOutlineMatrix.transformOffset).toList();
|
||||||
|
final dxSet = points.map((v) => v.dx).toSet();
|
||||||
|
final dySet = points.map((v) => v.dy).toSet();
|
||||||
|
final topLeft = Offset(dxSet.reduce(min), dySet.reduce(min));
|
||||||
|
final bottomRight = Offset(dxSet.reduce(max), dySet.reduce(max));
|
||||||
|
return Rect.fromPoints(topLeft, bottomRight);
|
||||||
|
}
|
||||||
|
|
||||||
Rect _containedOutlineFromRegion(ViewState viewState, CropRegion region) {
|
Rect _containedOutlineFromRegion(ViewState viewState, CropRegion region) {
|
||||||
final regionToOutlineMatrix = _getRegionToOutlineMatrix(viewState);
|
final regionToOutlineMatrix = _getRegionToOutlineMatrix(viewState);
|
||||||
final points = region.corners.map(regionToOutlineMatrix.transformOffset).toList();
|
final points = region.corners.map(regionToOutlineMatrix.transformOffset).toList();
|
||||||
|
|
|
@ -16,7 +16,7 @@ class ScaleBoundaries extends Equatable {
|
||||||
final ScaleLevel _initialScale;
|
final ScaleLevel _initialScale;
|
||||||
final Size viewportSize;
|
final Size viewportSize;
|
||||||
final Size contentSize;
|
final Size contentSize;
|
||||||
final EdgeInsets padding;
|
final EdgeInsets Function(double scale)? padding;
|
||||||
final Matrix4? externalTransform;
|
final Matrix4? externalTransform;
|
||||||
|
|
||||||
static const Alignment basePosition = Alignment.center;
|
static const Alignment basePosition = Alignment.center;
|
||||||
|
@ -31,7 +31,7 @@ class ScaleBoundaries extends Equatable {
|
||||||
required ScaleLevel initialScale,
|
required ScaleLevel initialScale,
|
||||||
required this.viewportSize,
|
required this.viewportSize,
|
||||||
required this.contentSize,
|
required this.contentSize,
|
||||||
this.padding = EdgeInsets.zero,
|
this.padding,
|
||||||
this.externalTransform,
|
this.externalTransform,
|
||||||
}) : _allowOriginalScaleBeyondRange = allowOriginalScaleBeyondRange,
|
}) : _allowOriginalScaleBeyondRange = allowOriginalScaleBeyondRange,
|
||||||
_minScale = minScale,
|
_minScale = minScale,
|
||||||
|
@ -45,7 +45,7 @@ class ScaleBoundaries extends Equatable {
|
||||||
initialScale: ScaleLevel(ref: ScaleReference.contained),
|
initialScale: ScaleLevel(ref: ScaleReference.contained),
|
||||||
viewportSize: Size.zero,
|
viewportSize: Size.zero,
|
||||||
contentSize: Size.zero,
|
contentSize: Size.zero,
|
||||||
padding: EdgeInsets.zero,
|
padding: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
ScaleBoundaries copyWith({
|
ScaleBoundaries copyWith({
|
||||||
|
@ -55,7 +55,7 @@ class ScaleBoundaries extends Equatable {
|
||||||
ScaleLevel? initialScale,
|
ScaleLevel? initialScale,
|
||||||
Size? viewportSize,
|
Size? viewportSize,
|
||||||
Size? contentSize,
|
Size? contentSize,
|
||||||
EdgeInsets? padding,
|
EdgeInsets Function(double scale)? padding,
|
||||||
Matrix4? externalTransform,
|
Matrix4? externalTransform,
|
||||||
}) {
|
}) {
|
||||||
return ScaleBoundaries(
|
return ScaleBoundaries(
|
||||||
|
@ -115,7 +115,8 @@ class ScaleBoundaries extends Equatable {
|
||||||
|
|
||||||
final minX = ((positionX - 1).abs() / 2) * widthDiff * -1;
|
final minX = ((positionX - 1).abs() / 2) * widthDiff * -1;
|
||||||
final maxX = ((positionX + 1).abs() / 2) * widthDiff;
|
final maxX = ((positionX + 1).abs() / 2) * widthDiff;
|
||||||
return EdgeRange(minX - padding.left, maxX + padding.right);
|
final _padding = padding?.call(scale) ?? EdgeInsets.zero;
|
||||||
|
return EdgeRange(minX - _padding.left, maxX + _padding.right);
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeRange getYEdges({required double scale}) {
|
EdgeRange getYEdges({required double scale}) {
|
||||||
|
@ -127,7 +128,8 @@ class ScaleBoundaries extends Equatable {
|
||||||
|
|
||||||
final minY = ((positionY - 1).abs() / 2) * heightDiff * -1;
|
final minY = ((positionY - 1).abs() / 2) * heightDiff * -1;
|
||||||
final maxY = ((positionY + 1).abs() / 2) * heightDiff;
|
final maxY = ((positionY + 1).abs() / 2) * heightDiff;
|
||||||
return EdgeRange(minY - padding.top, maxY + padding.bottom);
|
final _padding = padding?.call(scale) ?? EdgeInsets.zero;
|
||||||
|
return EdgeRange(minY - _padding.top, maxY + _padding.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
double clampScale(double scale) {
|
double clampScale(double scale) {
|
||||||
|
|
Loading…
Reference in a new issue