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

Scroll Progress (get) #21

Closed
davidjerleke opened this issue Sep 16, 2019 · 11 comments
Closed

Scroll Progress (get) #21

davidjerleke opened this issue Sep 16, 2019 · 11 comments
Labels
feature request New feature or request resolved This issue is resolved

Comments

@davidjerleke
Copy link
Owner

davidjerleke commented Sep 16, 2019

👉 Conclusion / Feature Specification

The discussion in this issue has resulted in a decision to implement the following API method:

// get scroll progress
// returns a number representing % scrolled of scrollable distance.
// 0 is start position and 1 is end position

embla.scrollProgress()

Example Usage

embla.on('scroll', () => {
  console.log(`Current progress is: ${embla.scrollProgress() * 100}%`)
}

CodeSandbox

See example usage.

Special thanks

@xiel for discussing this and sharing your thoughts and ideas.
@welteki for the nice demonstration.

@davidjerleke davidjerleke added feature request New feature or request investigating Issue is being looked into labels Sep 16, 2019
@xiel
Copy link
Contributor

xiel commented Sep 16, 2019

Hey David,
I think this makes a lot of sense and would be a great addition to the API. It would make it possible to sync other things to the movement or implement other kinds of pagination indicators etc.

Would you also consider an API for setting of scroll progress at the same time?
embla.scrollProgress(20)
embla.scrollBy(-15)

This could be used to sync Embla to external things (like scroll position in one-pagers or other kinds of user input).

Cheers!

@davidjerleke
Copy link
Owner Author

Hi Felix (@xiel),
Thank you for your feedback. This is a great suggestion 🙂.

Just want to confirm that I understand you correctly. At the time of writing we have a method called: embla.scrollTo(index) which scrolls to a specific snap point index. Maybe we should think about how we name these methods to avoid confusion?

  • embla.scrollProgress() --> retrieves the current scroll position in %
  • embla.scrollBy(number)--> sets the current scroll position in %

Is this what you had in mind?

Best,
David

@xiel
Copy link
Contributor

xiel commented Sep 16, 2019

I had a get/set interface in mind, so when you do not pass anything, you get the current value back. And if you pass something, this value will gets applied.

embla.scrollProgress() // get in %
embla.scrollProgress(number) // set in %

Sometimes relative change to the current position is more interesting. For that, a second convenience method could offer to update the position by a relative value (similar to window.scrollBy):

embla.scrollBy(0.25) // change current by % (default, to be analog to the unit of scrollProgress)
embla.scrollBy(340, 'px') // change based on current +/- using px

I think it makes sense to also allow setting and getting in px dimensions, this could be done either as a second parameter (px / %) or side-by-side as own methods?

  • embla.scrollProgressPx() // get in px
  • embla.scrollProgressPx(680) // set in px
  • embla.scrollByPx(340) // relative change in px

Recarding the unit, I would also suggest to use 0..1 range for percentage (instead of 1..100), as it is more common in JS and easier to distinguish from px values.

Sorry for all the requests. Happy to take this into a separate issue if it's to much here ;)

@davidjerleke
Copy link
Owner Author

davidjerleke commented Sep 18, 2019

Hello Felix (@xiel),

That's surely a lot to take in 😄. But I always appreciate ideas so thank you for taking time to discuss this. So I think embla.scrollProgress() is pretty straightforward:

embla.scrollProgress()
// get scroll progress
// returns a number from 0 - 1 representing % scrolled of scrollable distance

And I think I understand the idea for scrollProgress(number) and scrollBy(number):

embla.scrollProgress(0.5)
// set scroll progress
// accepts a number from 0 - 1 representing % scrolled of scrollable distance
embla.scrollBy(0.5)
// set scroll position relative to current
// accepts a number from 0 - 1 representing % to scroll based on current scroll position

Methods like scrollProgress(number) and scrollBy(number) would move the carousel to arbitrary positions (not a snap point), pretty much like when you drag the carousel and have { dragFree: true }. Maybe I'm missing something obvious, but do you have use case/cases in mind for this to help me understand this better when these methods could be useful?

Regarding px units I think it's a bigger surgical intervention because at the time of writing Embla translates the carousel with % rather than px. So maybe it makes sense to open a separate issue for the px request 😉.

Best
David

@welteki
Copy link

welteki commented Sep 24, 2019

Hi David (@davidjerleke),

A couple of months ago I forked this repository with a similar idea in mind. I wanted to create a carousel with parallax effect and changing background gradient but in order to do this I needed the scroll progress. I made a quick implementation to experiment with this a bit.

Here's an example: https://codesandbox.io/embed/embla-carousel-scroll-event-czzbo
My implementation isn't great but I hope this can give you an idea of how this API can be used.

@xiel
Copy link
Contributor

xiel commented Sep 24, 2019

Hey @davidjerleke,

use cases for setting the scroll position manually:

  • alternative input methods (arrow keys, gestures, eye tracking, you name it...)
  • alternative interactions, examples:
    • a scroll progress indicator, which the user could drag to move the slider
    • carousel position is bound to scroll position
    • two carousels bound to each other

I think it does not make sense to implement all these use cases within Embla itself, but I would love to see the API evolve and being able to implement them myself when needed. And a way to change the scroll position would definitely be needed for that.

I agree that the developer might move the carousel to arbitrary positions, that should be a solvable challenge. Could the developer not just call scrollTo(selectedScrollSnap()) to make it snap if wanted?

I have not dived deep into the code, but don't you already map from px dimensions to % dimensions in your drag implementation? Otherwise providing the scroll length would also be sufficient, then the developer could map to percentage values himself.

Best,
Felix

@davidjerleke
Copy link
Owner Author

Hello Han (@welteki),

Very creative with the background color changing, I like it 😄. And thank you for this example, I think it's a great demonstration for other users browsing this issue. This feature will be implemented as soon as possible. Do you have any further ideas about this feature that you think could be valuable?

Best,
David

@davidjerleke
Copy link
Owner Author

davidjerleke commented Sep 26, 2019

Hi @xiel,

Thank you for taking time to explain 💪.

I agree that the developer might move the carousel to arbitrary positions, that should be a solvable challenge. Could the developer not just call scrollTo(selectedScrollSnap()) to make it snap if wanted?

You're absolutely right about this.

I've decided to split all feature requests in this discussion into separate issues. I think it will make it easier to follow each feature request and implement them separately, one by one. I hope this is ok with you.

Please see ScrollBy #23.

Best,
David

@davidjerleke davidjerleke mentioned this issue Sep 26, 2019
@davidjerleke
Copy link
Owner Author

davidjerleke commented Sep 28, 2019

Hi Felix (@xiel),

About the method for setting scroll progress embla.scrollProgress(number), we are talking about an instant setter right? Meaning using this method won’t scroll to desired position but rather go there instantly. I’d like to hear your thoughts.

Thank you for your attention!
David

@xiel
Copy link
Contributor

xiel commented Sep 28, 2019

Yes, I would expect it to be an instant setter by default.

@davidjerleke davidjerleke added upcoming A feature or bug fix is on its way for this issue and removed investigating Issue is being looked into labels Sep 28, 2019
@davidjerleke davidjerleke self-assigned this Sep 30, 2019
@davidjerleke davidjerleke changed the title Scroll progress Scroll Progress Sep 30, 2019
@davidjerleke davidjerleke changed the title Scroll Progress Scroll Progress (set) Oct 6, 2019
@davidjerleke davidjerleke changed the title Scroll Progress (set) Scroll Progress (get) Oct 6, 2019
@davidjerleke davidjerleke added resolved This issue is resolved and removed upcoming A feature or bug fix is on its way for this issue labels Oct 6, 2019
@davidjerleke davidjerleke removed their assignment Oct 6, 2019
@davidjerleke
Copy link
Owner Author

davidjerleke commented Oct 6, 2019

Hello @xiel and @welteki,

I'm happy to announce that the first part of this, the scroll progress getter has been released with version 2.5.0 🚀.

Read more here or check this CodeSandbox out.

Enjoy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request resolved This issue is resolved
Projects
None yet
Development

No branches or pull requests

3 participants