UNPKG

wx-mini-weview

Version:

weixin UI

291 lines (250 loc) 6.49 kB
const { WvComponentHandler } = require('../../behaviors/WvComponentHandler'); Component({ options: { styleIsolation: 'apply-shared', multipleSlots: true }, behaviors: [ WvComponentHandler({ handleMethods: { tap: { show: {}, hide: {} } } }), ], properties: { show: { type: Boolean, value: false, observer(newVal) { if (newVal) { this.show(); } else { this.hide(); } } }, // 滑出位置:'top', 'right', 'bottom', 'left' position: { type: String, value: 'bottom' }, // 尺寸设置 width: { type: String, value: '100%' // 固定值或vw或auto, 百分比无效 }, height: { type: String, value: '100%' // 固定值或vh或auto, 百分比无效 }, remainOffset: { type: String, value: '' // 为空时使用width/height,否则使用100vh/100vw减去此值 }, showHeader: { type: Boolean, value: true }, showFooter: { type: Boolean, value: false }, showMask: { type: Boolean, value: true }, maskClosable: { type: Boolean, value: true }, // z-index层级 zIndex: { type: Number, value: 9000 }, theme: { type: String, value: '' }, radius: { type: String, value: 'var(--wv-border-radius-huge)' }, closeIcon: { type: String, value: 'bi-x-lg' // 为空则不显示关闭按钮 }, // 关闭按钮位置:'top-right', 'top-left', 'bottom-right', 'bottom-left' closePosition: { type: String, value: 'top-right' }, enableEdgeGesture: { type: Boolean, value: false }, gestureAreaWidth: { type: Number, value: 20 } }, data: { gestureStart: null, gestureTriggered: false, calculatedWidth: '100%', calculatedHeight: '100%', visible: false }, observers: { 'position, width, height, remainOffset': function(position, width, height, remainOffset) { let calculatedWidth = width; let calculatedHeight = height; if (remainOffset) { if (position === 'left' || position === 'right') { calculatedWidth = `calc(100vw - ${remainOffset})`; } else if (position === 'top' || position === 'bottom') { calculatedHeight = `calc(100vh - ${remainOffset})`; } } this.setData({ calculatedWidth, calculatedHeight }); } }, lifetimes: { attached() { this.initGestureTrigger(); }, detached() { }, ready() { const that = this that.toast = that.selectComponent('#slidepanel-toast'); const position = that.data.position; const positionMap = { 'top': 'top', 'right': 'center-right', 'bottom': 'bottom', 'left': 'center-left' }; const toastPosition = positionMap[position] || 'bottom'; const animationMap = { 'top': { show: 'slide-top', hide: 'slide-top' }, 'right': { show: 'slide-right', hide: 'slide-right' }, 'bottom': { show: 'slide-bottom', hide: 'slide-bottom' }, 'left': { show: 'slide-left', hide: 'slide-left' } }; const animations = animationMap[position] that.toast.setData({ showAnimationType: animations.show, hideAnimationType: animations.hide, position: toastPosition, maskClosable: that.data.maskClosable, zIndex: that.data.zIndex, topOffset: '0rpx', rightOffset: '0rpx', bottomOffset: '0rpx', leftOffset: '0rpx', duration: 0 }); } }, methods: { catchTouchMove(e) { return false; }, show(callback = null) { const that = this that.toast.showSlot(0, callback); that.data.visible = true that.triggerEvent('show'); }, hide(callback = null) { if (this.toast) { this.toast.hide(() => { if (callback && typeof callback === 'function') { callback(); } }); } }, onClose() { this.data.visible = false this.triggerEvent('hide'); }, isVisible() { return this.data.visible; }, initGestureTrigger() { setTimeout(() => { this.setData({ gestureTriggered: false }); }, 100); }, onGestureTouchStart(e) { if (!this.data.enableEdgeGesture) return; this.setData({ gestureStart: { x: e.touches[0].clientX, y: e.touches[0].clientY, time: Date.now() } }); }, onGestureTouchMove(e) { if (!this.data.enableEdgeGesture || !this.data.gestureStart || this.data.gestureTriggered) return; const touch = e.touches[0]; const start = this.data.gestureStart; const deltaX = touch.clientX - start.x; const deltaY = touch.clientY - start.y; const deltaTime = Date.now() - start.time; const minDistance = 30; const maxTime = 300; switch (this.data.position) { case 'right': if (deltaX < -minDistance && Math.abs(deltaY) < Math.abs(deltaX) && deltaTime < maxTime) { this.triggerGestureShow(); } break; case 'left': if (deltaX > minDistance && Math.abs(deltaY) < Math.abs(deltaX) && deltaTime < maxTime) { this.triggerGestureShow(); } break; case 'bottom': if (deltaY < -minDistance && Math.abs(deltaX) < Math.abs(deltaY) && deltaTime < maxTime) { this.triggerGestureShow(); } break; case 'top': if (deltaY > minDistance && Math.abs(deltaX) < Math.abs(deltaY) && deltaTime < maxTime) { this.triggerGestureShow(); } break; } }, onGestureTouchEnd(e) { this.setData({ gestureStart: null }); }, triggerGestureShow() { if (this.data.gestureTriggered) return; this.setData({ gestureTriggered: true }, () => { this.show(); setTimeout(() => { this.setData({ gestureTriggered: false }); }, 1000); }); } } });