| <template> |
| <div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll"> |
| <div class="scroll-wrapper" ref="scrollWrapper" :style="{left: left + 'px'}"> |
| <slot></slot> |
| </div> |
| </div> |
| </template> |
| |
| <script> |
| const padding = 15 // tag's padding |
| |
| export default { |
| name: 'scrollPane', |
| data() { |
| return { |
| left: 0 |
| } |
| }, |
| methods: { |
| handleScroll(e) { |
| const eventDelta = e.wheelDelta || -e.deltaY * 3 |
| const $container = this.$refs.scrollContainer |
| const $containerWidth = $container.offsetWidth |
| const $wrapper = this.$refs.scrollWrapper |
| const $wrapperWidth = $wrapper.offsetWidth |
| |
| if (eventDelta > 0) { |
| this.left = Math.min(0, this.left + eventDelta) |
| } else { |
| if ($containerWidth - padding < $wrapperWidth) { |
| if (this.left < -($wrapperWidth - $containerWidth + padding)) { |
| this.left = this.left |
| } else { |
| this.left = Math.max(this.left + eventDelta, $containerWidth - $wrapperWidth - padding) |
| } |
| } else { |
| this.left = 0 |
| } |
| } |
| }, |
| moveToTarget($target) { |
| const $container = this.$refs.scrollContainer |
| const $containerWidth = $container.offsetWidth |
| const $targetLeft = $target.offsetLeft |
| const $targetWidth = $target.offsetWidth |
| |
| if ($targetLeft < -this.left) { |
| // tag in the left |
| this.left = -$targetLeft + padding |
| } else if ($targetLeft + padding > -this.left && $targetLeft + $targetWidth < -this.left + $containerWidth - padding) { |
| // tag in the current view |
| // eslint-disable-line |
| } else { |
| // tag in the right |
| this.left = -($targetLeft - ($containerWidth - $targetWidth) + padding) |
| } |
| } |
| } |
| } |
| </script> |
| |
| <style rel="stylesheet/scss" lang="scss" scoped> |
| .scroll-container { |
| white-space: nowrap; |
| position: relative; |
| overflow: hidden; |
| width: 100%; |
| .scroll-wrapper { |
| position: absolute; |
| } |
| } |
| </style> |