Slider.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <template>
  2. <div class="container"
  3. dir="rtl">
  4. <div class="slider-ui color2"
  5. dir="ltr">
  6. <input type="range"
  7. value="0"
  8. min="0"
  9. max="200"
  10. data-labels="0,10,20,35,50,80,100,150,200"
  11. data-positions="0,5,10,17.5,25,40,50,75,100">
  12. <ul class="slider-labels" />
  13. <div class="bar">
  14. <span class="min" />
  15. <span class="max" />
  16. </div>
  17. <div class="track">
  18. <div class="value" />
  19. </div>
  20. </div>
  21. <!-- <div id="slider-container" style="&#45;&#45;value:0.51;"><input type="range" id="slider" min="0" max="100" step="1"><div id="value">51</div><div id="slider-track"></div></div>-->
  22. </div>
  23. </template>
  24. <script>
  25. export default {
  26. name: 'Slider',
  27. mounted () {
  28. const sliders = document.querySelectorAll('.slider-ui')
  29. sliders.forEach(slider => {
  30. const input = slider.querySelector('input[type=range]')
  31. const min = input.getAttribute('min')
  32. const max = input.getAttribute('max')
  33. const valueElem = slider.querySelector('.value')
  34. const positions = input.getAttribute('data-positions').split(',')
  35. const labels = input.getAttribute('data-labels').split(',')
  36. const sliderLabels = slider.querySelector('.slider-labels')
  37. positions.forEach((value, index) => {
  38. const li = document.createElement('li')
  39. li.innerHTML = labels[index]
  40. li.style.left = 'calc( ' + value + '% - 12px)'
  41. sliderLabels.appendChild(li)
  42. })
  43. slider.querySelector('.min').innerText = min
  44. slider.querySelector('.max').innerText = max
  45. function setValueElem () {
  46. valueElem.innerText = input.value
  47. const percent = (input.value - min) / (max - min) * 100
  48. valueElem.style.left = percent + '%'
  49. }
  50. // function setSliderOnStep () {
  51. // if (input.value < 10) {
  52. // input.value = 0
  53. // } else if (input.value > 10 && input.value < 20) {
  54. // input.value = 20
  55. // } else if (input.value > 20 && input.value < 35) {
  56. // input.value = 35
  57. // } else if (input.value > 35 && input.value < 50) {
  58. // input.value = 50
  59. // } else if (input.value > 50 && input.value < 80) {
  60. // input.value = 80
  61. // } else if (input.value > 80 && input.value < 100) {
  62. // input.value = 100
  63. // } else if (input.value > 100 && input.value < 150) {
  64. // input.value = 150
  65. // } else if (input.value > 150 && input.value < 200) {
  66. // input.value = 200
  67. // }
  68. // setValueElem()
  69. // }
  70. setValueElem()
  71. input.addEventListener('input', setValueElem)
  72. input.addEventListener('mousedown', () => {
  73. valueElem.classList.add('up')
  74. })
  75. input.addEventListener('mouseup', () => {
  76. // setSliderOnStep()
  77. valueElem.classList.remove('up')
  78. })
  79. })
  80. }
  81. }
  82. </script>
  83. <style>
  84. #slider-container {
  85. --value : 0 ;
  86. --slider-track-color : #B0EFEF45 ;
  87. --slider-thumb-color : #fff ;
  88. --slider-fill-color : #31D3C6 ;
  89. --slider-fill2-color : #00A2BB ;
  90. width : 100% ;
  91. height: 1rem ;
  92. display: flex ;
  93. align-items: center ;
  94. justify-content: center ;
  95. padding: 0 ;
  96. margin: 0 ;
  97. animation: color-cycle 1s infinite alternate linear;
  98. }
  99. @keyframes color-cycle {
  100. 0% {
  101. --slider-fill-color : #31D3C6 ;
  102. }
  103. 100% {
  104. --slider-fill-color : #00A2BB ;
  105. }
  106. }
  107. #slider {
  108. -webkit-appearance: none;
  109. appearance: none;
  110. height: 1rem ;
  111. width: 100% ;
  112. margin : 0 ;
  113. padding: 0 ;
  114. background-color: #00000000 ;
  115. outline: none ;
  116. z-index: 99 ;
  117. }
  118. #slider-track {
  119. position: absolute ;
  120. top: calc(50% - 0.25rem);
  121. left: 0 ;
  122. width: 100% ;
  123. height: 0.5rem ;
  124. border-radius: 0.25rem ;
  125. background-color: var(--slider-track-color) ;
  126. overflow: hidden ;
  127. }
  128. #slider-track::before {
  129. position: absolute ;
  130. content: "" ;
  131. left: calc(-100% + 1.5rem) ;
  132. top : 0 ;
  133. width : calc(100% - 1rem) ;
  134. height: 100% ;
  135. background-color: var(--slider-fill-color) ;
  136. transition: background-color 300ms ease-out ;
  137. transform-origin: 100% 0%;
  138. transform: translateX(calc( var(--value) * 100% )) scaleX(1.2);
  139. }
  140. #slider::-webkit-slider-thumb {
  141. -webkit-appearance: none;
  142. appearance: none;
  143. width : 1rem ;
  144. height: 1rem ;
  145. border-radius: 50% ;
  146. background-color: var(--slider-thumb-color) ;
  147. cursor: pointer ;
  148. z-index: 99 ;
  149. border: 2px solid var(--slider-fill-color) ;
  150. transition: border-color 300ms ease-out ;
  151. }
  152. #value {
  153. position: absolute ;
  154. bottom: calc(100% + 0.5rem) ;
  155. left: calc( var(--value) * calc(100% - 1rem) - 0.8rem) ;
  156. min-width: 3ch ;
  157. border-radius: 4px ;
  158. pointer-events: none ;
  159. padding: 0.5rem ;
  160. display: flex ;
  161. align-items: center ;
  162. justify-content: center ;
  163. color: #FFF ;
  164. background-color: var(--slider-fill-color);
  165. opacity: 0 ;
  166. transition: left 300ms ease-out , opacity 300ms 300ms ease-out , background-color 300ms ease-out ;
  167. }
  168. #value::before {
  169. position: absolute ;
  170. content: "" ;
  171. top: 100% ;
  172. left: 50% ;
  173. width: 1rem ;
  174. height: 1rem ;
  175. border-radius: 2px ;
  176. background-color: inherit ;
  177. transform: translate(-50%,-80%) rotate(45deg);
  178. z-index: -1 ;
  179. }
  180. #slider-container:hover #value {
  181. opacity: 1 ;
  182. }
  183. </style>
  184. <style>
  185. .slider-labels {
  186. list-style: none;
  187. position: absolute;
  188. left: 15px;
  189. right: 15px;
  190. top: 0;
  191. }
  192. .slider-labels li {
  193. position: absolute;
  194. width: 30px;
  195. top: 15px;
  196. text-align: center;
  197. }
  198. .slider-ui {
  199. position: relative;
  200. width: 100%;
  201. height: 8px;
  202. margin: 70px 0;
  203. }
  204. .slider-ui input {
  205. position: absolute;
  206. z-index: 10;
  207. top: 0;
  208. bottom: 0;
  209. width: 100%;
  210. cursor: pointer;
  211. opacity: 0;
  212. }
  213. .slider-ui .bar {
  214. position: absolute;
  215. z-index: 1;
  216. left: 0;
  217. right: 0;
  218. top: 0;
  219. bottom: 0;
  220. background-color: #000;
  221. border-radius: 50px;
  222. box-shadow: 0 5px 0 rgba(0,0,0,.1);
  223. }
  224. .slider-ui .min,
  225. .slider-ui .max {
  226. position: absolute;
  227. z-index: 2;
  228. top: 50%;
  229. transform: translateY(-50%);
  230. font-size: 14px;
  231. font-weight: 800;
  232. color: #fff;
  233. display: none;
  234. }
  235. .slider-ui .min {
  236. left: 2%;
  237. }
  238. .slider-ui .max {
  239. right: 2%;
  240. }
  241. .slider-ui .track {
  242. position: absolute;
  243. z-index: 3;
  244. left: 15px;
  245. right: 15px;
  246. top: 0;
  247. bottom: 0;
  248. }
  249. .slider-ui .value {
  250. position: absolute;
  251. left: 50%;
  252. top: -17px;
  253. width: 40px;
  254. height: 40px;
  255. display: flex;
  256. justify-content: center;
  257. align-items: center;
  258. font-size: 14px;
  259. font-weight: 800;
  260. color: inherit;
  261. background-color: #fff;
  262. border: 4px solid #000;
  263. border-radius: 100%;
  264. box-sizing: border-box;
  265. transform: translateX(-50%);
  266. transition: top .3s ease-in-out, color .3s ease-in-out;
  267. }
  268. .slider-ui .value.up {
  269. top: -50px;
  270. color: #000;
  271. width: 50px;
  272. height: 50px;
  273. }
  274. .slider-ui.color1 .bar {
  275. background-color: #00b894;
  276. }
  277. .slider-ui.color1 .value {
  278. border-color: #00b894;
  279. }
  280. .slider-ui.color2 .bar {
  281. background-color: #00cec9;
  282. }
  283. .slider-ui.color2 .value {
  284. border-color: #00cec9;
  285. }
  286. .slider-ui.color3 .bar {
  287. background-color: #0984e3;
  288. }
  289. .slider-ui.color3 .value {
  290. border-color: #0984e3;
  291. }
  292. .youtube-link {
  293. position: fixed;
  294. left: 20px;
  295. bottom: 20px;
  296. color: #000;
  297. text-decoration: none;
  298. font-size: 12px;
  299. }
  300. </style>