Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snap to integer zoom level #3532

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open

Conversation

quinncnl
Copy link

@quinncnl quinncnl commented Jan 2, 2024

Add an option to snap to integer zoom level: #1591

Example: https://tracestrack.s3-website.nl-ams.scw.cloud/dist/
Example: https://tracestrack.s3-website.nl-ams.scw.cloud/dist/#12.40/11.7933/53.4402
jsfiddle: https://jsfiddle.net/142rftnx/1/

Launch Checklist

  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!
  • Briefly describe the changes in this PR.
  • Link to related issues.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality.
  • Document any changes to public APIs.
  • Post benchmark scores.
  • Add an entry to CHANGELOG.md under the ## main section.

@quinncnl quinncnl marked this pull request as draft January 2, 2024 18:44
@quinncnl quinncnl changed the title init Snap to integer zoom level Jan 2, 2024
@HarelM
Copy link
Member

HarelM commented Jan 2, 2024

Thanks for taking the time to contribute!
Quick question, What about touch gestures?
Also note that there's a similar behavior to snap bearing to north, might be worth getting inspiration from, maybe...

@quinncnl
Copy link
Author

quinncnl commented Jan 2, 2024

Thanks for the note! I'll check those :)

@codecov-commenter
Copy link

codecov-commenter commented Jan 7, 2024

Codecov Report

Attention: Patch coverage is 35.93750% with 41 lines in your changes are missing coverage. Please review.

Project coverage is 86.46%. Comparing base (44b582e) to head (4c47772).
Report is 51 commits behind head on main.

Files Patch % Lines
src/ui/handler/scroll_zoom.ts 0.00% 22 Missing and 1 partial ⚠️
src/ui/map.ts 52.94% 8 Missing ⚠️
src/ui/handler/box_zoom.ts 0.00% 5 Missing ⚠️
src/ui/handler/click_zoom.ts 0.00% 0 Missing and 2 partials ⚠️
src/ui/handler/tap_zoom.ts 75.00% 1 Missing and 1 partial ⚠️
src/ui/camera.ts 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3532      +/-   ##
==========================================
- Coverage   86.83%   86.46%   -0.37%     
==========================================
  Files         241      242       +1     
  Lines       32341    32530     +189     
  Branches     1962     2161     +199     
==========================================
+ Hits        28082    28128      +46     
- Misses       3340     3454     +114     
- Partials      919      948      +29     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@quinncnl
Copy link
Author

quinncnl commented Jan 7, 2024

I've done some changes to ScrollZoom. For TagDragZoom and TwoFingersTouchZoom it requires more investigation and probably a bigger change. Can we ignore the touch zoom for now?

@HarelM
Copy link
Member

HarelM commented Jan 8, 2024

I don't think we can ignore the touch events without a flag that is specifying to which gestures the interger zoom applies I guess.
Also I'm not sure the animation of the zoom scroll in the demo is working well...
Can you add hash control to the demo so that zoom level will be easy to see?

@quinncnl
Copy link
Author

OK will add hash control. For the touch event it'll take some time since it's quite complicated.

@HarelM
Copy link
Member

HarelM commented Jan 12, 2024

What I meant to say is that if you decide not to implement touch handling the flag specifying the integer zoom should be something like:
snapToIntegerZoom: {touch: false, scroll: true, controls: true}
And not a simple boolean, this will on one hand allow more granularity and also provide a way to implement just the relevant part.
When all are implemented, true and false can be added to indicate "apply to all" kind of configuration.

@HarelM
Copy link
Member

HarelM commented Mar 8, 2024

Any updates on this?

@quinncnl
Copy link
Author

quinncnl commented Mar 8, 2024

Hey @HarelM sorry I got busy. Will try to followup on it this weekend. I'll break it into smaller pieces as you suggested.

@quinncnl
Copy link
Author

Hi @HarelM I've updated the example map and added a jsfiddle. Could you please check it and provide feedback? Once it looks good I'll fix the tests and docs.

src/ui/map.ts Outdated Show resolved Hide resolved
src/ui/map.ts Outdated Show resolved Hide resolved
src/ui/handler/tap_zoom.ts Outdated Show resolved Hide resolved
src/ui/handler/tap_zoom.ts Outdated Show resolved Hide resolved
@HarelM
Copy link
Member

