cm-drag.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <view
  3. id="_drag_button"
  4. class="cart-icon"
  5. :style="'left: ' + left + 'px; top:' + top + 'px;'"
  6. @touchstart="touchstart"
  7. @touchmove.stop.prevent="touchmove"
  8. @touchend="touchend"
  9. @click.stop.prevent="click"
  10. :class="{ transition: isDock && !isMove }"
  11. >
  12. <text v-if="cartNum > 0" class="badge">{{ cartNum >= 100 ? '99+' : cartNum }}</text>
  13. <text class="iconfont icon-gouwuche-mianxing"></text>
  14. </view>
  15. </template>
  16. <script>
  17. export default {
  18. name: 'drag-button',
  19. props: {
  20. cartNum: {
  21. type: Number,
  22. default: 0
  23. },
  24. isDock: {
  25. type: Boolean,
  26. default: false
  27. },
  28. existTabBar: {
  29. type: Boolean,
  30. default: false
  31. }
  32. },
  33. data() {
  34. return {
  35. StaticUrl: this.$Static,
  36. top: 300,
  37. left: 150,
  38. width: 0,
  39. height: 0,
  40. offsetWidth: 0,
  41. offsetHeight: 0,
  42. windowWidth: 0,
  43. windowHeight: 0,
  44. isMove: true,
  45. edge: 10
  46. }
  47. },
  48. created() {
  49. console.log(this.cartNum)
  50. },
  51. mounted() {
  52. const sys = uni.getSystemInfoSync()
  53. this.windowWidth = sys.windowWidth
  54. this.windowHeight = sys.windowHeight
  55. // #ifdef APP-PLUS
  56. this.existTabBar && (this.windowHeight -= 50)
  57. // #endif
  58. if (sys.windowTop) {
  59. this.windowHeight += sys.windowTop
  60. }
  61. // console.log(sys)
  62. const query = uni.createSelectorQuery().in(this)
  63. query
  64. .select('#_drag_button')
  65. .boundingClientRect(data => {
  66. this.width = data.width
  67. this.height = data.height
  68. this.offsetWidth = data.width / 2
  69. this.offsetHeight = data.height / 2
  70. this.left = this.windowWidth - this.width - this.edge - 5
  71. this.top = this.windowHeight - this.height - this.edge - 150
  72. })
  73. .exec()
  74. },
  75. methods: {
  76. click() {
  77. this.$emit('btnClick')
  78. },
  79. touchstart(e) {
  80. this.$emit('btnTouchstart')
  81. },
  82. touchmove(e) {
  83. // 单指触摸
  84. if (e.touches.length !== 1) {
  85. return false
  86. }
  87. this.isMove = true
  88. this.left = e.touches[0].clientX - this.offsetWidth
  89. let clientY = e.touches[0].clientY - this.offsetHeight
  90. // #ifdef H5
  91. clientY += this.height
  92. // #endif
  93. let edgeBottom = this.windowHeight - this.height - this.edge
  94. // 上下触及边界
  95. if (clientY < this.edge) {
  96. this.top = this.edge
  97. } else if (clientY > edgeBottom) {
  98. this.top = edgeBottom
  99. } else {
  100. this.top = clientY
  101. }
  102. },
  103. touchend(e) {
  104. if (this.isDock) {
  105. let edgeRigth = this.windowWidth - this.width - this.edge
  106. if (this.left < this.windowWidth / 2 - this.offsetWidth) {
  107. this.left = this.edge
  108. } else {
  109. this.left = edgeRigth
  110. }
  111. }
  112. this.isMove = false
  113. this.$emit('btnTouchend')
  114. }
  115. }
  116. }
  117. </script>
  118. <style lang="scss" scoped>
  119. .cart-icon {
  120. width: 92rpx;
  121. height: 92rpx;
  122. border-radius: 50%;
  123. background: rgba(0, 0, 0, 0.2);
  124. position: fixed;
  125. right: 24rpx;
  126. bottom: 28%;
  127. display: flex;
  128. align-items: center;
  129. justify-content: center;
  130. cursor: pointer;
  131. z-index: 20;
  132. line-height: 92rpx;
  133. text-align: center;
  134. .icon-gouwuche-mianxing {
  135. font-size: 56rpx;
  136. color: #ff457b;
  137. }
  138. .badge {
  139. @extend .cm-flex-center;
  140. font-size: 24rpx;
  141. position: absolute;
  142. top: -10rpx;
  143. right: 0;
  144. width: 40rpx;
  145. height: 40rpx;
  146. border-radius: 50%;
  147. background-color: #ff457b;
  148. color: #fff;
  149. }
  150. &.transition {
  151. transition: left 0.3s ease, top 0.3s ease;
  152. }
  153. }
  154. </style>