wk-drag-button.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <template>
  2. <view
  3. class="wk-drag-button"
  4. :style="{
  5. top: top + 'px',
  6. left: left + 'px',
  7. transition: transitionStyle
  8. }"
  9. @touchstart="handleTouchStart"
  10. @touchmove.stop.prevent="handleTouchMove"
  11. @touchend="handleTouchEnd"
  12. @click="handleClick">
  13. <slot />
  14. </view>
  15. </template>
  16. <script>
  17. export default {
  18. name: 'WkDragButton',
  19. props: {
  20. // 距离上有下左的安全距离
  21. padding: {
  22. type: String,
  23. default: '116 20 70 20'
  24. },
  25. // 初始位置距离底部的距离
  26. bottom: {
  27. type: Number,
  28. default: 70
  29. },
  30. width: {
  31. type: Number,
  32. default: uni.upx2px(100)
  33. },
  34. height: {
  35. type: Number,
  36. default: uni.upx2px(100)
  37. }
  38. },
  39. data() {
  40. return {
  41. timer: null,
  42. clientWidth: 0,
  43. clientHeight: 0,
  44. itemWidth: 0,
  45. itemHeight: 0,
  46. left: 0,
  47. top: 0,
  48. transitionStyle: 'none'
  49. }
  50. },
  51. computed: {
  52. // 安全距离
  53. safeArea() {
  54. return this.padding.split(' ')
  55. },
  56. dragStyle() {
  57. return {
  58. top: this.top + 'px',
  59. left: this.left + 'px',
  60. transition: this.transitionStyle
  61. }
  62. }
  63. },
  64. created() {
  65. this.initButton()
  66. },
  67. methods: {
  68. initButton() {
  69. const sysInfo = uni.getSystemInfoSync()
  70. this.clientWidth = sysInfo.windowWidth
  71. this.clientHeight = sysInfo.windowHeight
  72. // 设置位置
  73. this.left = this.clientWidth - this.width - this.safeArea[1]
  74. this.top = this.clientHeight - this.height - this.bottom
  75. },
  76. handleClick(evt) {
  77. this.$emit('click', evt)
  78. },
  79. handleTouchStart() {
  80. this.transitionStyle = 'none'
  81. },
  82. handleTouchMove(e) {
  83. const touch = e.changedTouches[0]
  84. this.left = touch.clientX - this.width / 2
  85. this.top = touch.clientY - this.height / 2
  86. },
  87. handleTouchEnd(e) {
  88. this.transitionStyle = 'all 0.3s'
  89. // 手指放开left位置
  90. if (this.left > this.clientWidth / 2) {
  91. this.left = this.clientWidth - this.width - this.safeArea[1]
  92. } else {
  93. this.left = this.safeArea[3]
  94. }
  95. // 手指放开top位置
  96. if (this.top < this.safeArea[0]) {
  97. this.top = this.safeArea[0]
  98. } else if (this.top > this.clientHeight - this.height - this.safeArea[2]) {
  99. // 不低于最低
  100. this.top = this.clientHeight - this.height - this.safeArea[2]
  101. }
  102. }
  103. }
  104. }
  105. </script>
  106. <style lang="scss">
  107. .wk-drag-button {
  108. position: fixed;
  109. z-index: 1;
  110. display: flex;
  111. justify-content: center;
  112. align-items: center;
  113. transition: all 0.3s;
  114. pointer-events: auto;
  115. }
  116. </style>