Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e51c419
scrollFriction added to InteractiveViewer
frankteller-de Aug 12, 2022
b3b5763
Update interactive_viewer.dart
frankteller-de Aug 12, 2022
a2bfd15
Apply suggestions from code review
frankteller-de Aug 12, 2022
d2a7868
Update interactive_viewer.dart
frankteller-de Aug 12, 2022
15676ec
update
frankteller-de Aug 12, 2022
ca36786
update
frankteller-de Aug 12, 2022
0649892
* added _kDefaultScrollFrictionCoefficient
frankteller-de Aug 12, 2022
096a0e8
Merge branch 'flutter:master' into master
frankteller-de Aug 12, 2022
1544747
Update interactive_viewer_test.dart
frankteller-de Aug 12, 2022
4866626
scrollFrictionCoefficient test update
frankteller-de Aug 15, 2022
00e441b
Merge branch 'master' of https://github.com/codeforce-dev/flutter-v3.0.5
frankteller-de Aug 15, 2022
4d8f821
scrollFrictionCoefficient changed to interactionEndFrictionCoefficient
frankteller-de Aug 17, 2022
909322a
scrollFrictionCoefficient changed to interactionEndFrictionCoefficient
frankteller-de Aug 17, 2022
ee97fb9
update
frankteller-de Aug 17, 2022
9042a43
update
frankteller-de Aug 17, 2022
0577bd6
Update interactive_viewer.dart
frankteller-de Aug 19, 2022
6570d0f
interactionEndFrictionCoefficient test modified
frankteller-de Aug 19, 2022
75254f0
Merge branch 'flutter:master' into master
frankteller-de Aug 19, 2022
5fe26b0
update
frankteller-de Sep 20, 2022
1909afd
Merge branch 'flutter:master' into master
frankteller-de Sep 20, 2022
44eedfb
Merge branch 'master' of https://github.com/codeforce-dev/flutter-v3.0.5
frankteller-de Sep 20, 2022
ecb9837
Merge branch 'flutter:master' into master
frankteller-de Sep 20, 2022
bb43621
Update packages/flutter/lib/src/widgets/interactive_viewer.dart
Piinks Sep 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions packages/flutter/lib/src/widgets/interactive_viewer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class InteractiveViewer extends StatefulWidget {
// use cases.
this.maxScale = 2.5,
this.minScale = 0.8,
this.interactionEndFrictionCoefficient = _kDrag,
this.onInteractionEnd,
this.onInteractionStart,
this.onInteractionUpdate,
Expand All @@ -93,6 +94,7 @@ class InteractiveViewer extends StatefulWidget {
assert(constrained != null),
assert(minScale != null),
assert(minScale > 0),
assert(interactionEndFrictionCoefficient > 0),
assert(minScale.isFinite),
assert(maxScale != null),
assert(maxScale > 0),
Expand Down Expand Up @@ -131,6 +133,7 @@ class InteractiveViewer extends StatefulWidget {
// use cases.
this.maxScale = 2.5,
this.minScale = 0.8,
this.interactionEndFrictionCoefficient = _kDrag,
this.onInteractionEnd,
this.onInteractionStart,
this.onInteractionUpdate,
Expand All @@ -143,6 +146,7 @@ class InteractiveViewer extends StatefulWidget {
assert(builder != null),
assert(minScale != null),
assert(minScale > 0),
assert(interactionEndFrictionCoefficient > 0),
assert(minScale.isFinite),
assert(maxScale != null),
assert(maxScale > 0),
Expand Down Expand Up @@ -326,6 +330,13 @@ class InteractiveViewer extends StatefulWidget {
/// than maxScale.
final double minScale;

/// Changes the deceleration behavior after a gesture.
///
/// Defaults to 0.0000135.
///
/// Cannot be null, and must be a finite number greater than zero.
final double interactionEndFrictionCoefficient;

/// Called when the user ends a pan or scale gesture on the widget.
///
/// At the time this is called, the [TransformationController] will have
Expand Down Expand Up @@ -408,6 +419,10 @@ class InteractiveViewer extends StatefulWidget {
/// * [TextEditingController] for an example of another similar pattern.
final TransformationController? transformationController;

// Used as the coefficient of friction in the inertial translation animation.
// This value was eyeballed to give a feel similar to Google Photos.
static const double _kDrag = 0.0000135;

/// Returns the closest point to the given point on the given line segment.
@visibleForTesting
static Vector3 getNearestPointOnLine(Vector3 point, Vector3 l1, Vector3 l2) {
Expand Down Expand Up @@ -549,10 +564,6 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
// https://github.com/flutter/flutter/issues/57698
final bool _rotateEnabled = false;

// Used as the coefficient of friction in the inertial translation animation.
// This value was eyeballed to give a feel similar to Google Photos.
static const double _kDrag = 0.0000135;

// The _boundaryRect is calculated by adding the boundaryMargin to the size of
// the child.
Rect get _boundaryRect {
Expand Down Expand Up @@ -913,18 +924,18 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
final Vector3 translationVector = _transformationController!.value.getTranslation();
final Offset translation = Offset(translationVector.x, translationVector.y);
final FrictionSimulation frictionSimulationX = FrictionSimulation(
_kDrag,
widget.interactionEndFrictionCoefficient,
translation.dx,
details.velocity.pixelsPerSecond.dx,
);
final FrictionSimulation frictionSimulationY = FrictionSimulation(
_kDrag,
widget.interactionEndFrictionCoefficient,
translation.dy,
details.velocity.pixelsPerSecond.dy,
);
final double tFinal = _getFinalTime(
details.velocity.pixelsPerSecond.distance,
_kDrag,
widget.interactionEndFrictionCoefficient,
);
_animation = Tween<Offset>(
begin: translation,
Expand Down
56 changes: 56 additions & 0 deletions packages/flutter/test/widgets/interactive_viewer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,62 @@ void main() {
expect(scaleHighZoomedIn, greaterThan(scaleHighZoomedOut));
expect(scaleHighZoomedIn - scaleHighZoomedOut, lessThan(scaleZoomedIn - scaleZoomedOut));
});

testWidgets('interactionEndFrictionCoefficient', (WidgetTester tester) async {
// Use the default interactionEndFrictionCoefficient.
final TransformationController transformationController1 = TransformationController();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: SizedBox(
width: 200,
height: 200,
child: InteractiveViewer(
constrained: false,
transformationController: transformationController1,
child: const SizedBox(width: 2000.0, height: 2000.0),
),
),
),
),
);

expect(transformationController1.value, equals(Matrix4.identity()));

await tester.flingFrom(const Offset(100, 100), const Offset(0, -50), 100.0);
await tester.pumpAndSettle();
final Vector3 translation1 = transformationController1.value.getTranslation();
expect(translation1.y, lessThan(-58.0));

// Next try a custom interactionEndFrictionCoefficient.
final TransformationController transformationController2 = TransformationController();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: SizedBox(
width: 200,
height: 200,
child: InteractiveViewer(
constrained: false,
interactionEndFrictionCoefficient: 0.01,
transformationController: transformationController2,
child: const SizedBox(width: 2000.0, height: 2000.0),
),
),
),
),
);

expect(transformationController2.value, equals(Matrix4.identity()));

await tester.flingFrom(const Offset(100, 100), const Offset(0, -50), 100.0);
await tester.pumpAndSettle();
final Vector3 translation2 = transformationController2.value.getTranslation();

// The coefficient 0.01 is greater than the default of 0.0000135,
// so the translation comes to a stop more quickly.
expect(translation2.y, lessThan(translation1.y));
});
});

group('getNearestPointOnLine', () {
Expand Down