Skip to content

Conversation

@frankteller-de
Copy link
Contributor

@frankteller-de frankteller-de commented Aug 12, 2022

It would be nice if the kDrag parameter were public to change the scrolling behavior.

For example I've changed the kDrag var into a public parameter called scrollFriction.

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • All existing and new tests are passing.

@flutter-dashboard flutter-dashboard bot added the framework flutter/packages/flutter repository. See also f: labels. label Aug 12, 2022
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@google-cla
Copy link

google-cla bot commented Aug 12, 2022

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Comment on lines 303 to 310
/// Changes the scrolling behavior after end of a gesture.
///
/// Used as the coefficient of friction in the inertial translation animation.
/// This value was eyeballed to give a feel similar to Google Photos.
///
/// Defaults to 0.0000135.
///
/// Cannot be null, and must be a finite number greater than zero
Copy link
Contributor

@alestiago alestiago Aug 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add documentation on how the scroll changes when the value increases or decreases?

@alestiago
Copy link
Contributor

I agree with this change, it would be nice if the constant internal value could be changed. I think the solution is quite simple. Thanks for raising the PR!

I just added small nit comments regarding naming and documentation, overall looks good to me. Are you planning to add tests?

@frankteller-de
Copy link
Contributor Author

Thank you @alestiago! I can add some tests but first I have to look at the documentation what I have to do to add a test. It was my first PR.

frankteller-de and others added 6 commits August 12, 2022 13:48
scrollFriction renamed to scrollFrictionCoefficient

Co-authored-by: Alejandro Santiago <dev@alestiago.com>
rename scrollFriction
@frankteller-de
Copy link
Contributor Author

I've added a test but I don't know what I should test exactly. That parameter is very random.

@alestiago
Copy link
Contributor

alestiago commented Aug 12, 2022

You could test how the amount of scroll differs when a value x is provided compared to when a value y is given.

@HansMuller HansMuller requested a review from justinmc August 12, 2022 22:14
Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this PR, I'm on board but I want to make sure there's not a more generic way to solve this.

This makes me think of Scrollable's physics parameter. What if we allowed users to pass in the entire Simulation and defaulted to the current FrictionSimulation? Or even more high level, maybe InteractiveViewer should be using ScrollPhysics?

@Piinks You're working on 2D scrolling, are you using regular ScrollPhysics for that, or is there anything that could also apply here?

I'm not saying that scrollFrictionCoefficient isn't the best solution here, I just want to think through these other options.

@alestiago
Copy link
Contributor

alestiago commented Aug 13, 2022

I agree with @justinmc making use of a subclass of ScrollPhysics to achieve the effect is an interesting and more consistent solution with the framework and other Scrollables. Definitely a great suggestion!

I'm also glad to hear @justinmc is onboard with the aims of this PR. Thanks for hopping in 💙

I'm curious about @Piinks insights and opinion on this PR to 👀

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to incorporate more scrolling into interactive viewer, but I think it is more complicated than adding some properties that emulate scrolling. I've been exploring this in #64210. Ultimately, under the hood InteractiveViewer is not a scrolling widget. We may be able to rework it to become one, but that may require breaking changes, which is why I have been working on a separate 2D scrollable that would avoid breaking existing code.

I don't think adding this is a bad idea, I would just avoid referring to it as scrolling.

// use cases.
this.maxScale = 2.5,
this.minScale = 0.8,
this.scrollFrictionCoefficient = _kDefaultScrollFrictionCoefficient,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit misleading, InteractiveViewer is not a scrolling widget. If we use scrolling terms, users expect other scrolling conventions to apply, like having a ScrollPosition, and ScrollNotifications.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good point. How about we call it interactionEndFrictionCoefficient or dragEndFrictionCoefficient?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds good to me! :)

@frankteller-de frankteller-de changed the title Add scrollFriction to InteractiveViewer Add friction coefficient to InteractiveViewer Aug 17, 2022
@justinmc
Copy link
Contributor

Thanks @Piinks.

So using ScrollPhysics is off the table, but does it make sense to allow customizing the entire Simulation (here)? Or maybe that would still be far too complicated and we should just stick with the coefficient?

@Piinks
Copy link
Contributor

Piinks commented Aug 17, 2022

does it make sense to allow customizing the entire Simulation (here)? Or maybe that would still be far too complicated and we should just stick with the coefficient?

@codeforce-dev is there an open issue that this is seeking to resolve? It would be very helpful in answering these questions and better understanding the request.

