index.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <template>
  2. <div class="layer" @click="clickHandle($event)" ref="layer">
  3. <div class="percentage" :style="{width: left}"></div>
  4. <span class="bar" :style="{left: left}" ref="bar" @click.stop></span>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. props: {
  10. value: {
  11. type: Number | String,
  12. default: 1
  13. },
  14. min: {
  15. type:Number,
  16. default: 1
  17. },
  18. max: {
  19. type: Number,
  20. default: Infinity
  21. },
  22. isGradient:{
  23. type: Number,
  24. default: 0
  25. }
  26. },
  27. data() {
  28. let gradientArr = []
  29. if(this.max > this.isGradient){
  30. let temp = Array(Math.ceil(this.max / this.isGradient)).fill(0)
  31. gradientArr = temp.map((item,i)=>{
  32. return [i*this.isGradient,(i+1)*this.isGradient]
  33. })
  34. console.log(gradientArr);
  35. }
  36. return {
  37. current: Number(this.value),
  38. isLegal:this.max > this.isGradient && this.isGradient,
  39. gradientArr
  40. }
  41. },
  42. mounted() {
  43. this.downHandle = this.downHandle.bind(this)
  44. this.$refs.bar.addEventListener('mousedown', this.downHandle, false)
  45. this.$refs.bar.addEventListener('touchstart', this.downHandle, false)
  46. },
  47. beforeDestroy() {
  48. this.$refs.bar.removeEventListener('mousedown', this.downHandle, false)
  49. this.$refs.bar.removeEventListener('touchstart', this.downHandle, false)
  50. },
  51. methods: {
  52. toChangeNum(tmp){
  53. let fallInRange = [0,0]
  54. if (this.isLegal) {
  55. fallInRange = this.gradientArr.find(item=>{
  56. return tmp >= item[0] && tmp < item[1]
  57. })
  58. }
  59. if (tmp == 0 || tmp == this.max) {
  60. this.current = tmp
  61. return
  62. }
  63. if (this.isLegal) {
  64. if (fallInRange) {
  65. if (tmp >= ((fallInRange[1] + fallInRange[0]) / 2)) {
  66. return Number(fallInRange[1])
  67. } else {
  68. return Number(fallInRange[0])
  69. }
  70. } else {
  71. return Number(tmp)
  72. }
  73. } else {
  74. return Number(tmp)
  75. }
  76. },
  77. clickHandle(ev) {
  78. let tmp = this.min + this.len * (ev.offsetX / this.width)
  79. this.current = this.toChangeNum(tmp)
  80. },
  81. downHandle(ev) {
  82. let $layer = document.documentElement
  83. let startX = ev.pageX || ev.touches[0].pageX
  84. let initV = this.current
  85. let move = ev => {
  86. let tmp = initV - ((startX - (ev.pageX || ev.touches[0].pageX)) / this.width) * this.len
  87. this.current = this.toChangeNum(tmp)
  88. }
  89. let end = ev => {
  90. $layer.removeEventListener('touchmove', move, false)
  91. $layer.removeEventListener('touchend', end, false)
  92. $layer.removeEventListener('mousemove', move, false)
  93. $layer.removeEventListener('mouseup', end, false)
  94. }
  95. $layer.addEventListener('touchmove', move, false)
  96. $layer.addEventListener('touchend', end, false)
  97. $layer.addEventListener('mousemove', move, false)
  98. $layer.addEventListener('mouseup', end, false)
  99. this.$bus.once('player/mouseup', end)
  100. }
  101. },
  102. computed: {
  103. width() {
  104. return this.$refs.layer.offsetWidth
  105. },
  106. len() {
  107. return this.max - this.min
  108. },
  109. left() {
  110. return ((this.current - this.min) / this.len) * 100 + '%'
  111. }
  112. },
  113. watch: {
  114. current() {
  115. let current = Number(this.current ? this.current.toFixed(2) : this.current)
  116. if (current !== this.current) return this.current = current
  117. if (!this.current.toString()) {
  118. return this.current = 1
  119. }
  120. if (this.current < this.min) {
  121. return this.current = this.min
  122. } else if (this.current > this.max) {
  123. this.current = this.max
  124. }
  125. this.$emit('input', this.current)
  126. },
  127. value(newV, oldV) {
  128. if (newV !== this.current)
  129. console.log(newV);
  130. this.current = Number(newV)
  131. }
  132. }
  133. }
  134. </script>
  135. <style lang="less" scoped>
  136. .layer {
  137. margin: 10px 0;
  138. position: relative;
  139. width: 100%;
  140. height: 6px;
  141. cursor: pointer;
  142. border-radius: 3px;
  143. background: #1A1B1D;
  144. border: 1px solid #404040;
  145. >.percentage {
  146. height: 100%;
  147. background-color: @color;
  148. position: absolute;
  149. top: 0;
  150. left: 0;
  151. border-radius: 3px;
  152. }
  153. >.bar {
  154. position: absolute;
  155. height: 20px;
  156. width: 20px;
  157. background-color: #ffffff;
  158. position: absolute;
  159. border-radius: 50%;
  160. top: 50%;
  161. transform: translate(-50%, -50%);
  162. cursor: pointer;
  163. }
  164. }
  165. </style>