FloatBtn.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <template>
  2. <div class="float-btn-wrap"
  3. :style="levitatedSpherePositionData"
  4. @mousedown.prevent="onSphereDown"
  5. @mouseup.prevent.stop="onSphereUp"
  6. @touchmove.prevent="touchmoveLevitatedSphere"
  7. @mousemove.prevent="touchmoveLevitatedSphere"
  8. @touchend="touchendLevitatedSphere"
  9. @mouseup="touchendLevitatedSphere"
  10. @mouseleave="touchendLevitatedSphere"
  11. @click.prevent.stop="clickHandler"
  12. >
  13. <div class="round-outside">
  14. <div class="round-small">
  15. <div class="status"></div>
  16. </div>
  17. </div>
  18. </div>
  19. </template>
  20. <script>
  21. export default {
  22. name: 'FloatBtn',
  23. props: {
  24. // 窗口尺寸 高
  25. width: {
  26. type: Number,
  27. default: 0
  28. },
  29. // 窗口尺寸 宽
  30. height: {
  31. type: Number,
  32. default: 0
  33. }
  34. },
  35. data() {
  36. return {
  37. // 悬浮球位置
  38. levitatedSpherePositionData: {},
  39. }
  40. },
  41. mounted() {
  42. this.initLevitatedSpherePositionData();
  43. },
  44. methods: {
  45. // 悬浮球初始化位置
  46. initLevitatedSpherePositionData() {
  47. // 从本地存储中获取悬浮球位置
  48. let levitatedSpherePositionData = localStorage.getItem('levitatedSpherePositionData');
  49. // 悬浮球位置
  50. this.levitatedSpherePositionData = levitatedSpherePositionData ? JSON.parse(levitatedSpherePositionData) : { left: '15px', top: '15px' }
  51. },
  52. // 悬浮球按下事件
  53. onSphereDown(e) {
  54. // 给元素设置鼠标按下状态
  55. e.target.isMousedown = true;
  56. e.preventDefault();
  57. },
  58. // 悬浮球抬起事件
  59. onSphereUp(e) {
  60. // 给元素设置鼠标按下状态
  61. e.target.isMousedown = false;
  62. e.preventDefault();
  63. },
  64. // 悬浮球移动
  65. touchmoveLevitatedSphere(e) {
  66. // 过滤未按下时的移动事件
  67. if (e.type === 'mousemove' && !e.target.isMousedown) return
  68. let pageX, pageY;
  69. if (e.type === 'mousemove' && e.target.isMousedown) {
  70. pageX = e.pageX;
  71. pageY = e.pageY;
  72. } else if (e.type === 'touchmove') {
  73. pageX = e.targetTouches[0].pageX;
  74. pageY = e.targetTouches[0].pageY;
  75. }
  76. let min = 20
  77. let MaxPageX = this.width - 20
  78. let MaxPageY = this.height - 20
  79. pageX = pageX <= min ? min : (pageX >= MaxPageX ? MaxPageX : pageX)
  80. pageY = pageY <= min ? min : (pageY >= MaxPageY ? MaxPageY : pageY)
  81. this.levitatedSpherePositionData = {
  82. left: `${pageX}px`,
  83. top: `${pageY}px`,
  84. transform: 'translate(-50%, -50%)'
  85. }
  86. e.preventDefault();
  87. },
  88. touchendLevitatedSphere(e) {
  89. localStorage.setItem('levitatedSpherePositionData', JSON.stringify(this.levitatedSpherePositionData))
  90. },
  91. // 点击悬浮球
  92. clickHandler(e){
  93. this.$emit('onClick');
  94. e.preventDefault();
  95. },
  96. }
  97. }
  98. </script>
  99. <style lang="scss" scoped>
  100. .float-btn-wrap{
  101. position: absolute;
  102. left: 15px;
  103. top: 15px;
  104. z-index: 1;
  105. .round-outside,
  106. .round-small,
  107. .status{
  108. border-radius: 50%;
  109. }
  110. .round-outside{
  111. padding: 4px;
  112. background-color: #4D4D4D;
  113. // 设置透明度
  114. opacity: 0.8;
  115. .round-small{
  116. padding: 4px;
  117. background-color: #A5A5A5;
  118. opacity: 0.8;
  119. .status{
  120. width: 20px;
  121. height: 20px;
  122. background-color: #EDEDED;
  123. opacity: 0.8;
  124. }
  125. }
  126. }
  127. }
  128. </style>