@frankteller-de
Copy link
Contributor Author

The coefficient would be the simplest way to optimize the "scrolling" behaviour for some purposes. A more complex solution is not necessary. For example, pdf_render uses InterativeViewer to handle the user interaction. But in my opinion, the default drag behaviour with a value of 0.0000135 feels not good for that purpose.

FrictionCoefficient
Screen 1 = 0.0000135 | Screen 2 = 0.01

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds to me like a custom Simulation is too confusing and low-level for use cases like the one given by @codeforce-dev. I say let's just go forward with exposing the coefficent of friction like in this PR 👍.

A few comments below but I think this is almost ready. Thanks for dealing with all of my questions on making sure this is the best solution!

// late TransformationController _transformationController;
// Widget child = const Placeholder();

/// Default coefficient of friction.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the original comments on _kDrag had some important details about where the value came from:

// Used as the coefficient of friction in the inertial translation animation.
// This value was eyeballed to give a feel similar to Google Photos.

/// Used as the coefficient of friction in the inertial translation animation.
/// This value was eyeballed to give a feel similar to Google Photos.
///
/// Defaults to [_kDefaultInteractionEndFrictionCoefficient].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constant is private. I think we should explicitly give the 0.0000135 value here, because readers will want to know whether to give a value greater than or less than that for their own use cases.

await tester.dragFrom(const Offset(100.0, 100.0), const Offset(0.0, 50.0));
final Vector3 translation2 = transformationController.value.getTranslation();

expect(translation2.y, equals(0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this isn't properly testing the feature. It looks like in the first drag, the expectation happens immediately after the drag, before any inertia animation has happened, so the y value is exactly the same as the length of the gesture (-50.0). In the second drag, it goes in the opposite direction and ends up not moving at all (because it hit the boundary?).

What if you pumpAndSettle after each drag and then get the translation? I imagine then you would see more translation because the inertia animation has happened. (And I think make sure the second drag goes in the same direction as the first.)

Lastly, I think the most important expectation is that translation1.y > translation2.y, because that shows that a greater coefficient of friction slows down the animation more quickly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your reply. I've already tried dragFrom and moveBy with pumpAndSettle but unfortunately it has no effect on it. I always get -50.

final TestGesture gesture = await tester.startGesture(const Offset(100, 100));
await gesture.moveBy(const Offset(0, -50));
await tester.pumpAndSettle();
final Vector3 translation = transformationController.value.getTranslation();
// translation.y = -50;

Copy link
Contributor Author

@frankteller-de frankteller-de Aug 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, flingFrom is the solution.

await tester.flingFrom(const Offset(100, 100), const Offset(0, -50), 100.0);
await tester.pumpAndSettle();

@goderbauer goderbauer requested a review from justinmc August 23, 2022 22:17
@frankteller-de frankteller-de requested review from Piinks and alestiago and removed request for alestiago and justinmc September 1, 2022 21:03
Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a few nits - thank you!

/// Changes the scrolling behavior after end of a gesture.
///
/// Used as the coefficient of friction in the inertial translation animation.
/// This value was eyeballed to give a feel similar to Google Photos.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this? This could change at any time, but also does not account for how Google Photos behaves on different devices.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. Keep it in the comments below, but remove it from the public docs. You could make it "Google Photos on Android 12" since I think that's what I was using when I wrote that comment.

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nits as well. Let me know if you want to fix those and we can get this merged. 👍

/// Changes the scrolling behavior after end of a gesture.
///
/// Used as the coefficient of friction in the inertial translation animation.
/// This value was eyeballed to give a feel similar to Google Photos.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. Keep it in the comments below, but remove it from the public docs. You could make it "Google Photos on Android 12" since I think that's what I was using when I wrote that comment.

MaterialApp(
home: Scaffold(
body: SizedBox(
width: 200, height: 200,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate these onto different lines.

await tester.pumpAndSettle();
final Vector3 translation2 = transformationController2.value.getTranslation();

// Test 2 movement must be greater than in Test 1.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to: The coefficient 0.01 is greater than the default of 0.0000135, so the translation comes to a stop more quickly.

@Piinks
Copy link
Contributor

Piinks commented Sep 20, 2022

Hi @codeforce-dev, would you like to address the outstanding comments from @justinmc so this can land? Thanks!

@Piinks Piinks added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 20, 2022
@auto-submit auto-submit bot merged commit 4aea2f9 into flutter:master Sep 20, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Sep 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants