| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // nvueæä½domçåºï¼ç¨äºè·ådomçå°ºå¯¸ä¿¡æ¯ |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // nvueä¸ç¨äºæä½å
ç´ å¨ç»çåºï¼ç±»ä¼¼äºuni.animationï¼åªä¸è¿uni.animationä¸è½ç¨äºnvue |
| | | const animation = uni.requireNativePlugin('animation') |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | // æ¯å¦æ»å¨ä¸ |
| | | moving: false, |
| | | // ç¶æï¼open-æå¼ç¶æï¼close-å
³éç¶æ |
| | | status: 'close', |
| | | // å¼å§è§¦æ¸ç¹çXåYè½´åæ |
| | | startX: 0, |
| | | startY: 0, |
| | | // ææéèæé®çå°ºå¯¸ä¿¡æ¯æ°ç» |
| | | buttons: [], |
| | | // æææé®çæ»å®½åº¦ |
| | | buttonsWidth: 0, |
| | | // è®°å½ä¸ä¸æ¬¡ç§»å¨çä½ç½®å¼ |
| | | moveX: 0, |
| | | // è®°å½ä¸ä¸æ¬¡æ»å¨çä½ç½®ï¼ç¨äºåå两次å对æ¯ï¼å¦æç§»å¨çè·ç¦»å°äºæä¸éå¼ï¼å认为ååä¹é´æ²¡æç§»å¨ï¼ä¸ºäºè§£å³å¯è½åå¨çéä¿¡é»å¡é®é¢ |
| | | lastX: 0 |
| | | } |
| | | }, |
| | | computed: { |
| | | // è·åè¿æ¸¡æ¶é´ |
| | | getDuratin() { |
| | | let duration = String(this.duration) |
| | | // 妿ms为åä½ï¼è¿åmsçæ°å¼é¨å |
| | | if (duration.indexOf('ms') >= 0) return parseInt(duration) |
| | | // 妿s为åä½ï¼ä¸ºäºå¾å°msçæ°å¼ï¼éè¦ä¹ä»¥1000 |
| | | if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000 |
| | | // 妿å¼ä¼ äºæ°å¼ï¼ä¸å°äº30ï¼è®¤ä¸ºæ¯såä½ |
| | | duration = Number(duration) |
| | | return duration < 30 ? duration * 1000 : duration |
| | | } |
| | | }, |
| | | watch: { |
| | | show: { |
| | | immediate: true, |
| | | handler(n) { |
| | | // if(n === true) { |
| | | // uni.$u.sleep(50).then(() => { |
| | | // this.openSwipeAction() |
| | | // }) |
| | | // } else { |
| | | // this.closeSwipeAction() |
| | | // } |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | uni.$u.sleep(20).then(() => { |
| | | this.queryRect() |
| | | }) |
| | | }, |
| | | methods: { |
| | | close() { |
| | | this.closeSwipeAction() |
| | | }, |
| | | // 触æ¸åå
æ ¼ |
| | | touchstart(event) { |
| | | if (this.disabled) return |
| | | this.closeOther() |
| | | const { touches } = event |
| | | // è®°å½è§¦æ¸å¼å§ç¹çåæ å¼ |
| | | this.startX = touches[0].pageX |
| | | this.startY = touches[0].pageY |
| | | }, |
| | | // // è§¦æ¸æ»å¨ |
| | | touchmove(event) { |
| | | if (this.disabled) return |
| | | const { touches } = event |
| | | const { pageX } = touches[0] |
| | | const { pageY } = touches[0] |
| | | let moveX = pageX - this.startX |
| | | const moveY = pageY - this.startY |
| | | const { buttonsWidth } = this |
| | | const len = this.buttons.length |
| | | |
| | | // 夿åå两次çç§»å¨è·ç¦»ï¼å¦æå°äºä¸å®å¼ï¼åä¸è¿è¡ç§»å¨å¤ç |
| | | if (Math.abs(pageX - this.lastX) < 0.3) return |
| | | this.lastX = pageX |
| | | |
| | | // ç§»å¨çXè½´è·ç¦»å¤§äºYè½´è·ç¦»ï¼ä¹å³ç»ç¹ä¸èµ·ç¹ä½ç½®è¿çº¿ï¼ä¸X轴夹è§å°äº45度æ¶ï¼ç¦æ¢é¡µé¢æ»å¨ |
| | | if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > this.threshold) { |
| | | event.stopPropagation() |
| | | } |
| | | // å¦æç§»å¨çXè½´è·ç¦»å°äºYè½´è·ç¦»ï¼ä¹å³ç»ç¹ä½ç½®ä¸èµ·ç¹ä½ç½®è¿çº¿ï¼ä¸Y轴夹è§å°äº45度æ¶ï¼è®¤ä¸ºæ¯é¡µé¢ä¸ä¸æ»å¨ï¼è䏿¯å·¦å³æ»å¨åå
æ ¼ |
| | | if (Math.abs(moveX) < Math.abs(moveY)) return |
| | | |
| | | // éå¶å³æ»çè·ç¦»ï¼ä¸å
许å
容é¨åå¾å³åç§»ï¼å³æ»ä¼å¯¼è´Xè½´åç§»å¼å¤§äº0ï¼ä»¥æ¤å夿 |
| | | // æ¤å¤ä¸è½ç´æ¥returnï¼å 为æ»å¨è¿ç¨ä¸ä¼ç¼ºå¤±æäºå
³é®ç¹åæ ï¼ä¼å¯¼è´éä¹±ï¼æå¥½çåæ³å°±æ¯ |
| | | // å¨è¶
åºåï¼è®¾ç½®ä¸º0 |
| | | if (this.status === 'open') { |
| | | // å¨å¼å¯ç¶æä¸ï¼åå·¦æ»å¨ï¼éå¿½ç¥ |
| | | if (moveX < 0) moveX = 0 |
| | | // æ³è¦æ¶èµ·èåï¼æå¤§è½ç§»å¨çè·ç¦»ä¸ºæé®çæ»å®½åº¦ |
| | | if (moveX > buttonsWidth) moveX = buttonsWidth |
| | | // 妿æ¯å·²ç»æå¼äºçç¶æï¼åå·¦æ»å¨æ¶ï¼ç§»å¨æ¶èµ·èå |
| | | this.moveSwipeAction(-buttonsWidth + moveX) |
| | | } else { |
| | | // å
³éç¶æä¸ï¼å³æ»å¨éå¿½ç¥ |
| | | if (moveX > 0) moveX = 0 |
| | | // æ»å¨çè·ç¦»ä¸å
许è¶
è¿æææé®çæ»å®½åº¦ï¼æ¤æ¶åªè½æ¯å·¦æ»ï¼æç»è®¾ç½®æé®çæ»å®½åº¦ï¼åæ¶ä¸ºè´æ° |
| | | if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth |
| | | // åªè¦æ¯å¨æ»è¿ç¨ä¸ï¼å°±ä¸æç§»å¨èåçå
容é¨åï¼ä»è使éèçèåæ¾ç¤ºåºæ¥ |
| | | this.moveSwipeAction(moveX) |
| | | } |
| | | }, |
| | | // åå
æ ¼ç»æè§¦æ¸ |
| | | touchend(event) { |
| | | if (this.disabled) return |
| | | const touches = event.changedTouches ? event.changedTouches[0] : {} |
| | | const { pageX } = touches |
| | | const { pageY } = touches |
| | | const { buttonsWidth } = this |
| | | this.moveX = pageX - this.startX |
| | | if (this.status === 'open') { |
| | | // å¨å±å¼çç¶æä¸ï¼ç»§ç»å·¦æ»ï¼æ éæä½ |
| | | if (this.moveX < 0) this.moveX = 0 |
| | | if (this.moveX > buttonsWidth) this.moveX = buttonsWidth |
| | | // å¨å¼å¯ç¶æä¸ï¼ç¹å»ä¸ä¸å
容åºåï¼moveX为0ï¼ä¹å³æ²¡æè¿è¡ç§»å¨ï¼è¿æ¶æ§è¡æ¶èµ·èåé»è¾ |
| | | if (this.moveX === 0) { |
| | | return this.closeSwipeAction() |
| | | } |
| | | // å¨å¼å¯ç¶æä¸ï¼æ»å¨è·ç¦»å°äºéå¼ï¼åé»è®¤ä¸ºä¸å
³éï¼åæ¶æ¢å¤åæ¥çæå¼ç¶æ |
| | | if (Math.abs(this.moveX) < this.threshold) { |
| | | this.openSwipeAction() |
| | | } else { |
| | | // 妿æ»å¨è·ç¦»å¤§äºéå¼ï¼åæ§è¡æ¶èµ·é»è¾ |
| | | this.closeSwipeAction() |
| | | } |
| | | } else { |
| | | // å¨å
³éçç¶æä¸ï¼å³æ»ï¼æ éæä½ |
| | | if (this.moveX >= 0) this.moveX = 0 |
| | | if (this.moveX <= -buttonsWidth) this.moveX = -buttonsWidth |
| | | // çç±åä¸ |
| | | if (Math.abs(this.moveX) < this.threshold) { |
| | | this.closeSwipeAction() |
| | | } else { |
| | | this.openSwipeAction() |
| | | } |
| | | } |
| | | }, |
| | | // ç§»å¨æ»å¨éæ©å¨å
容åºåï¼åæ¶æ¾ç¤ºåºå
¶éèçèå |
| | | moveSwipeAction(moveX) { |
| | | if (this.moving) return |
| | | this.moving = true |
| | | |
| | | let previewButtonsMoveX = 0 |
| | | const len = this.buttons.length |
| | | animation.transition(this.$refs['u-swipe-action-item__content'].ref, { |
| | | styles: { |
| | | transform: `translateX(${moveX}px)` |
| | | }, |
| | | timingFunction: 'linear' |
| | | }, () => { |
| | | this.moving = false |
| | | }) |
| | | // æé®çç»çé¿åº¦ |
| | | for (let i = len - 1; i >= 0; i--) { |
| | | const buttonRef = this.$refs[`u-swipe-action-item__right__button-${i}`][0].ref |
| | | // éè¿æ¯ä¾ï¼å¾åºå
ç´ èªèº«è¯¥ç§»å¨çè·ç¦» |
| | | const translateX = this.buttons[i].width / this.buttonsWidth * moveX |
| | | // æç»ç§»å¨çè·ç¦»ï¼æ¯éè¿èªèº«æ¯ä¾ç®åºçè·ç¦»ï¼åå ä¸å¨å®ä¹åæææé®ç§»å¨çè·ç¦»ä¹å |
| | | const realTranslateX = translateX + previewButtonsMoveX |
| | | animation.transition(buttonRef, { |
| | | styles: { |
| | | transform: `translateX(${realTranslateX}px)` |
| | | }, |
| | | duration: 0, |
| | | delay: 0, |
| | | timingFunction: 'linear' |
| | | }, () => {}) |
| | | // è®°å½æ¬æé®ä¹åçæææé®çç§»å¨è·ç¦»ä¹å |
| | | previewButtonsMoveX += translateX |
| | | } |
| | | }, |
| | | // å
³éèå |
| | | closeSwipeAction() { |
| | | if (this.status === 'close') return |
| | | this.moving = true |
| | | const { buttonsWidth } = this |
| | | animation.transition(this.$refs['u-swipe-action-item__content'].ref, { |
| | | styles: { |
| | | transform: 'translateX(0px)' |
| | | }, |
| | | duration: this.getDuratin, |
| | | timingFunction: 'ease-in-out' |
| | | }, () => { |
| | | this.status = 'close' |
| | | this.moving = false |
| | | this.closeHandler() |
| | | }) |
| | | // æé®çç»çé¿åº¦ |
| | | const len = this.buttons.length |
| | | for (let i = len - 1; i >= 0; i--) { |
| | | const buttonRef = this.$refs[`u-swipe-action-item__right__button-${i}`][0].ref |
| | | // 妿䏿»¡è¶³è¾¹çæ¡ä»¶ï¼è¿å |
| | | if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return |
| | | |
| | | animation.transition(buttonRef, { |
| | | styles: { |
| | | transform: 'translateX(0px)' |
| | | }, |
| | | duration: this.getDuratin, |
| | | timingFunction: 'ease-in-out' |
| | | }, () => {}) |
| | | } |
| | | }, |
| | | // æå¼èå |
| | | openSwipeAction() { |
| | | if (this.status === 'open') return |
| | | this.moving = true |
| | | const buttonsWidth = -this.buttonsWidth |
| | | let previewButtonsMoveX = 0 |
| | | animation.transition(this.$refs['u-swipe-action-item__content'].ref, { |
| | | styles: { |
| | | transform: `translateX(${buttonsWidth}px)` |
| | | }, |
| | | duration: this.getDuratin, |
| | | timingFunction: 'ease-in-out' |
| | | }, () => { |
| | | this.status = 'open' |
| | | this.moving = false |
| | | this.openHandler() |
| | | }) |
| | | // æé®çç»çé¿åº¦ |
| | | const len = this.buttons.length |
| | | for (let i = len - 1; i >= 0; i--) { |
| | | const buttonRef = this.$refs[`u-swipe-action-item__right__button-${i}`][0].ref |
| | | // 妿䏿»¡è¶³è¾¹çæ¡ä»¶ï¼è¿å |
| | | if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return |
| | | // éè¿æ¯ä¾ï¼å¾åºå
ç´ èªèº«è¯¥ç§»å¨çè·ç¦» |
| | | const translateX = this.buttons[i].width / this.buttonsWidth * buttonsWidth |
| | | // æç»ç§»å¨çè·ç¦»ï¼æ¯éè¿èªèº«æ¯ä¾ç®åºçè·ç¦»ï¼åå ä¸å¨å®ä¹åæææé®ç§»å¨çè·ç¦»ä¹å |
| | | const realTranslateX = translateX + previewButtonsMoveX |
| | | animation.transition(buttonRef, { |
| | | styles: { |
| | | transform: `translateX(${realTranslateX}px)` |
| | | }, |
| | | duration: this.getDuratin, |
| | | timingFunction: 'ease-in-out' |
| | | }, () => {}) |
| | | previewButtonsMoveX += translateX |
| | | } |
| | | }, |
| | | // æ¥è¯¢æé®èç¹ä¿¡æ¯ |
| | | queryRect() { |
| | | // åéæææé®æ°ç»ï¼éè¿getRectByDomè¿åä¸ä¸ªpromise |
| | | const promiseAll = this.rightOptions.map((item, index) => this.getRectByDom(this.$refs[`u-swipe-action-item__right__button-${index}`][0])) |
| | | // éè¿promise.allæ¹æ³ï¼è®©æææé®çæ¥è¯¢ç»æè¿åä¸ä¸ªæ°ç»çå½¢å¼ |
| | | Promise.all(promiseAll).then((sizes) => { |
| | | this.buttons = sizes |
| | | // è®¡ç®æææé®æ»å®½åº¦ |
| | | this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0) |
| | | }) |
| | | }, |
| | | // éè¿nvueçdom模åï¼æ¥è¯¢èç¹ä¿¡æ¯ |
| | | getRectByDom(ref) { |
| | | return new Promise((resolve) => { |
| | | dom.getComponentRect(ref, (res) => { |
| | | resolve(res.size) |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | } |