drag-button.vue 3.4 KB

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