1+ <script >
2+ import { createEventDispatcher , onMount , onDestroy } from " svelte"
3+
4+ export let value = 0
5+ export let cssStyle = ' '
6+ export let width = 100
7+ export let thumbHeight = 18
8+ export let height = 12
9+
10+ let emit = createEventDispatcher ()
11+ let startMove = false
12+ let input
13+
14+ let dx
15+
16+ function mouseDown (ev ) {
17+ startMove = true
18+ let _value = ev .offsetX / input .offsetWidth * 100
19+ value = _value
20+ dx = ev .offsetX
21+ emit (' mousedown' , _value)
22+ }
23+
24+ function mouseMove (ev ) {
25+ ev .stopPropagation ()
26+ if (! startMove) return
27+ dx += ev .movementX
28+ let _value = Math .min (100 , Math .max (0 , dx / input .offsetWidth * 100 ))
29+ value = _value
30+ emit (' mousemove' , value)
31+ }
32+
33+ function mouseUp () {
34+ if (startMove) {
35+ startMove = false
36+ dx = 0
37+ emit (' mouseup' , value)
38+ }
39+ }
40+
41+ onMount (() => {
42+ document .addEventListener (' mouseup' , mouseUp)
43+ document .addEventListener (' mousemove' , mouseMove, { passive: true , capture: true })
44+ })
45+
46+ onDestroy (() => {
47+ document .removeEventListener (' mousemove' , mouseMove)
48+ document .removeEventListener (' mouseup' , mouseUp)
49+ })
50+
51+ $: progressRaw = value / 100
52+ let scale = (width - 4 ) / width
53+
54+ </script >
55+
56+ <style >
57+ .container {
58+ --width : 100 ;
59+ width : calc (1px * var (--width ));
60+ --thumbHeight : 18 ;
61+ position : relative ;
62+ contain : paint;
63+ height : calc (var (--thumbHeight ) * 1px );
64+ }
65+
66+ .track {
67+ --progress : 0 ;
68+ --height : 12 ;
69+ position : absolute ;
70+ top : 50% ;
71+ left : 50% ;
72+ transform : translate (-50% , -50% );
73+ width : calc (100% - 2px );
74+ height : calc (var (--height ) * 1px );
75+ border-radius : 12px ;
76+ overflow : hidden ;
77+ }
78+
79+ .container > * , .track > * {
80+ pointer-events : none ;
81+ }
82+
83+ .thumb-box {
84+ width : 100% ;
85+ height : calc (var (--height ) * 1px );
86+ position : relative ;
87+ display : flex ;
88+ gap : 7px ;
89+ }
90+
91+ .thumb-box ::before {
92+ content : ' ' ;
93+ position : relative ;
94+ box-sizing : border-box ;
95+ left : 0 ;
96+ width : calc (var (--progress ) * var (--width ) * 1px - 3px );
97+ height : 100% ;
98+ border-radius : 12px 6px 6px 12px ;
99+ background-color : var (--controlColor );
100+ }
101+
102+ .thumb-box ::after {
103+ content : ' ' ;
104+ box-sizing : border-box ;
105+ position : relative ;
106+ right : 0 ;
107+ width : calc ((1 - var (--progress )) * var (--width ) * 1px - 3px );
108+ height : 100% ;
109+ border-radius : 6px 12px 12px 6px ;
110+ background-color : var (--controlBright );
111+ }
112+
113+ .divider {
114+ position : absolute ;
115+ box-sizing : border-box ;
116+ top : 50% ;
117+ left : calc (var (--progress ) * var (--scale ) * 100% + 2px );
118+ transform : translate (-50% , -50% );
119+ display : flex ;
120+ width : 1px ;
121+ border : solid 1px var (--controlBlack );
122+ height : calc (var (--thumbHeight ) * 1px );
123+ pointer-events : none ;
124+ }
125+ </style >
126+
127+ <div
128+ bind:this ={input }
129+ class =" container"
130+ style ="--width: {width }; --thumbHeight: {thumbHeight }; --scale: {scale }; {cssStyle }"
131+ on:mousedown ={mouseDown }
132+ on:mousemove ={mouseMove }
133+ >
134+ <div class ="track" style ="--height: {height }; --progress: {progressRaw };" >
135+ <div class =" thumb-box" />
136+ </div >
137+
138+ <div class ="divider" style ="--progress: {progressRaw };" />
139+ </div >
0 commit comments