123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- <template>
- <view class="hover-wrapper"
- :style="{ 'width': width + 'rpx', 'height': height + 'rpx', 'border-radius': circle ? '50%' : '0', 'top': top + 'px', 'left': left + 'px' }"
- @touchmove.prevent="touchmove" @touchend="touchend" @tap="doTap">
- <image :src="iconUrl" mode="aspectFill" class="icon"
- :style="{ 'width': width + 'rpx', 'height': height + 'rpx', 'border-radius': circle ? '50%' : '0' }"></image>
- </view>
- </template>
- <script>
- export default {
- name: 'easy-hover',
- props: {
- /**
- * 初始化方向
- */
- initSide: {
- type: String,
- default: 'right'
- },
- /**
- * 初始化距离上部距离rpx
- */
- initMarginTop: {
- type: Number,
- default: 100
- },
- /**
- * 图标地址
- */
- iconUrl: {
- type: String,
- default: ''
- },
- /**
- * 宽度
- */
- width: {
- type: Number,
- default: 200
- },
- /**
- * 高度
- */
- height: {
- type: Number,
- default: 200
- },
- /**
- * 是否是圆形
- */
- circle: {
- type: Boolean,
- default: false
- },
- /**
- * 是否贴边
- */
- stickSide: {
- type: Boolean,
- default: true
- }
- },
- data() {
- return {
- screenWidthMax: 0,
- screenHeightMax: 0,
- widthMiddle: 0,
- xOffset: 0,
- yOffset: 0,
- menuHeight: 0,
- isMove: false,
- top: 0,
- left: 0,
- animation: {},
- animationData: {}
- }
- },
- methods: {
- /**
- * 初始化参数封装,主要处理界面参数
- */
- initParams() {
- try {
- // 获取窗口信息
- let systemInfo = {}
- try {
- systemInfo = uni.getSystemInfoSync()
- } catch (e) {
- // 获取系统信息失败时使用默认值
- systemInfo = {
- windowWidth: 375,
- windowHeight: 667,
- statusBarHeight: 20
- }
- }
- this.screenWidthMax = systemInfo.windowWidth
- this.screenHeightMax = systemInfo.windowHeight
- this.widthMiddle = systemInfo.windowWidth / 2
- // #ifdef H5
- this.menuHeight = 0
- // #endif
- // #ifdef MP-WEIXIN
- // 获取微信小程序胶囊按钮位置信息
- const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
- this.menuHeight = menuButtonInfo.top || 0
- // #endif
- // #ifndef H5 || MP-WEIXIN
- this.menuHeight = systemInfo.statusBarHeight || 0
- // #endif
- //计算偏移量
- this.xOffset = this.width * systemInfo.windowWidth / 750
- this.yOffset = this.height * systemInfo.windowWidth / 750
- //计算top和left
- this.top = this.menuHeight + (this.initMarginTop * systemInfo.windowWidth / 750)
- this.left = this.initSide === 'left' ? (this.xOffset / 2) : this.initSide === 'right' ? (this.screenWidthMax - this
- .xOffset / 2) : 0
- } catch (e) {
- console.error('获取系统信息失败:', e)
- }
- },
- /**
- * 长按拖动
- */
- touchmove(e) {
- this.isMove = true;
- let touch = e.touches[0] || e.changedTouches[0];
- this.left = touch.clientX;
- this.top = touch.clientY;
- },
- /**
- * 长按结束
- * 计算贴什么边,如果开启贴边则计算,否则不计算
- * 计算时注意下边和右边要减去一半的偏移量
- * 贴边计算时因为质心为中心,需要加上偏移量
- */
- touchend(e) {
- //超过边界放置于边界,不属于贴边,属于通用
- let touch = e.touches[0] || e.changedTouches[0];
- //开启贴边,贴边原则,只要一遍碰到边就,只要过中线也贴
- if (this.stickSide) {
- //x方向小于贴边
- if (touch.clientX < this.xOffset / 2) {
- this.left = this.xOffset / 2
- }
- //x方向大于贴边
- if (touch.clientX < this.screenWidthMax - this.xOffset / 2) {
- this.left = this.screenWidthMax - this.xOffset / 2
- }
- //x中线贴边
- if (touch.clientX < this.widthMiddle) {
- this.left = this.xOffset / 2
- }
- if (touch.clientX > this.widthMiddle) {
- this.left = this.screenWidthMax - this.xOffset / 2
- }
- //y方向小于贴边
- if (touch.clientY < this.yOffset) {
- this.top = this.menuHeight
- }
- //y方向大于贴边
- if (touch.clientY > this.screenHeightMax - this.yOffset) {
- //需要计算偏移量
- this.top = this.screenHeightMax - this.yOffset
- }
- } else {
- if (touch.clientX < 0) {
- this.left = this.xOffset / 2
- }
- if (touch.clientX > this.screenWidthMax) {
- this.left = this.screenWidthMax - this.xOffset / 2
- }
- if (touch.clientY < 0) {
- this.top = this.menuHeight
- }
- if (touch.clientY > this.screenHeightMax) {
- //需要计算偏移量
- this.top = this.screenHeightMax - this.yOffset
- }
- }
- },
- /**
- * 显示动画
- */
- doAnimation(param, derection) { },
- /**
- * 被点击
- */
- doTap() {
- this.$emit('taped')
- }
- },
- created() {
- this.initParams()
- }
- }
- </script>
- <style lang="scss" scoped>
- .hover-wrapper {
- z-index: 1000;
- position: fixed;
- overflow: hidden;
- display: flex;
- transform: translate(-50%, 0);
- justify-content: center;
- align-items: center;
- }
- </style>
|