DominikSerafin / vuebar

(🗃️ Archived) Vue 2 directive for custom scrollbar that uses native scroll behavior. Lightweight, performant, customizable and without dependencies. Used successfully in production on https://ggather.com
https://github.serafin.io/vuebar/
MIT License
649 stars 77 forks source link

Different level of Zoom (and Pixel Ratio?) make native scrollbar visible #48

Open DominikSerafin opened 6 years ago

DominikSerafin commented 6 years ago

Originally spotted by @frlinw on https://chat.vuejs.org #i-made-this channel

@frlinw - Today at 5:27 AM @DominikSerafin I guess you have something like this in your code contentWidth = contentWrapperWidth + scrollbarWidth. But it should be contentWidth = contentWrapperWidth + (scrollbarWidth/window.devicePixelRatio). Browser zoom change the devicePixelRatio so the scrollbar width changes too, that's why the native scrollbar became visible if you zoom-out(edited)

untitled

madmoizo commented 6 years ago

In addition, when you get the scrollbarWidth, you want the original scrollbarWidth (when devicePixelRatio = 1) so you have to add barWidth = Math.round(barWidth * window.devicePixelRatio) after https://github.com/DominikSerafin/vuebar/blob/master/vuebar.js#L854 then, on element resize, as I said, you can do something like contentWidth = contentWrapperWidth + (baseWidth/window.devicePixelRatio)

Moreover, I don't know if I understand correctly but here https://github.com/DominikSerafin/vuebar/blob/master/vuebar.js#L571 you use a resize listener on window but vue-bar does not detect a resize of the content right ? I mean, if you have a v-for inside vue-bar and the length of the list changes, vue-bar won't update the scrollbar height ? If I am right, take a look at ResizeObserver: https://wicg.github.io/ResizeObserver/ it's designed for this use case There is a polyfill: https://github.com/que-etc/resize-observer-polyfill

Anyway if you want some inspiration about that, I share my custom scrollbar implementation: https://gist.github.com/frlinw/93d2e28d54d79fc13af9ee8c18545edb (Note: horizontal scrollbar is still buggy, I started to work on it yesterday)

Good luck !

DominikSerafin commented 6 years ago

@frlinw

Vuebar is updated after any component update. So any state/DOM update dispatched in Vue component where the Vuebar is used will be detected and updates applied immediately and in $nextTick. So this covers v-for changes. (See: https://github.com/DominikSerafin/vuebar/blob/master/vuebar.js#L671)

And on top of that, I'm using MutationObserver to detect some of the changes outside of Vue, as a kind of fail-safe against people doing some DOM updates outside of Vue... (See: https://github.com/DominikSerafin/vuebar/blob/master/vuebar.js#L454)

But, thank you for the suggestion of using new ResizeObserver. I've actually seen some mentions on Twitter about it, but I forgot about it completely... I'll take a look into it and maybe introduce it in Vuebar 2.0/2.1 which is currently developed in "development" branch (https://github.com/DominikSerafin/vuebar/tree/development / https://github.com/DominikSerafin/vuebar/projects/1).

I'll also take a look into your implementation for sure, thanks!

madmoizo commented 6 years ago

Thanks for the clarification (I didn't dig too deep in the code) :)