HTML
<div class="slider_bar">
<div class="slider_button">
<span id="slider_per">0%</span>
<img src="{src}" id="slider" />
</div>
</div>
๊ฐ๋จํ๊ฒ slider bar ์์ button์ ๋์๋ค. img๋ button ์์ ์์นํ๋ค.
span ์์๋ ๋๋ ์ ๋ ๋ช ํผ์ผํธ์ธ์ง ๋ํ๋ด๊ธฐ ์ํจ์ด๋ค.
CSS
.slider_bar {
display: flex;
position: fixed;
right: 5%;
top: 35%;
bottom: 20%;
width: 2%;
height: 40%;
background: linear-gradient(to bottom,
rgba(176, 196, 238, 1) 20%,
rgba(176, 196, 238, 0.75) 35%,
rgba(176, 196, 238, 0.5) 60%,
rgba(176, 196, 238, 0.25) 85%,
rgba(176, 196, 238, 0) 100%);
border-radius: 20px;
justify-content: center;
}
.slider_bar img {
height: 30px;
width: 30px;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;
}
.slider_bar span {
display: none;
position: absolute;
left: -50px;
width: 40px;
height: 30px;
border-radius: 10px;
color: #FFFFFF;
background-color: #8e8989;
padding: 0 auto;
align-items: center;
justify-content: center;
font-weight: 400;
transition-duration: all 2s;
}
.slider_button {
display: flex;
width: 40px;
height: 40px;
position: absolute;
bottom: 0;
border-radius: 50%;
background-color: #FFFFFF;
text-align: center;
font-weight: 900;
color: gray;
line-height: 7px;
justify-content: center;
align-items: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none
}
css์ ์ค์ํ ์ ์, slider button์ bottom๊ฐ์ ์ฃผ์ด์ slider bar์์ ์ผ๋ง๋ ๋จ์ด์ ธ ์๋๋ฅผ ๊ธฐ๋กํ๋ ๊ฒ์ด๋ค. ๋๋จธ์ง๋ ์์ ๋กญ๊ฒ ์ค์ ํ๋ฉด ๋๋ค.
JS
var slider_button = document.getElementsByClassName("slider_button")[0];
var percent = document.getElementById('slider_per');
//ํฐ์น๊ฐ ์์๋ ๋
slider_button.addEventListener("touchstart", (e) => {
percent.style.display = "flex"; // ํฐ์น๊ฐ ์์๋๋ฉด ํผ์ผํธ ๋ณด์ด๊ธฐ
startPoint = e.touches[0].pageY; // ํฐ์น๊ฐ ์์๋๋ ์์น ์ ์ฅ
});
//ํฐ์น๊ฐ ์์ง์ผ ๋
slider_button.addEventListener("touchmove", (e) => {
//์๋ bottom ๊ฐ
let origin = parseInt(getComputedStyle(slider_button).bottom.slice(0, -2));
//์ต๊ณ ๋์ด
let max_height = parseInt(getComputedStyle(slider_bar).height);
//์์ ์ง์ ๊ณผ ์ฌ์ฉ์ ํฐ์น์์ ์ฌ์ด ๊ฐ
diff = parseInt(startPoint - e.touches[0].pageY);
//
if (((origin + (diff - pre)) > 0) && ((origin + (diff - pre)) <= max_height)) {
slider_button.style.bottom = origin + (diff - pre) + "px"; // ์๋ ๊ฐ + (์ฐจ์ด - ์ด์ ๊ฐ)
// + ์ฌ๋ผ์ด๋๊ฐ ์ฌ๋ผ๊ฐ ๋ ์๊ธธ ๋ณํ๋ฅผ ์ฌ๊ธฐ์
}
pre = diff; // ์ด์ ๊ฐ ์ ์ฅ
// bottom ๊ฐ
let bottom_height = parseInt(getComputedStyle(slider_button).bottom);
// ํผ์ผํธ ๊ฐ ๋ณ๊ฒฝ
percent.innerText = parseInt(bottom_height / parseInt(max_height) * 100) + "%";
});
//ํฐ์น๊ฐ ๋๋ฌ์ ๋
slider_button.addEventListener("touchend", (e) => {
pre = 0; //์ด์ ๊ฐ์ 0์ผ๋ก ์ด๊ธฐํ
percent.style.display = "none"; //ํผ์ผํธ ๊ฐ ๊ฐ๋ฆฌ๊ธฐ
});
- ํฐ์น๊ฐ ์์๋๋ฉด ์์๋ ๊ฐ์ ์ ์ฅํ๋ค.
- ํฐ์น๊ฐ ์์ง์ด๋ฉด, ํฐ์น ์์ ์ ๊ณผ ํ์ฌ ์ฌ์ฉ์๊ฐ ํฐ์นํ๊ณ ์๋ Y๊ฐ์ ๋น๊ตํ๊ณ , ๊ทธ ์ฐจ์ด๋ฅผ ์ ์ฅํ๋ค.
- ๋ค์์ ๊ฒ์ฌํ๋ค :
3-1. ์๋ bottom ๊ฐ + (์ฐจ์ด - ์ด์ ๊ฐ) ์ด 0๋ณด๋ค ํฐ์ง
3-2. ์๋ bottom ๊ฐ + (์ฐจ์ด - ์ด์ ๊ฐ) ์ด ์ต๊ณ ๋์ด๋ณด๋ค ์์ ์ง
-> ํ ๋ง๋๋ก ์ฌ๋ผ์ด๋ ๋ฒํผ์ด ์์ ์์น๊ฐ ์ฌ๋ผ์ด๋ ๋ฐ ์์ ์์ด๋ ๋๋์ง๋ฅผ ๊ฒ์ฌํ๋ค. - ๊ฒ์ฌ๊ฐ ํต๊ณผ๋๋ฉด ์ฌ๋ผ์ด๋ ๋ฒํผ์ bottom ๊ฐ์ ์๋ ๊ฐ + (์ฐจ์ด - ์ด์ ๊ฐ) px๋งํผ์ผ๋ก ์ค์ ํ๋ค.
- ์ด์ ๊ฐ ๋ณ์์ ํ์ฌ ๊ฐ์ ์ ์ฅํ๋ค.
- ํฐ์น๊ฐ ๋๋๋ฉด, ์ด์ ๊ฐ์ 0์ผ๋ก ์ด๊ธฐํํ๊ณ , ํผ์ผํธ ๊ฐ์ ๊ฐ๋ฆฐ๋ค.
๋ด ๊ฒฝํ ์ ์ด๋ ๊ฒ ๊ตฌํํ๋๊ฒ ๊ฐ์ฅ ๊น๋ํ๊ฒ ์์ง์ด๊ณ ์๋ํ๋ ๊ฒ ๊ฐ๋ค. ๐
'FrontEnd > HTML | JS | CSS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Vanilla JS] ๋ฐํ ์ํธ(Bottom Sheet) ๊ตฌํํ๊ธฐ (0) | 2023.09.02 |
---|---|
๋ทํ๋ฆญ์ค ๋์์ธ์ผ๋ก ํฌํธํด๋ฆฌ์ค ๋ง๋ค๊ธฐ (0) | 2023.09.01 |
๋ด๋ชจํผ์ฆ ์คํ์ผ๋ก ์กธ์ ์๊ฑด ๊ฒ์ฌ ์ฌ์ดํธ ์ ์ํ๊ธฐ (0) | 2023.09.01 |