FloatingBox.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <template>
  2. <div
  3. ref="box"
  4. :class="{
  5. 'floating-box': true,
  6. column
  7. }"
  8. :id="id"
  9. v-if="shown"
  10. :style="{
  11. width: width + 'px',
  12. height: height + 'px',
  13. top: top + 'px',
  14. left: left + 'px'
  15. }"
  16. @mousedown="onResizeBox"
  17. >
  18. <div class="box-header item-draggable" @mousedown="onDragBox">
  19. <slot name="header"></slot>
  20. </div>
  21. <div class="box-body">
  22. <slot name="body"></slot>
  23. </div>
  24. </div>
  25. </template>
  26. <script>
  27. export default {
  28. props: {
  29. id: { type: String, default: null },
  30. column: { type: Boolean, default: true }
  31. },
  32. data() {
  33. return {
  34. width: 200,
  35. height: 200,
  36. top: 0,
  37. left: 0,
  38. shown: false,
  39. pos1: 0,
  40. pos2: 0,
  41. pos3: 0,
  42. pos4: 0
  43. };
  44. },
  45. mounted() {
  46. if (this.id !== null && localStorage[`box:${this.id}`]) {
  47. const json = JSON.parse(localStorage.getItem(`box:${this.id}`));
  48. this.height = json.height;
  49. this.width = json.width;
  50. this.top = json.top;
  51. this.left = json.left;
  52. this.shown = json.shown;
  53. }
  54. },
  55. methods: {
  56. onDragBox(e) {
  57. const e1 = e || window.event;
  58. e1.preventDefault();
  59. this.pos3 = e1.clientX;
  60. this.pos4 = e1.clientY;
  61. document.onmousemove = e => {
  62. const e2 = e || window.event;
  63. e2.preventDefault();
  64. // calculate the new cursor position:
  65. this.pos1 = this.pos3 - e.clientX;
  66. this.pos2 = this.pos4 - e.clientY;
  67. this.pos3 = e.clientX;
  68. this.pos4 = e.clientY;
  69. // set the element's new position:
  70. this.top -= this.pos2;
  71. this.left -= this.pos1;
  72. };
  73. document.onmouseup = () => {
  74. document.onmouseup = null;
  75. document.onmousemove = null;
  76. this.saveBox();
  77. };
  78. },
  79. onResizeBox(e) {
  80. if (e.target !== this.$refs.box) return;
  81. document.onmouseup = () => {
  82. document.onmouseup = null;
  83. const { height, width } = e.target.style;
  84. this.height = Number(
  85. height
  86. .split("")
  87. .splice(0, height.length - 2)
  88. .join("")
  89. );
  90. this.width = Number(
  91. width
  92. .split("")
  93. .splice(0, width.length - 2)
  94. .join("")
  95. );
  96. this.saveBox();
  97. };
  98. },
  99. toggleBox() {
  100. this.shown = !this.shown;
  101. this.saveBox();
  102. },
  103. resetBox() {
  104. this.top = 0;
  105. this.left = 0;
  106. this.width = 200;
  107. this.height = 200;
  108. this.saveBox();
  109. },
  110. saveBox() {
  111. if (this.id === null) return;
  112. localStorage.setItem(
  113. `box:${this.id}`,
  114. JSON.stringify({
  115. height: this.height,
  116. width: this.width,
  117. top: this.top,
  118. left: this.left,
  119. shown: this.shown
  120. })
  121. );
  122. }
  123. }
  124. };
  125. </script>
  126. <style lang="scss">
  127. .night-mode .floating-box {
  128. background-color: var(--dark-grey-2) !important;
  129. border: 0 !important;
  130. .box-body b {
  131. color: var(--light-grey-2) !important;
  132. }
  133. }
  134. .floating-box {
  135. background-color: var(--white);
  136. color: var(--black);
  137. position: fixed;
  138. z-index: 10000000;
  139. resize: both;
  140. overflow: auto;
  141. border: 1px solid var(--light-grey-2);
  142. border-radius: 5px;
  143. padding: 10px;
  144. min-height: 50px !important;
  145. min-width: 50px !important;
  146. .box-header {
  147. z-index: 100000001;
  148. background-color: var(--primary-color);
  149. padding: 10px;
  150. display: block;
  151. height: 10px;
  152. width: 100%;
  153. }
  154. .box-body {
  155. display: flex;
  156. flex-wrap: wrap;
  157. justify-content: space-evenly;
  158. span {
  159. padding: 3px 6px;
  160. }
  161. }
  162. &.column .box-body {
  163. flex-flow: column;
  164. span {
  165. flex: 1;
  166. display: block;
  167. }
  168. }
  169. }
  170. </style>