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.
245 lines
5.5 KiB
245 lines
5.5 KiB
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() |
|
} |
|
}) |
|
} |
|
} |
|
} |
|
}
|
|
|