HarelM commented Mar 11, 2024

I think this direction is OK.

@sbachinin
Copy link
Collaborator

sbachinin commented Mar 12, 2024

Noticed that in your jsfiddle you can't zoom in. When I drag the mousewheel forward, it jumps to zoom 3.0 and you are stuck there.

src/ui/map.ts Outdated Show resolved Hide resolved
src/ui/map.ts Outdated Show resolved Hide resolved
test/build/min.test.ts Outdated Show resolved Hide resolved
@quinncnl quinncnl marked this pull request as ready for review March 17, 2024 19:24
if (options === null || options === undefined) {
this._snapToIntegerZoomOptions = {boxZoom: false, clickZoom: false, scrollZoom: false, tapZoom: false};
} else {
this._snapToIntegerZoomOptions = options;
Copy link
Member

Choose a reason for hiding this comment

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

I think this will reset other snap options, wouldn't it? i.e. if I set scroll to true in the first call and set box to true in the second call, I'll reset scroll configuration.
Consider doing a for loop here maybe? Not sure if it's a great idea though...

Copy link
Member

Choose a reason for hiding this comment

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

Or maybe consider the API to be similar to the get/should

Copy link
Author

@quinncnl quinncnl Mar 18, 2024

Choose a reason for hiding this comment

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

I see your point. I think replacing the entire options is more logical here because we are setting SnapToIntegerZoomOptions instead of type: SnapToIntegerZoomType. It's also same like other setters like style: StyleSpecification.

Or maybe consider the API to be similar to the get/should

Something like setSnapToIntegerZoom(type: SnapToIntegerZoomType, value: boolean)? Normally this options is set once at the map init instead of fine tune later. Using this kind of setter is not very convenient in this common case. As you would find codes like:

setSnapToIntegerZoom("boxScroll", true);
setSnapToIntegerZoom("clickScroll", true);

instead of simple setOptions({boxScrolll: true, clickScroll: true})


zoomTarget = Math.round(zoomTarget);

this._map.easeTo({
Copy link
Member

Choose a reason for hiding this comment

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

It seems like there is a explicit animation code for regular zoom, how come this can be avoided using easeTo instead of writing the animation code (using frames etc)?

Copy link
Author

Choose a reason for hiding this comment

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

The explicit animation is about smoothOutEasing which doesn't have a targetZoom. The end zoom is based on an easing function which is hard to ease to an integer level. So I just skip that and use a simple easeTo instead.

@HarelM
Copy link
Member

HarelM commented Mar 17, 2024

@quinncnl did you check/fix the issue reported by @sbachinin?

@quinncnl
Copy link
Author

@quinncnl did you check/fix the issue reported by @sbachinin?

I can't seem to reproduce the scenario. @sbachinin could you try again? Maybe it was before my refator to scrollZoom.

@sbachinin
Copy link
Collaborator

This particular jsfiddle shows the same bad behaviour.
It could be broken because of using some outdated bundle, I don't know.

Here's what I get when I try to zoom in:

1234.mp4

@quinncnl
Copy link
Author

@sbachinin Thanks. I can reproduce it using touchpad scroll. Will check

@quinncnl
Copy link
Author

quinncnl commented Apr 2, 2024

Hi @sbachinin I updated the demo. Could you try again? It seems we have to round the zoom at the end of inertia animation. If this is not acceptable can we have a separate toggle for it, like trackpadScroll and do it later? @HarelM

@HarelM
Copy link
Member

HarelM commented Apr 3, 2024

I would expect the last commit to be added with a test to make sure this is the expected behavior.

@sbachinin
Copy link
Collaborator

@quinncnl, all the demos given here still demonstrate zooming problems for me. (Chrome 122.0.6261.129)
When I roll mousewheel forward:
first several "clicks" are ignored, then I'm jumping to zoom 3.
When I roll mousewheel backward:
first several "clicks" are ignored, then begins a normal zoom out.

@quinncnl
Copy link
Author

quinncnl commented Apr 3, 2024

I tried a different computer on Windows and there it jumps zoom by 2 with single scroll. Looks like I need to test with different browser/OS/scroll device(trackpad/mouse) as they have different scroll values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants