This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0
wcui/src/scroll/index.wc

256 lines
5.6 KiB
Plaintext

<template>
<div class="container"><slot></slot></div>
<div class="is-horizontal"><span class="thumb"></span></div>
<div class="is-vertical"><span class="thumb"></span></div>
</template>
<style lang="scss">
:host {
overflow: hidden;
position: relative;
display: flex;
width: 100%;
.container {
overflow: hidden;
position: relative;
width: 100%;
height: 100%;
}
}
/* 横向 */
.is-horizontal,
.is-vertical {
visibility: hidden;
position: absolute;
z-index: 10240;
opacity: 0;
transition: opacity 0.3s linear, visibility 0.3s linear;
.thumb {
display: block;
border-radius: 3px;
background: rgba(44, 47, 53, 0.25);
cursor: default;
&:hover {
background: rgba(44, 47, 53, 0.5);
}
}
}
.is-horizontal {
left: 0;
bottom: 1px;
width: 100%;
height: 6px;
.thumb {
width: 0;
height: 6px;
}
}
/* 纵向 */
.is-vertical {
top: 0;
right: 1px;
width: 6px;
height: 100%;
.thumb {
width: 6px;
height: 0;
}
}
:host(:hover) {
.is-horizontal,
.is-vertical {
visibility: visible;
opacity: 1;
}
}
</style>
<script>
// 是否火狐浏览器
const IS_FF = !!window.sidebar
/* */
export default class Scroll {
props = {
v: ''
}
constructor() {
/* render */
this.__BOX__ = this.root.children[1]
this.__X__ = this.root.children[2].children[0]
this.__Y__ = this.root.children[3].children[0]
}
mounted() {
// 初始化滚动条的位置和长度
this._initFn = ev => {
var ow = this.__BOX__.offsetWidth
var sw = this.__BOX__.scrollWidth
var oh = this.__BOX__.offsetHeight
var sh = this.__BOX__.scrollHeight
var yh = ((oh * oh) / sh) >> 0
var xw = ((ow * ow) / sw) >> 0
if (yh < 50) {
yh = 50
}
if (xw < 50) {
xw = 50
}
// 100%时不显示
if (xw === ow) {
xw = 0
}
if (yh === oh) {
yh = 0
}
this.props.oh = oh
this.props.sh = sh
this.props.ow = ow
this.props.sw = sw
this.props.yh = yh
this.props.xw = xw
this.__X__.style.width = xw + 'px'
this.__Y__.style.height = yh + 'px'
}
// 鼠标滚动事件
this._wheelFn = ev => {
ev.preventDefault()
var { sh, oh, yh, sw, ow, xw } = this.props
// x轴 y轴 都为0时, 不作任何处理
if (!xw && !yh) {
return
}
//校正兼容苹果鼠标在 chrome和FF下滚动的精度
var deltaX
var deltaY
if (IS_FF) {
// 区分是触摸板还是普通鼠标
deltaX = ev.deltaMode ? 10 * ev.deltaX : ev.deltaX
deltaY = ev.deltaMode ? 10 * ev.deltaY : ev.deltaY
} else {
var delta = Math.abs(ev.wheelDelta)
// 精度高的(小于120), 一般是触摸板或苹果的鼠标
if (delta < 120) {
deltaX = ev.deltaX
deltaY = ev.deltaY
} else {
deltaX = ev.deltaX / (delta / 120)
deltaY = ev.deltaY / (delta / 120)
}
}
this.__BOX__.scrollTop += deltaY
this.__BOX__.scrollLeft += deltaX
if (xw) {
// 修正滚动条的位置
// 滚动比例 x 滚动条的可移动距离
var fixedX = (this.__BOX__.scrollLeft / (sw - ow)) * (ow - xw)
this.props.thumbX = fixedX
this.__X__.style.transform = `translateX(${fixedX}px)`
}
if (yh) {
var fixedY = (this.__BOX__.scrollTop / (sh - oh)) * (oh - yh)
this.props.thumbY = fixedY
this.__Y__.style.transform = `translateY(${fixedY}px)`
}
}
this.__BOX__.addEventListener('mouseenter', this._initFn, false)
this.__BOX__.addEventListener('wheel', this._wheelFn, false)
var startX,
startY,
moveX,
moveY,
mousemoveFn = ev => {
var { sw, ow, xw, sh, oh, yh, thumbY, thumbX } = this.props
if (startX !== null) {
moveX = thumbX + ev.pageX - startX
if (moveX < 0) {
moveX = 0
} else if (moveX > ow - xw) {
moveX = ow - xw
}
this.__BOX__.scrollLeft = (sw - ow) * (moveX / (ow - xw))
this.__X__.style.transform = `translateX(${moveX}px)`
}
if (startY !== null) {
moveY = thumbY + ev.pageY - startY
if (moveY < 0) {
moveY = 0
} else if (moveY > oh - yh) {
moveY = oh - yh
}
this.__BOX__.scrollTop = (sh - oh) * (moveY / (oh - yh))
this.__Y__.style.transform = `translateY(${moveY}px)`
}
},
mouseupFn = ev => {
startX = null
startY = null
this.props.thumbX = moveX
this.props.thumbY = moveY
document.removeEventListener('mousemove', mousemoveFn)
document.removeEventListener('mouseup', mouseupFn)
}
this.__Y__.addEventListener(
'mousedown',
ev => {
startY = ev.pageY
if (!this.props.thumbY) {
this.props.thumbY = 0
}
document.addEventListener('mousemove', mousemoveFn, false)
document.addEventListener('mouseup', mouseupFn, false)
},
false
)
this.__X__.addEventListener(
'mousedown',
ev => {
startX = ev.pageX
if (!this.props.thumbX) {
this.props.thumbX = 0
}
document.addEventListener('mousemove', mousemoveFn, false)
document.addEventListener('mouseup', mouseupFn, false)
},
false
)
}
unmount() {
this.__BOX__.removeEventListener('mouseenter', this._initFn)
this.__BOX__.removeEventListener('wheel', this._wheelFn)
}
}
</script>
wcui是一套基于`Web Components`的UI组件库, 宗旨是追求简单、实用、不花哨。
JavaScript 95.2%
CSS 4.8%