강의영상 : https://www.youtube.com/watch?v=V_G1WzPjb4o
깃허브 미리보기 : https://ohikmyeong.github.io/ot_clrProgress/
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
30
31
32
33
34
35
|
<!DOCTYPE html>
<html lang="en">
<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>Animated Circular Progress Bar Using Html CSS Only | Dynamic SVG Progress Bar</title>
<link rel="stylesheet" type="text/css" href="./css/style.css"/>
<script src="./js/main.js" type="module"></script>
</head>
<body>
<!-- https://www.youtube.com/watch?v=V_G1WzPjb4o -->
<div class="container">
<template>
<article class="card">
<div class="percent" style="--clr:#f404fc;--num:80;">
<div class="dot"></div>
<svg>
<circle cx="73" cy="75" r="68"></circle>
<circle cx="73" cy="75" r="68"></circle>
</svg>
<div class="number">
<h2>80</h2>
<p>Html</p>
</div>
</div><!-- percent -->
</article>
</template>
</div>
<script>
</script>
</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
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
|
@charset "utf-8";
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700;900&display=swap');
*{margin:0;padding:0;box-sizing:border-box;}
html,body{
font-family: 'Roboto', sans-serif;
color:#fff;
}
body{
display:flex; flex-flow:column nowrap;
justify-content:center; align-items:center;
width:100%;min-height:100vh;
background:#222; color:#fff;
}
.container{
display:flex; flex-flow:row wrap;
justify-content:center; align-items:center;
gap:40px;
position:relative;
width:min(calc(100% - 40px), 520px);
}
.card{
display:flex; flex-flow:row wrap;
justify-content:center; align-items:center;
position:relative;
/* width:max(220px,calc(50% - 40px)); */
/* aspect-ratio:1/1.13; */
width:220px; height:260px;
background:#2a2a2a;
}
.percent{
position:relative;
width:66%; aspect-ratio:1/1;
/* background:#fff; */
}
.percent svg{
position:relative;
/* width:100%;height:100%; */
width:150px;height:150px;
transform:rotate(270deg);
}
.percent svg circle{
width:100%;height:100%;
fill:transparent;
stroke-width:2;
stroke:#191919;
}
.percent svg circle:last-child{
stroke:var(--clr);
stroke-dasharray:440;
stroke-dashoffset: 440; /* 아무것도 안보이게 */
stroke-dashoffset: calc(440 - (440 * var(--num)) / 100);
animation: fadeIn .5s 2.5s linear both;
}
.dot{
position:absolute; z-index:10;
inset:5px;
/* 360deg / 100 = 3.6 */
animation: aniDot 2s linear forwards;
}
.dot::before{
content:'';display:block;position:absolute;
left:52%;
width:10px; aspect-ratio:1/1;
background:var(--clr);
border-radius:50%;
box-shadow: 0 0 10px var(--clr),
0 0 30px var(--clr);
}
.number{
position:absolute;
inset:0;
display:flex;flex-flow:column nowrap;
justify-content:center; align-items:center;
text-align:center;
animation: fadeIn 1s 2.8s linear both;
}
.number h2{font-size:2.5rem;}
.number h2::after{content:'%'; font-size:.5em; font-weight:300;}
.number p{font-size:0.875rem; text-transform:uppercase; margin-top:.25em; opacity:.75;}
@keyframes aniDot {
from{transform:rotate(0deg)}
to{transform:rotate(calc( 3.6deg * var(--num) ));}
}
@keyframes fadeIn {
from{opacity:0;}
to{opacity:1;}
}
|
cs |
JS-main.js
1
2
3
4
5
6
7
8
9
10
11
|
import { ClrProgress } from "./clrProgress.js";
const DATA = [
{name:"html",per:80,clr:"#04fc43"},
{name:"css",per:90,clr:"#04d7fc"},
{name:"js",per:85,clr:"#f0fc04"},
{name:"design",per:70,clr:"#f404fc"},
];
const clrProgress = new ClrProgress(DATA);
|
cs |
JS-clrProgress.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
|
export class ClrProgress{
constructor(data){
this.DATA = data;
this.$container = document.querySelector('.container');
//실행
this.init();
}//constructor
init(){
const $frag = document.createDocumentFragment();
for(let obj of this.DATA){
const $card = this.make_elem('ARTICLE','card');
const $percent = this.append_percent(obj);
this.append_dot($percent);
this.append_circle($percent);
this.append_number($percent, obj);
$card.appendChild($percent);
$frag.appendChild($card);
}
this.$container.appendChild($frag)
}//init
make_elem(elemType, className){
const $res = document.createElement(elemType);
className && $res.classList.add(className);
return $res
}//make_elem
add_text($elem,text){ $elem.textContent = text;}
append_percent(obj){
const{clr,per} = obj;
const $elem = this.make_elem('DIV','percent');
$elem.style.setProperty('--clr',clr);
$elem.style.setProperty('--num',per);
return $elem;
}//append_percent
append_dot($parent){
const $elem = this.make_elem('DIV','dot');
$parent.appendChild($elem);
}//append_dot
append_circle($parent){
const $svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
const $clr_1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
const $clr_2 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
const clr_data = {cx:73, cy:75, r:68};
this.set_circle($clr_1,clr_data);
this.set_circle($clr_2,clr_data);
$svg.appendChild($clr_1);
$svg.appendChild($clr_2);
$parent.appendChild($svg);
}//append_circle
append_number($parent,obj){
const {per,name} = obj;
const $number = this.make_elem('DIV','number');
this.appendPerName("H2",per,$number);
this.appendPerName("P",name,$number);
$parent.appendChild($number);
}//append_number
appendPerName(elemType,text,$parent){
const $elem = this.make_elem(elemType);
this.add_text($elem, text);
$parent.appendChild($elem);
}//appendPerName
set_circle($clr,data){
for(let key in data){ $clr.setAttribute(key, data[key]);}
}//set_circle
}//ClrProgress
|
cs |
'CSS&JS > 👀Study and Copy' 카테고리의 다른 글
WDS- Sortable Drag & Drop List (0) | 2022.08.09 |
---|---|
[WDS] CSS + JS Review Card (0) | 2022.08.08 |
[vanilla JS] 자바스크립트로 테트리스 만들기 (1) (0) | 2022.06.10 |
2048 클론코딩 (0) | 2022.06.07 |
getter,setter (0) | 2022.06.03 |