You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
6.1 KiB
292 lines
6.1 KiB
const BindingX = uni.requireNativePlugin('bindingx'); |
|
const dom = uni.requireNativePlugin('dom'); |
|
const animation = uni.requireNativePlugin('animation'); |
|
|
|
export default { |
|
data() { |
|
return {} |
|
}, |
|
|
|
watch: { |
|
show(newVal) { |
|
if (this.autoClose) return |
|
if (this.stop) return |
|
this.stop = true |
|
if (newVal) { |
|
this.open(newVal) |
|
} else { |
|
this.close() |
|
} |
|
}, |
|
leftOptions() { |
|
this.getSelectorQuery() |
|
this.init() |
|
}, |
|
rightOptions(newVal) { |
|
this.init() |
|
} |
|
}, |
|
created() { |
|
if (this.swipeaction.children !== undefined) { |
|
this.swipeaction.children.push(this) |
|
} |
|
}, |
|
mounted() { |
|
this.box = this.getEl(this.$refs['selector-box--hock']) |
|
this.selector = this.getEl(this.$refs['selector-content--hock']); |
|
this.leftButton = this.getEl(this.$refs['selector-left-button--hock']); |
|
this.rightButton = this.getEl(this.$refs['selector-right-button--hock']); |
|
this.init() |
|
}, |
|
beforeDestroy() { |
|
this.swipeaction.children.forEach((item, index) => { |
|
if (item === this) { |
|
this.swipeaction.children.splice(index, 1) |
|
} |
|
}) |
|
}, |
|
methods: { |
|
init() { |
|
this.$nextTick(() => { |
|
this.x = 0 |
|
this.button = { |
|
show: false |
|
} |
|
setTimeout(() => { |
|
this.getSelectorQuery() |
|
}, 200) |
|
}) |
|
}, |
|
onClick(index, item, position) { |
|
this.$emit('click', { |
|
content: item, |
|
index, |
|
position |
|
}) |
|
}, |
|
touchstart(e) { |
|
// 每次只触发一次,避免多次监听造成闪烁 |
|
if (this.stop) return |
|
this.stop = true |
|
if (this.autoClose) { |
|
this.swipeaction.closeOther(this) |
|
} |
|
|
|
const leftWidth = this.button.left.width |
|
const rightWidth = this.button.right.width |
|
let expression = this.range(this.x, -rightWidth, leftWidth) |
|
let leftExpression = this.range(this.x - leftWidth, -leftWidth, 0) |
|
let rightExpression = this.range(this.x + rightWidth, 0, rightWidth) |
|
|
|
this.eventpan = BindingX.bind({ |
|
anchor: this.box, |
|
eventType: 'pan', |
|
props: [{ |
|
element: this.selector, |
|
property: 'transform.translateX', |
|
expression |
|
}, { |
|
element: this.leftButton, |
|
property: 'transform.translateX', |
|
expression: leftExpression |
|
}, { |
|
element: this.rightButton, |
|
property: 'transform.translateX', |
|
expression: rightExpression |
|
}, ] |
|
}, (e) => { |
|
// nope |
|
if (e.state === 'end') { |
|
this.x = e.deltaX + this.x; |
|
this.isclick = true |
|
this.bindTiming(e.deltaX) |
|
} |
|
}); |
|
}, |
|
touchend(e) { |
|
if (this.isopen !== 'none' && !this.isclick) { |
|
this.open('none') |
|
} |
|
}, |
|
bindTiming(x) { |
|
const left = this.x |
|
const leftWidth = this.button.left.width |
|
const rightWidth = this.button.right.width |
|
const threshold = this.threshold |
|
if (!this.isopen || this.isopen === 'none') { |
|
if (left > threshold) { |
|
this.open('left') |
|
} else if (left < -threshold) { |
|
this.open('right') |
|
} else { |
|
this.open('none') |
|
} |
|
} else { |
|
if ((x > -leftWidth && x < 0) || x > rightWidth) { |
|
if ((x > -threshold && x < 0) || (x - rightWidth > threshold)) { |
|
this.open('left') |
|
} else { |
|
this.open('none') |
|
} |
|
} else { |
|
if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) { |
|
this.open('right') |
|
} else { |
|
this.open('none') |
|
} |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* 移动范围 |
|
* @param {Object} num |
|
* @param {Object} mix |
|
* @param {Object} max |
|
*/ |
|
range(num, mix, max) { |
|
return `min(max(x+${num}, ${mix}), ${max})` |
|
}, |
|
|
|
/** |
|
* 开启swipe |
|
*/ |
|
open(type) { |
|
this.animation(type) |
|
}, |
|
|
|
/** |
|
* 关闭swipe |
|
*/ |
|
close() { |
|
this.animation('none') |
|
}, |
|
|
|
/** |
|
* 开启关闭动画 |
|
* @param {Object} type |
|
*/ |
|
animation(type) { |
|
const time = 300 |
|
const leftWidth = this.button.left.width |
|
const rightWidth = this.button.right.width |
|
if (this.eventpan && this.eventpan.token) { |
|
BindingX.unbind({ |
|
token: this.eventpan.token, |
|
eventType: 'pan' |
|
}) |
|
} |
|
|
|
switch (type) { |
|
case 'left': |
|
Promise.all([ |
|
this.move(this.selector, leftWidth), |
|
this.move(this.leftButton, 0), |
|
this.move(this.rightButton, rightWidth * 2) |
|
]).then(() => { |
|
this.setEmit(leftWidth, type) |
|
}) |
|
break |
|
case 'right': |
|
Promise.all([ |
|
this.move(this.selector, -rightWidth), |
|
this.move(this.leftButton, -leftWidth * 2), |
|
this.move(this.rightButton, 0) |
|
]).then(() => { |
|
this.setEmit(-rightWidth, type) |
|
}) |
|
break |
|
default: |
|
Promise.all([ |
|
this.move(this.selector, 0), |
|
this.move(this.leftButton, -leftWidth), |
|
this.move(this.rightButton, rightWidth) |
|
]).then(() => { |
|
this.setEmit(0, type) |
|
}) |
|
|
|
} |
|
}, |
|
setEmit(x, type) { |
|
const leftWidth = this.button.left.width |
|
const rightWidth = this.button.right.width |
|
this.isopen = this.isopen || 'none' |
|
this.stop = false |
|
this.isclick = false |
|
// 只有状态不一致才会返回结果 |
|
if (this.isopen !== type && this.x !== x) { |
|
if (type === 'left' && leftWidth > 0) { |
|
this.$emit('change', 'left') |
|
} |
|
if (type === 'right' && rightWidth > 0) { |
|
this.$emit('change', 'right') |
|
} |
|
if (type === 'none') { |
|
this.$emit('change', 'none') |
|
} |
|
} |
|
this.x = x |
|
this.isopen = type |
|
}, |
|
move(ref, value) { |
|
return new Promise((resolve, reject) => { |
|
animation.transition(ref, { |
|
styles: { |
|
transform: `translateX(${value})`, |
|
}, |
|
duration: 150, //ms |
|
timingFunction: 'linear', |
|
needLayout: false, |
|
delay: 0 //ms |
|
}, function(res) { |
|
resolve(res) |
|
}) |
|
}) |
|
|
|
}, |
|
|
|
/** |
|
* 获取ref |
|
* @param {Object} el |
|
*/ |
|
getEl(el) { |
|
return el.ref |
|
}, |
|
/** |
|
* 获取节点信息 |
|
*/ |
|
getSelectorQuery() { |
|
Promise.all([ |
|
this.getDom('left'), |
|
this.getDom('right'), |
|
]).then((data) => { |
|
let show = 'none' |
|
if (this.autoClose) { |
|
show = 'none' |
|
} else { |
|
show = this.show |
|
} |
|
|
|
if (show === 'none') { |
|
// this.close() |
|
} else { |
|
this.open(show) |
|
} |
|
|
|
}) |
|
|
|
}, |
|
getDom(str) { |
|
return new Promise((resolve, reject) => { |
|
dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], (data) => { |
|
if (data) { |
|
this.button[str] = data.size |
|
resolve(data) |
|
} else { |
|
reject() |
|
} |
|
}) |
|
}) |
|
} |
|
} |
|
}
|
|
|