animationend 이벤트 리스너를 이용하여 아주 간단하게 만들 수 있다.
여기서 타이밍 조정은 CSS에서 가능하다는게 가장 큰 장점이다.
깃허브 : https://github.com/OhIkmyeong/time-slider
데모 : https://ohikmyeong.github.io/time-slider/
HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>타임슬라이더</title>
<link rel="stylesheet" type="text/css" href="./css/timeSlider.css">
<script src="./js/main.js" type="module"></script>
</head>
<body>
<h1>TimeSlider v1.0</h1>
<ul class="time-slider" id="timeSlider">
<li style="--bg-color:salmon">1</li>
<li style="--bg-color:orange">2</li>
<li style="--bg-color:yellow">3</li>
<li style="--bg-color:green">4</li>
<li style="--bg-color:royalblue">5</li>
<li style="--bg-color:purple">6</li>
</ul>
<footer>
<p>
참고 : 노비타 홈페이지 <a href="https://www.novita.co.kr/main" traget="blank">www.novita.co.kr</a>
</p>
</footer>
</body>
</html>
|
cs |
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
@charset "utf-8";
*{margin:0;padding:0;box-sizing:border-box;}
li{list-style-type:none;}
/* 📌[TIME SLIDER] */
.time-slider-wrap{
--gap:10px;
--time-ing:3s;
--time-end:1s;
--time-end-delay:.5s;
position:relative;
width:100vmin; aspect-ratio:2/1;
margin:0 auto;
border:1px solid black;
}
.time-slider{
position:relative; overflow:hidden;
width:100%; height:100%;
}
.time-slider-item{
display:flex; flex-flow:row wrap;
justify-content:center;align-items:center;
position:absolute;
top:0;left:0;
width:100%;height:100%;
background:var(--bg-color);
font-size:10vmin;
transition:opacity .3s .1s;
}
/* on */
.time-slider-item.off{
opacity:0;
pointer-events:none;
}
/* 타이머 */
.time-slider-time-wrap{
display:flex;
align-items:center;
gap:10px;
position:absolute;
left:0;bottom:0;
padding:var(--gap) calc(var(--gap) + var(--gap)/ 2);
background:rgba(0,0,0,.5);
font-size:20px; color:#fff;
}
.time-slider-time-bar-wrap{
position:relative; overflow:hidden;
width:150px; height:8px;
background:rgba(255,255,255,.1);
border:1px solid rgba(0,0,0,.1);
}
.time-slider-time-bar{
position:relative;
width:100%;height:100%;
background:rgb(255,255,255);
transform:translateX(calc(-100% + 1px));
}
.time-slider-time-bar.ing{
animation: timebarIng var(--time-ing) linear both;
}
.time-slider-time-bar.end{
animation: timebarEnd var(--time-end) var(--time-end-delay) ease-out both;
}
@keyframes timebarIng {
to{transform:translateX(0);}
}
@keyframes timebarEnd {
from{transform:translateX(0);}
to{transform:translateX(100%);}
}
|
cs |
main.js
1
2
3
4
5
6
|
import { TimeSlider } from "./timeSlider.js";
const $slider = document.getElementById('timeSlider');
const timeSlider = new TimeSlider();
timeSlider.init($slider);
|
cs |
timeSlider.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
/** time-slider */
export class TimeSlider{
/** time-slider */
constructor(){
this.DOM = new TimeSliderDomMaker(this)
this.CURR = 0;
this.LEN = null;
}//constructor
/**
* time-slider 생성 시작
* @param {DOM}$slider DOM
* */
init($slider){
this.DOM.init($slider);
}//init
update(){
this.DOM.hide_item(this.CURR);
this.update_curr_idx();
this.DOM.display_curr_idx();
}//update
update_curr_idx(){
this.CURR++;
if(this.CURR >= this.LEN){
this.CURR = 0;
this.DOM.show_all_item();
}
}//update_curr_idx
}//TimeSlider
class TimeSliderDomMaker{
constructor(CTRL){
this.CTRL = CTRL;
this.$slider = null;
this.$$item = null;
this.$wrap = null;
this.$timer = {
wrap : null,
curr : null,
all : null,
bar : null
}
}//constructor
init($slider){
this.$slider = $slider;
this.make_wrap();
this.order_reverse_item();
this.make_time_bar();
this.animate_time_bar();
}//init
/** .time-slider-wrap */
make_wrap(){
const $parent = this.$slider.parentElement;
this.$wrap = document.createElement("DIV");
this.$wrap.classList.add('time-slider-wrap');
const $all = this.$slider.nextElementSibling;
if(!$all){
$parent.appendChild(this.$wrap);
}else{
$parent.appendChild(this.$wrap);
$parent.insertBefore(this.$wrap,$all);
}
this.$wrap.appendChild(this.$slider);
}//make_wrap
order_reverse_item(){
this.$$item = Array.from(this.$slider.children);
this.CTRL.LEN = this.$$item.length;
for(let i=this.CTRL.LEN - 1; i >=0; i--){
this.$$item[i].classList.add('time-slider-item');
this.$slider.appendChild(this.$$item[i]);
}
}//order_reverse_item
make_time_bar(){
this.$timer.wrap = document.createElement('DIV');
this.$timer.curr = document.createElement('DIV');
this.$timer.all = document.createElement('DIV');
this.$timer.bar = document.createElement('DIV');
const $barWrap = document.createElement('DIV');
this.$timer.wrap.classList.add('time-slider-time-wrap');
this.$timer.curr.classList.add('time-slider-time-curr');
this.$timer.all.classList.add('time-slider-time-all');
this.$timer.bar.classList.add('time-slider-time-bar');
$barWrap.classList.add('time-slider-time-bar-wrap');
$barWrap.appendChild(this.$timer.bar);
this.display_curr_idx();
this.$timer.all.textContent = String(this.CTRL.LEN).padStart(2,"0");
this.$timer.wrap.appendChild(this.$timer.curr);
this.$timer.wrap.appendChild($barWrap);
this.$timer.wrap.appendChild(this.$timer.all);
this.$wrap.appendChild(this.$timer.wrap);
}//make_time_bar
display_curr_idx(){
const idx = String(this.CTRL.CURR + 1).padStart(2,"0");
this.$timer.curr.textContent = idx;
}//display_curr_idx
hide_item(idx){
this.$$item[idx].classList.add('off');
}//hide_item
show_all_item(){
this.$$item.forEach($item=>$item.classList.remove('off'));
}//show_item
ing_time_bar(){
this.$timer.bar.classList.remove('end');
this.$timer.bar.classList.add('ing');
}//ing_time_bar
end_time_bar(){
this.$timer.bar.classList.remove('ing');
this.$timer.bar.classList.add('end');
}//end_time_bar
animate_time_bar(){
this.ing_time_bar();
this.$timer.bar.addEventListener('animationend',()=>{
this.end_time_bar();
this.$timer.bar.addEventListener('animationend',()=>{
this.CTRL.update();
//재귀
this.animate_time_bar();
},{once:true});
},{once:true});
}//animate_time_bar
}//TimeSliderDomMaker
|
cs |
'CSS&JS > ⚡Thinkers' 카테고리의 다른 글
달력 만들기(3) + To Do List (0) | 2022.12.15 |
---|---|
[CSS,JS] 3d-carousel slider(캐러샐 슬라이더) (0) | 2022.10.24 |
[vanilla JS] 바닐라 자바스크립트로 무한 슬라이더 만들기. v1.0 (0) | 2022.10.11 |
[JS] vanilla JavaScript로 jQuery ui의 Draggable과 Resizable 구현하기 (0) | 2022.09.07 |
clipText (0) | 2022.07.25 |