123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- import {
- nextTick
- } from '../../shared/utils.js';
- export default function Scrollbar({
- swiper,
- extendParams,
- on,
- emit
- }) {
- let isTouched = false;
- let timeout = null;
- let dragTimeout = null;
- let dragStartPos;
- let dragSize;
- let trackSize;
- let divider;
- extendParams({
- scrollbar: {
- el: null,
- dragSize: 'auto',
- hide: false,
- draggable: false,
- snapOnRelease: true,
- lockClass: 'swiper-scrollbar-lock',
- dragClass: 'swiper-scrollbar-drag',
- },
- });
- swiper.scrollbar = {
- el: null,
- dragEl: null,
- $el: null,
- $dragEl: null,
- };
- function setTranslate() {
- if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
- const {
- scrollbar,
- rtlTranslate: rtl,
- progress
- } = swiper;
- const params = swiper.params.scrollbar;
- let newSize = dragSize;
- let newPos = (trackSize - dragSize) * progress;
- if (rtl) {
- newPos = -newPos;
- if (newPos > 0) {
- newSize = dragSize - newPos;
- newPos = 0;
- } else if (-newPos + dragSize > trackSize) {
- newSize = trackSize + newPos;
- }
- } else if (newPos < 0) {
- newSize = dragSize + newPos;
- newPos = 0;
- } else if (newPos + dragSize > trackSize) {
- newSize = trackSize - newPos;
- }
- if (swiper.isHorizontal()) {
- swiper.$wrapperEl.scrollbarItemTransform(`translate3d(${newPos}px, 0, 0)`);
- swiper.$wrapperEl.scrollbarItemCss({
- width: `${newSize}px`
- })
- } else {
- swiper.$wrapperEl.scrollbarItemTransform(`translate3d(0px, ${newPos}px, 0)`);
- swiper.$wrapperEl.scrollbarItemCss({
- height: `${newSize}px`
- })
- }
- if (params.hide) {
- clearTimeout(timeout);
- swiper.$wrapperEl.scrollbarCss({
- opacity: 1
- })
- timeout = setTimeout(() => {
- swiper.$wrapperEl.scrollbarCss({
- opacity: 0
- })
- swiper.$wrapperEl.scrollbarTransition(400)
- }, 1000);
- }
- }
- function setTransition(duration) {
- if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
- swiper.$wrapperEl.scrollbarItemTransition(duration);
- }
- async function updateSize() {
- if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
- const {
- scrollbar
- } = swiper;
- const {
- $el,
- methods
- } = scrollbar;
- swiper.$wrapperEl.scrollbarItemCss({
- width: '',
- height: ''
- })
- let rectInfo = await swiper.native.getRectScrollbar();
- methods.offset = function() {
- return rectInfo;
- }
- trackSize = swiper.isHorizontal() ? rectInfo.width : rectInfo.height;
- divider =
- swiper.size /
- (swiper.virtualSize +
- swiper.params.slidesOffsetBefore -
- (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
- if (swiper.params.scrollbar.dragSize === 'auto') {
- dragSize = trackSize * divider;
- } else {
- dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
- }
- if (swiper.isHorizontal()) {
- swiper.$wrapperEl.scrollbarItemCss({
- width: `${dragSize}px`
- })
- } else {
- swiper.$wrapperEl.scrollbarItemCss({
- height: `${dragSize}px`
- })
- }
- if (divider >= 1) {
- swiper.$wrapperEl.scrollbarCss({
- display: 'none'
- })
- } else {
- swiper.$wrapperEl.scrollbarCss({
- display: ''
- })
- }
- if (swiper.params.scrollbar.hide) {
- swiper.$wrapperEl.scrollbarCss({
- opacity: 0
- })
- }
- if (swiper.params.watchOverflow && swiper.enabled) {
- swiper.$wrapperEl[swiper.isLocked ? 'addScrollbarClass' : 'removeScrollbarClass'](
- swiper.params.scrollbar.lockClass,
- );
- }
- }
- function getPointerPosition(e) {
- if (swiper.isHorizontal()) {
- return e.type === 'touchstart' || e.type === 'touchmove' || 'touchStart' || e.type === 'touchMove' ?
- e.touches[0].clientX :
- e.clientX;
- }
- return e.type === 'touchstart' || e.type === 'touchmove' ?
- e.touches[0].clientY :
- e.clientY;
- }
- function setDragPosition(e) {
- const {
- scrollbar,
- rtlTranslate: rtl
- } = swiper;
- const {
- $el,
- methods
- } = scrollbar;
- let positionRatio;
- positionRatio =
- (getPointerPosition(e) -
- methods.offset()[swiper.isHorizontal() ? 'left' : 'top'] -
- (dragStartPos !== null ? dragStartPos : dragSize / 2)) /
- (trackSize - dragSize);
- positionRatio = Math.max(Math.min(positionRatio, 1), 0);
- if (rtl) {
- positionRatio = 1 - positionRatio;
- }
- const position =
- swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
- swiper.updateProgress(position);
- swiper.setTranslate(position);
- swiper.updateActiveIndex();
- swiper.updateSlidesClasses();
- }
- function onDragStart(_s, e) {
- const params = swiper.params.scrollbar;
- const {
- scrollbar,
- $wrapperEl
- } = swiper;
- isTouched = true;
- dragStartPos =
- // e.target ===
- // $dragEl[0] || e.target === $dragEl ?
- // getPointerPosition(e) -
- // e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] :
- null;
- // e.preventDefault();
- // e.stopPropagation();
- $wrapperEl.transition(100);
- swiper.$wrapperEl.scrollbarItemTransition(100)
- // $dragEl.transition(100);
- setDragPosition(e);
- clearTimeout(dragTimeout);
- swiper.$wrapperEl.scrollbarTransition(0)
- if (params.hide) {
- swiper.$wrapperEl.scrollbarCss({
- opacity: 1
- })
- }
- if (swiper.params.cssMode) {
- swiper.$wrapperEl.css({
- 'scroll-snap-type': 'none'
- });
- }
- emit('scrollbarDragStart', e);
- }
- function onDragMove(_s, e) {
- const {
- scrollbar,
- $wrapperEl
- } = swiper;
- if (!isTouched) return;
- setDragPosition(e);
- $wrapperEl.transition(0);
- swiper.$wrapperEl.scrollbarTransition(0)
- swiper.$wrapperEl.scrollbarItemTransition(0)
- emit('scrollbarDragMove', e);
- }
- function onDragEnd(_s, e) {
- const params = swiper.params.scrollbar;
- const {
- scrollbar,
- $wrapperEl
- } = swiper;
- const {
- $el
- } = scrollbar;
- if (!isTouched) return;
- isTouched = false;
- if (swiper.params.cssMode) {
- swiper.$wrapperEl.css({
- 'scroll-snap-type': ''
- });
- $wrapperEl.transition('');
- }
- if (params.hide) {
- clearTimeout(dragTimeout);
- dragTimeout = nextTick(() => {
- swiper.$wrapperEl.scrollbarCss({
- opacity: 0
- })
- swiper.$wrapperEl.scrollbarTransition(400)
- }, 1000);
- }
- emit('scrollbarDragEnd', e);
- if (params.snapOnRelease) {
- swiper.slideToClosest();
- }
- }
- function events(method) {
- const {
- scrollbar,
- touchEventsTouch,
- touchEventsDesktop,
- params,
- support
- } = swiper;
- const $el = scrollbar.$el;
- const target = $el;
- const activeListener =
- support.passiveListener && params.passiveListeners ? {
- passive: false,
- capture: false
- } :
- false;
- const passiveListener =
- support.passiveListener && params.passiveListeners ? {
- passive: true,
- capture: false
- } :
- false;
- if (!target) return;
- const eventMethod = method === 'on' ? 'on' : 'off';
- if (!support.touch) {
- swiper[eventMethod]('touchStartScrollbar', onDragStart, activeListener);
- swiper[eventMethod]('touchMoveScrollbar', onDragMove, activeListener);
- swiper[eventMethod]('touchEndScrollbar', onDragEnd, passiveListener);
- } else {
- swiper[eventMethod]('touchStartScrollbar', onDragStart, activeListener);
- swiper[eventMethod]('touchMoveScrollbar', onDragMove, activeListener);
- swiper[eventMethod]('touchEndScrollbar', onDragEnd, passiveListener);
- }
- }
- function enableDraggable() {
- if (!swiper.params.scrollbar.el) return;
- events('on');
- }
- function disableDraggable() {
- if (!swiper.params.scrollbar.el) return;
- events('off');
- }
- function init() {
- const {
- scrollbar,
- } = swiper;
- const params = swiper.params.scrollbar;
- if (!params.el) return;
- // swiper.native.updateData({
- // scrollbarShow: true
- // })
- let $el = params.el;
- Object.assign(scrollbar, {
- $el,
- el: $el,
- methods: {}
- });
- if (params.draggable) {
- enableDraggable();
- }
- swiper.$wrapperEl[swiper.enabled ? 'removeScrollbarClass' : 'addScrollbarClass'](swiper.params.scrollbar
- .lockClass);
- return true;
- }
- function destroy() {
- disableDraggable();
- }
- on('init', async () => {
- await init();
- updateSize();
- setTranslate();
- });
- on('update resize observerUpdate lock unlock', () => {
- updateSize();
- });
- on('setTranslate', () => {
- setTranslate();
- });
- on('setTransition', (_s, duration) => {
- setTransition(duration);
- });
- on('enable disable', () => {
- const {
- $el
- } = swiper.scrollbar;
- if ($el) {
- $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass);
- }
- });
- on('destroy', () => {
- destroy();
- });
- Object.assign(swiper.scrollbar, {
- updateSize,
- setTranslate,
- init,
- destroy,
- });
- }
|