import { addEvent, removeEvent } from '../util/dom' import { ease } from '../util/ease' export function mouseWheelMixin(BScroll) { BScroll.prototype._initMouseWheel = function () { this._handleMouseWheelEvent(addEvent) this.on('destroy', () => { clearTimeout(this.mouseWheelTimer) clearTimeout(this.mouseWheelEndTimer) this._handleMouseWheelEvent(removeEvent) }) this.firstWheelOpreation = true } BScroll.prototype._handleMouseWheelEvent = function (eventOperation) { eventOperation(this.wrapper, 'wheel', this) eventOperation(this.wrapper, 'mousewheel', this) eventOperation(this.wrapper, 'DOMMouseScroll', this) } BScroll.prototype._onMouseWheel = function (e) { if (!this.enabled) { return } e.preventDefault() if (this.options.stopPropagation) { e.stopPropagation() } if (this.firstWheelOpreation) { this.trigger('scrollStart') } this.firstWheelOpreation = false const {speed = 20, invert = false, easeTime = 300} = this.options.mouseWheel clearTimeout(this.mouseWheelTimer) this.mouseWheelTimer = setTimeout(() => { if (!this.options.snap && !easeTime) { this.trigger('scrollEnd', { x: this.x, y: this.y }) } this.firstWheelOpreation = true }, 400) let wheelDeltaX let wheelDeltaY switch (true) { case 'deltaX' in e: if (e.deltaMode === 1) { wheelDeltaX = -e.deltaX * speed wheelDeltaY = -e.deltaY * speed } else { wheelDeltaX = -e.deltaX wheelDeltaY = -e.deltaY } break case 'wheelDeltaX' in e: wheelDeltaX = e.wheelDeltaX / 120 * speed wheelDeltaY = e.wheelDeltaY / 120 * speed break case 'wheelDelta' in e: wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * speed break case 'detail' in e: wheelDeltaX = wheelDeltaY = -e.detail / 3 * speed break default: return } let direction = invert ? -1 : 1 wheelDeltaX *= direction wheelDeltaY *= direction if (!this.hasVerticalScroll) { wheelDeltaX = wheelDeltaY wheelDeltaY = 0 } let newX let newY if (this.options.snap) { newX = this.currentPage.pageX newY = this.currentPage.pageY if (wheelDeltaX > 0) { newX-- } else if (wheelDeltaX < 0) { newX++ } if (wheelDeltaY > 0) { newY-- } else if (wheelDeltaY < 0) { newY++ } this._goToPage(newX, newY) return } newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0) newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0) this.movingDirectionX = this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0 this.movingDirectionY = this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0 if (newX > this.minScrollX) { newX = this.minScrollX } else if (newX < this.maxScrollX) { newX = this.maxScrollX } if (newY > this.minScrollY) { newY = this.minScrollY } else if (newY < this.maxScrollY) { newY = this.maxScrollY } const needTriggerEnd = this.y === newY this.scrollTo(newX, newY, easeTime, ease.swipe) this.trigger('scroll', { x: this.x, y: this.y }) clearTimeout(this.mouseWheelEndTimer) if (needTriggerEnd) { this.mouseWheelEndTimer = setTimeout(() => { this.trigger('scrollEnd', { x: this.x, y: this.y }) }, easeTime) } } }