aves/lib/widgets/common/magnifier/scale/scale_boundaries.dart
Thibault Deckers 0124d5fa17 set wallpaper
2022-06-09 19:35:09 +09:00

92 lines
3 KiB
Dart

import 'dart:math';
import 'dart:ui';
import 'package:aves/widgets/common/magnifier/controller/controller.dart';
import 'package:aves/widgets/common/magnifier/scale/scale_level.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
/// Internal class to wrap custom scale boundaries (min, max and initial)
/// Also, stores values regarding the two sizes: the container and the child.
@immutable
class ScaleBoundaries extends Equatable {
final bool _allowOriginalScaleBeyondRange;
final ScaleLevel _minScale;
final ScaleLevel _maxScale;
final ScaleLevel _initialScale;
final Size viewportSize;
final Size childSize;
@override
List<Object?> get props => [_allowOriginalScaleBeyondRange, _minScale, _maxScale, _initialScale, viewportSize, childSize];
const ScaleBoundaries({
required bool allowOriginalScaleBeyondRange,
required ScaleLevel minScale,
required ScaleLevel maxScale,
required ScaleLevel initialScale,
required this.viewportSize,
required this.childSize,
}) : _allowOriginalScaleBeyondRange = allowOriginalScaleBeyondRange,
_minScale = minScale,
_maxScale = maxScale,
_initialScale = initialScale;
ScaleBoundaries copyWith({
Size? childSize,
}) {
return ScaleBoundaries(
allowOriginalScaleBeyondRange: _allowOriginalScaleBeyondRange,
minScale: _minScale,
maxScale: _maxScale,
initialScale: _initialScale,
viewportSize: viewportSize,
childSize: childSize ?? this.childSize,
);
}
double _scaleForLevel(ScaleLevel level) {
final factor = level.factor;
switch (level.ref) {
case ScaleReference.contained:
return factor * ScaleLevel.scaleForContained(viewportSize, childSize);
case ScaleReference.covered:
return factor * ScaleLevel.scaleForCovering(viewportSize, childSize);
case ScaleReference.absolute:
default:
return factor;
}
}
double get originalScale => 1.0 / window.devicePixelRatio;
double get minScale => {
_scaleForLevel(_minScale),
_allowOriginalScaleBeyondRange ? originalScale : double.infinity,
initialScale,
}.fold(double.infinity, min);
double get maxScale => {
_scaleForLevel(_maxScale),
_allowOriginalScaleBeyondRange ? originalScale : double.negativeInfinity,
initialScale,
}.fold(0, max);
double get initialScale => _scaleForLevel(_initialScale);
Offset get _viewportCenter => viewportSize.center(Offset.zero);
Offset get _childCenter => childSize.center(Offset.zero);
Offset viewportToStatePosition(MagnifierController controller, Offset viewportPosition) {
return viewportPosition - _viewportCenter - controller.position;
}
Offset viewportToChildPosition(MagnifierController controller, Offset viewportPosition) {
return viewportToStatePosition(controller, viewportPosition) / controller.scale! + _childCenter;
}
Offset childToStatePosition(double scale, Offset childPosition) {
return (_childCenter - childPosition) * scale;
}
}