feat: 首次提交
This commit is contained in:
42
components/firstui/fui-horizontal-scroll/bindingx.js
Normal file
42
components/firstui/fui-horizontal-scroll/bindingx.js
Normal file
@ -0,0 +1,42 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 186 140 7 2 54 9,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
// #ifdef APP-NVUE
|
||||
const BindingX = uni.requireNativePlugin('bindingx');
|
||||
export default {
|
||||
methods: {
|
||||
getEl(el) {
|
||||
return this.$refs[el].ref;
|
||||
},
|
||||
nvueScrollHandler(e) {
|
||||
const anchor = this.getEl('fui_scroller_view')
|
||||
const element = this.getEl('fui_hor_indicator')
|
||||
const scrollLeft = e.contentOffset.x
|
||||
const contentWidth = e.contentSize.width
|
||||
if (this.scroll && element) {
|
||||
const barAllMoveWidth = this.bgWidth - this.blockWidth
|
||||
const platform = uni.getSystemInfoSync().platform
|
||||
const actionNum = platform.toLowerCase() === 'ios' ? 2 : 1
|
||||
const expression = `(x / ${actionNum}) / ${contentWidth - this.width} * ${barAllMoveWidth}`
|
||||
BindingX.bind({
|
||||
anchor,
|
||||
eventType: 'scroll',
|
||||
props: [{
|
||||
element,
|
||||
property: 'transform.translateX',
|
||||
expression
|
||||
}]
|
||||
})
|
||||
}
|
||||
if (scrollLeft + this.width === contentWidth) {
|
||||
this.scrollEvent('right')
|
||||
} else if (scrollLeft === 0) {
|
||||
this.scrollEvent('left')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-NVUE
|
||||
export default {}
|
||||
// #endif
|
@ -0,0 +1,271 @@
|
||||
<!--本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 186 1 407 2549,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。-->
|
||||
<template>
|
||||
<view class="fui-horizontal__scroll" :style="{marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx'}"
|
||||
ref="fui_horizontal__scroll">
|
||||
<!-- #ifdef APP-VUE || MP-WEIXIN || H5-->
|
||||
<scroll-view :show-scrollbar="false" scroll-x :upper-threshold="0" :lower-threshold="0" :data-width="width" :data-bgwidth="bgWidth"
|
||||
:data-blockwidth="blockWidth" @scroll="handler.scroll" @scrolltoupper="handler.scrolltoupper"
|
||||
@scrolltolower="handler.scrolltolower" class="fui-hor__scroll-view">
|
||||
<view class="fui-hor__scroll-wrap">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<scroller class="fui-hor__scroll-view" ref="fui_scroller_view" scroll-direction="horizontal"
|
||||
:show-scrollbar="false" :offset-accuracy="2" @scroll="nvueScrollHandler">
|
||||
<view class="fui-hor__scroll-wrap">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</scroller>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifndef APP-PLUS || MP-WEIXIN || H5-->
|
||||
<scroll-view :show-scrollbar="false" scroll-x :upper-threshold="0" :lower-threshold="0" class="fui-hor__scroll-view"
|
||||
@scroll="scrollHandler" @scrolltoupper="scrolltoupper" @scrolltolower="scrolltolower">
|
||||
<view class="fui-hor__scroll-wrap">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- #endif -->
|
||||
<view class="fui-hor__scrollbar-wrap" :style="{marginTop:scrollGap+'rpx'}" v-if="scroll">
|
||||
<view class="fui-hor__scrollbar" :class="{'fui-hor__scroll-radius':scrollCap==='round'}"
|
||||
:style="{height:blockHeight+'px',width:bgWidth+'px',background:background}">
|
||||
<view class="fui-hor__scroll-indicator"
|
||||
:class="{'fui-hor__scroll-radius':scrollCap==='round','fui-hor__scroll-bg':!scrollBarColor}"
|
||||
:style="getStyles" ref="fui_hor_indicator"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<!-- #ifdef APP-VUE || MP-WEIXIN || H5-->
|
||||
<script src="./index.wxs" module="handler" lang="wxs"></script>
|
||||
<!-- #endif -->
|
||||
<script>
|
||||
// #ifdef APP-NVUE
|
||||
const dom = uni.requireNativePlugin('dom');
|
||||
// #endif
|
||||
import bindingx from './bindingx.js'
|
||||
import mpjs from './mpjs.js'
|
||||
export default {
|
||||
name: "fui-horizontal-scroll",
|
||||
mixins: [mpjs, bindingx],
|
||||
emits: ['scrolltoupper', 'scrolltolower'],
|
||||
props: {
|
||||
marginTop: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
marginBottom: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
// 是否显示滚动条
|
||||
scroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 滚动条区域宽度/长度
|
||||
scrollWidth: {
|
||||
type: [String, Number],
|
||||
default: 96
|
||||
},
|
||||
// 滚动条的宽度
|
||||
scrollBarWidth: {
|
||||
type: [String, Number],
|
||||
default: 32
|
||||
},
|
||||
// 滚动区域/滚动条高度
|
||||
scrollHeight: {
|
||||
type: [String, Number],
|
||||
default: 8
|
||||
},
|
||||
//滚动条两端样式,可选值为 square、round
|
||||
scrollCap: {
|
||||
type: String,
|
||||
default: 'round'
|
||||
},
|
||||
scrollBarColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
background: {
|
||||
type: String,
|
||||
default: '#EEEEEE'
|
||||
},
|
||||
//自定义滚动条距离上方内容间距
|
||||
scrollGap: {
|
||||
type: [String, Number],
|
||||
default: 24
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
width: 0,
|
||||
//滚动条背景长度
|
||||
bgWidth: 0,
|
||||
//滚动条滑块长度
|
||||
blockWidth: 0,
|
||||
blockHeight: 0,
|
||||
transform: '',
|
||||
isMounted: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.bgWidth = this.getPx(this.scrollWidth || 96)
|
||||
this.blockWidth = this.getPx(this.scrollBarWidth || 32)
|
||||
this.blockHeight = this.getPx(this.scrollHeight || 8)
|
||||
},
|
||||
mounted() {
|
||||
this.isMounted = true
|
||||
this.$nextTick(() => {
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
// #ifdef H5
|
||||
updated() {
|
||||
if(!this.isMounted && !this.width){
|
||||
setTimeout(() => {
|
||||
this.init()
|
||||
}, 0)
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
watch: {
|
||||
scrollWidth(val) {
|
||||
this.bgWidth = this.getPx(val || 96)
|
||||
},
|
||||
scrollBarWidth(val) {
|
||||
this.blockWidth = this.getPx(this.scrollBarWidth || 32)
|
||||
},
|
||||
scrollHeight(val) {
|
||||
this.blockHeight = this.getPx(this.scrollHeight || 8)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getStyles() {
|
||||
let style = `height:${this.blockHeight}px;width:${this.blockWidth}px;`
|
||||
let color = this.scrollBarColor;
|
||||
// #ifdef APP-NVUE
|
||||
if (!color || color === true) {
|
||||
const app = uni && uni.$fui && uni.$fui.color;
|
||||
color = (app && app.primary) || '#465CFF';
|
||||
}
|
||||
// #endif
|
||||
if (color && color !== true) {
|
||||
style += `background:${color};`
|
||||
}
|
||||
// #ifndef APP-PLUS || MP-WEIXIN
|
||||
style += `transform:${this.transform}`
|
||||
// #endif
|
||||
return style
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//如果初始化有误,可调用此方法重新初始化
|
||||
init() {
|
||||
setTimeout(() => {
|
||||
this._getSize()
|
||||
}, 80);
|
||||
},
|
||||
getPx(rpx) {
|
||||
let px = Math.floor(uni.upx2px(Number(rpx)));
|
||||
px = px % 2 === 0 ? px : px + 1
|
||||
return px;
|
||||
},
|
||||
scrollEvent(edge) {
|
||||
const event = edge === 'left' ? 'scrolltoupper' : 'scrolltolower'
|
||||
this.$emit(event)
|
||||
},
|
||||
_getSize() {
|
||||
// #ifndef APP-NVUE
|
||||
uni.createSelectorQuery()
|
||||
// #ifndef MP-ALIPAY
|
||||
.in(this)
|
||||
// #endif
|
||||
.select('.fui-horizontal__scroll')
|
||||
.boundingClientRect()
|
||||
.exec(ret => {
|
||||
if (ret) {
|
||||
this.width = ret[0].width || 0
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
dom.getComponentRect(this.$refs['fui_horizontal__scroll'], (ret) => {
|
||||
const size = ret.size
|
||||
if (size) {
|
||||
this.width = size.width
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* #ifndef APP-NVUE */
|
||||
::-webkit-scrollbar {
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
color: transparent !important;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
.fui-horizontal__scroll,
|
||||
.fui-hor__scroll-view,
|
||||
.fui-hor__scroll-wrap {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.fui-horizontal__scroll {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
/* #ifndef APP-NVUE */
|
||||
align-content: flex-start;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.fui-hor__scrollbar-wrap {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.fui-hor__scrollbar {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
/* #ifndef APP-NVUE */
|
||||
transform: translateZ(0);
|
||||
/* #endif */
|
||||
|
||||
}
|
||||
|
||||
.fui-hor__scroll-radius {
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.fui-hor__scroll-indicator {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
|
||||
}
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
.fui-hor__scroll-bg {
|
||||
background-color: var(--fui-color-primary, #465CFF) !important;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
</style>
|
39
components/firstui/fui-horizontal-scroll/index.wxs
Normal file
39
components/firstui/fui-horizontal-scroll/index.wxs
Normal file
@ -0,0 +1,39 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 186140 7 2 549,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
function scroll(event, ownerInstance) {
|
||||
var detail = event.detail
|
||||
var scrollWidth = detail.scrollWidth
|
||||
var scrollLeft = detail.scrollLeft
|
||||
var dataset = event.currentTarget.dataset
|
||||
var width = dataset.width || 0
|
||||
var scrollBarWidth = dataset.bgwidth || 0
|
||||
var blockWidth = dataset.blockwidth || 0
|
||||
var x = scrollLeft / (scrollWidth - width) * (scrollBarWidth - blockWidth)
|
||||
setBarStyle(ownerInstance, x)
|
||||
}
|
||||
|
||||
function scrolltolower(event, ownerInstance) {
|
||||
ownerInstance.callMethod('scrollEvent', 'right')
|
||||
var dataset = event.currentTarget.dataset
|
||||
var scrollBarWidth = dataset.bgwidth || 0
|
||||
var blockWidth = dataset.blockwidth || 0
|
||||
setBarStyle(ownerInstance, scrollBarWidth - blockWidth)
|
||||
}
|
||||
|
||||
function scrolltoupper(event, ownerInstance) {
|
||||
ownerInstance.callMethod('scrollEvent', 'left')
|
||||
setBarStyle(ownerInstance, 0)
|
||||
}
|
||||
|
||||
function setBarStyle(ownerInstance, x) {
|
||||
var block = ownerInstance.selectComponent('.fui-hor__scroll-indicator')
|
||||
block && block.setStyle({
|
||||
transform: 'translate3d(' + x + 'px,0,0)'
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
scroll: scroll,
|
||||
scrolltolower: scrolltolower,
|
||||
scrolltoupper: scrolltoupper
|
||||
}
|
32
components/firstui/fui-horizontal-scroll/mpjs.js
Normal file
32
components/firstui/fui-horizontal-scroll/mpjs.js
Normal file
@ -0,0 +1,32 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 18 61407 2 549,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
// #ifndef APP-PLUS || MP-WEIXIN || H5
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
scrollHandler(event) {
|
||||
const detail = event.detail
|
||||
const scrollWidth = detail.scrollWidth
|
||||
const scrollLeft = detail.scrollLeft
|
||||
const width = this.width
|
||||
const scrollBarWidth = this.bgWidth
|
||||
const blockWidth = this.blockWidth
|
||||
const x = scrollLeft / (scrollWidth - width) * (scrollBarWidth - blockWidth)
|
||||
this.transform = `translate3d(${x}px,0,0)`
|
||||
},
|
||||
scrolltoupper(event) {
|
||||
this.scrollEvent('left')
|
||||
this.transform = 'translate3d(0,0,0)'
|
||||
},
|
||||
scrolltolower(event) {
|
||||
this.scrollEvent('right')
|
||||
const x = this.bgWidth - this.blockWidth
|
||||
this.transform = `translate3d(${x}px,0,0)`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS|| MP-WEIXIN || H5
|
||||
export default {}
|
||||
// #endif
|
Reference in New Issue
Block a user