246 lines
5.8 KiB
JavaScript
246 lines
5.8 KiB
JavaScript
const BindingX = uni.requireNativePlugin('bindingx');
|
|
const dom = uni.requireNativePlugin('dom');
|
|
const animation = uni.requireNativePlugin('animation');
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
right: 0,
|
|
button: [],
|
|
preventGesture: false
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
show(newVal) {
|
|
if (!this.position || JSON.stringify(this.position) === '{}') return;
|
|
if (this.autoClose) return
|
|
if (this.isInAnimation) return
|
|
if (newVal) {
|
|
this.open()
|
|
} else {
|
|
this.close()
|
|
}
|
|
},
|
|
},
|
|
created() {
|
|
if (this.swipeaction.children !== undefined) {
|
|
this.swipeaction.children.push(this)
|
|
}
|
|
},
|
|
mounted() {
|
|
this.boxSelector = this.getEl(this.$refs['selector-box-hock']);
|
|
this.selector = this.getEl(this.$refs['selector-content-hock']);
|
|
this.buttonSelector = this.getEl(this.$refs['selector-button-hock']);
|
|
this.position = {}
|
|
this.x = 0
|
|
setTimeout(() => {
|
|
this.getSelectorQuery()
|
|
}, 200)
|
|
},
|
|
beforeDestroy() {
|
|
if (this.timing) {
|
|
BindingX.unbind({
|
|
token: this.timing.token,
|
|
eventType: 'timing'
|
|
})
|
|
}
|
|
if (this.eventpan) {
|
|
BindingX.unbind({
|
|
token: this.eventpan.token,
|
|
eventType: 'pan'
|
|
})
|
|
}
|
|
this.swipeaction.children.forEach((item, index) => {
|
|
if (item === this) {
|
|
this.swipeaction.children.splice(index, 1)
|
|
}
|
|
})
|
|
},
|
|
methods: {
|
|
onClick(index, item) {
|
|
this.$emit('click', {
|
|
content: item,
|
|
index
|
|
})
|
|
},
|
|
touchstart(e) {
|
|
if (this.isInAnimation) return
|
|
if (this.stop) return
|
|
this.stop = true
|
|
if (this.autoClose) {
|
|
this.swipeaction.closeOther(this)
|
|
}
|
|
let endWidth = this.right
|
|
let boxStep = `(x+${this.x})`
|
|
let pageX = `${boxStep}> ${-endWidth} && ${boxStep} < 0?${boxStep}:(x+${this.x} < 0? ${-endWidth}:0)`
|
|
|
|
let props = [{
|
|
element: this.selector,
|
|
property: 'transform.translateX',
|
|
expression: pageX
|
|
}]
|
|
|
|
let left = 0
|
|
for (let i = 0; i < this.options.length; i++) {
|
|
let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
|
|
if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
|
|
let moveMix = endWidth - left
|
|
left += this.button[i].width
|
|
let step = `(${this.x}+x)/${endWidth}`
|
|
let moveX = `(${step}) * ${moveMix}`
|
|
let pageButtonX = `${moveX}&& (x+${this.x} > ${-endWidth})?${moveX}:${-moveMix}`
|
|
props.push({
|
|
element: buttonSelectors,
|
|
property: 'transform.translateX',
|
|
expression: pageButtonX
|
|
})
|
|
}
|
|
|
|
this.eventpan = this._bind(this.boxSelector, props, 'pan', (e) => {
|
|
if (e.state === 'end') {
|
|
this.x = e.deltaX + this.x;
|
|
if (this.x < -endWidth) {
|
|
this.x = -endWidth
|
|
}
|
|
if (this.x > 0) {
|
|
this.x = 0
|
|
}
|
|
this.stop = false
|
|
this.bindTiming();
|
|
}
|
|
})
|
|
},
|
|
touchend(e) {
|
|
this.$nextTick(() => {
|
|
if (this.isopen && !this.isDrag && !this.isInAnimation) {
|
|
this.close()
|
|
}
|
|
})
|
|
},
|
|
bindTiming() {
|
|
if (this.isopen) {
|
|
this.move(this.x, -this.right)
|
|
} else {
|
|
this.move(this.x, -40)
|
|
}
|
|
},
|
|
move(left, value) {
|
|
if (left >= value) {
|
|
this.close()
|
|
} else {
|
|
this.open()
|
|
}
|
|
},
|
|
/**
|
|
* 开启swipe
|
|
*/
|
|
open() {
|
|
this.animation(true)
|
|
},
|
|
/**
|
|
* 关闭swipe
|
|
*/
|
|
close() {
|
|
this.animation(false)
|
|
},
|
|
/**
|
|
* 开启关闭动画
|
|
* @param {Object} type
|
|
*/
|
|
animation(type) {
|
|
this.isDrag = true
|
|
let endWidth = this.right
|
|
let time = 200
|
|
this.isInAnimation = true;
|
|
|
|
let exit = `t>${time}`;
|
|
let translate_x_expression = `easeOutExpo(t,${this.x},${type?(-endWidth-this.x):(-this.x)},${time})`
|
|
let props = [{
|
|
element: this.selector,
|
|
property: 'transform.translateX',
|
|
expression: translate_x_expression
|
|
}]
|
|
|
|
let left = 0
|
|
for (let i = 0; i < this.options.length; i++) {
|
|
let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
|
|
if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
|
|
let moveMix = endWidth - left
|
|
left += this.button[i].width
|
|
let step = `${this.x}/${endWidth}`
|
|
let moveX = `(${step}) * ${moveMix}`
|
|
let pageButtonX = `easeOutExpo(t,${moveX},${type ? -moveMix + '-' + moveX: 0 + '-' + moveX},${time})`
|
|
props.push({
|
|
element: buttonSelectors,
|
|
property: 'transform.translateX',
|
|
expression: pageButtonX
|
|
})
|
|
}
|
|
|
|
this.timing = BindingX.bind({
|
|
eventType: 'timing',
|
|
exitExpression: exit,
|
|
props: props
|
|
}, (e) => {
|
|
if (e.state === 'end' || e.state === 'exit') {
|
|
this.x = type ? -endWidth : 0
|
|
this.isInAnimation = false;
|
|
|
|
this.isopen = this.isopen || false
|
|
if (this.isopen !== type) {
|
|
this.$emit('change', type)
|
|
}
|
|
this.isopen = type
|
|
this.isDrag = false
|
|
}
|
|
});
|
|
},
|
|
/**
|
|
* 绑定 BindingX
|
|
* @param {Object} anchor
|
|
* @param {Object} props
|
|
* @param {Object} fn
|
|
*/
|
|
_bind(anchor, props, eventType, fn) {
|
|
return BindingX.bind({
|
|
anchor,
|
|
eventType,
|
|
props
|
|
}, (e) => {
|
|
typeof(fn) === 'function' && fn(e)
|
|
});
|
|
},
|
|
/**
|
|
* 获取ref
|
|
* @param {Object} el
|
|
*/
|
|
getEl(el) {
|
|
return el.ref
|
|
},
|
|
/**
|
|
* 获取节点信息
|
|
*/
|
|
getSelectorQuery() {
|
|
dom.getComponentRect(this.$refs['selector-content-hock'], (data) => {
|
|
if (this.position.content) return
|
|
this.position.content = data.size
|
|
})
|
|
for (let i = 0; i < this.options.length; i++) {
|
|
dom.getComponentRect(this.$refs['button-hock'][i], (data) => {
|
|
if (!this.button) {
|
|
this.button = []
|
|
}
|
|
if (this.options.length === this.button.length) return
|
|
this.button.push(data.size)
|
|
this.right += data.size.width
|
|
if (this.autoClose) return
|
|
if (this.show) {
|
|
this.open()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|