네개의 컵에 단계가 다른 물을 준비한다.
1단계부터 4단계까지 있으며, 단계가 올라갈수록 컵에 물이 차오르고, 물의 색은 위험을 나타내는 붉은색을 띈다.
가장 높은 단계인 4단계에서는 물이 넘치면서 살짝 튀기는 모습도 구현했다.(어색하지만,,😢)
준비한 물은 다음과 같다.
자바스크립트로 랜덤한 수를 생성해서 출력한다.
위 숫자에 따른 단계에 일치하도록 랜덤한 숫자와 물컵을 출력한다.
cpu, mem, disk 용량이나 프로그램의 사용시간에 따른 과부화 정도 등 동적인 데이터들을 구현한 물컵을 이용해서 직관적이고 귀엽게 표현하기 위해 구현했다.
현재는 단순하게 랜덤값을 한개만 가지고 오기 때문에 SVG를 랜덤으로 출력하는 것에 대한 브라우저의 활성 정도를 확실하게 확인하기가 어렵지만, 더 많은 동적인 데이터를 표현한다면 통계가 필요할 것 같다.
<!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>eunjeong</title>
<link rel="stylesheet" href="./style.css" />
<!-- svg.js -->
<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"></script>
</head>
<body style="padding: 20px;">
<h1>랜덤 숫자별로 다른 물컵을 가져오기</h1>
<p>Random : <span id="random"></span></p>
<div id="cupArea"></div>
<div class="container">
<p>1단계</p>
<div id="one">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="200"
height="200">
<path d="M42,130 C 50 120, 60 140, 80 120 S 110 140, 130 120 L122, 150 45, 150z" stroke="#C8F4F9"
fill="#C8F4F9" stroke-width="3" stroke-linecap="round">
<animate repeatCount="indefinite" fill="#C8F4F9" attributeName="d" dur="4s" attributeType="XML"
values="
M42,110 C 50 130, 60 110, 80 130 S 110 120, 130 110 L122, 150 45, 150z;
M42,130 C 50 120, 60 140, 80 120 S 110 140, 130 120 L122, 150 45, 150z;
M42,120 C 50 130, 60 110, 80 120 S 110 120, 130 120 L122, 150 45, 150z;
M42,110 C 50 120, 60 140, 80 120 S 110 140, 130 120 L122, 150 45, 150z;
M42,110 C 50 130, 60 110, 80 130 S 110 120, 130 110 L122, 150 45, 150z;
" />
</path>
<polygon points="20,5 150,5 125,150 45,150 " fill="none" stroke="#000" stroke-width="3" />
</svg>
</div>
</div>
<div class="container">
<p>2단계</p>
<div id="two">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="200"
height="200">
<path d="M38,110 C 50 100, 65 80, 80 100 S 95 80, 110 100, 130 80, 133 100 L125, 150 45, 150z"
stroke="#47D3CE" fill="#47D3CE" stroke-width="3" stroke-linecap="round">
<animate repeatCount="indefinite" fill="#47D3CE" attributeName="d" dur="3s" attributeType="XML"
values="
M38,100 C 50 110, 65 100, 80 90 S 95 80, 110 80, 130 100, 133 100 L125, 150 45, 150z;
M33,80 C 50 100, 65 80, 80 80 S 95 110, 110 120, 130 80, 133 110 L125, 150 45, 150z;
M38,110 C 50 70, 65 60, 80 70 S 95 90, 110 80, 130 70, 133 80 L125, 150 45, 150z;
M33,80 C 50 80, 65 80, 80 100 S 95 110, 110 80, 130 110, 130 100 L125, 150 45, 150z;
M38,100 C 50 90, 65 110, 80 95 S 95 80, 110 80, 130 90, 130 115 L125, 150 45, 150z;
" />
</path>
<polygon points="20,5 150,5 125,150 45,150" fill="none" stroke="#000" stroke-width="3" />
</svg>
</div>
</div>
<div class="container">
<p>3단계</p>
<div id="three">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="200"
height="200">
<path d="M38,90 C 60 80, 65 50, 80 80 S 95 80, 110 100, 130 80, 135 90 L125, 150 45, 150z"
stroke="#FCA4A2" fill="#FCA4A2" stroke-width="3" stroke-linecap="round">
<animate repeatCount="indefinite" fill="#FCA4A2" attributeName="d" dur="2s" attributeType="XML"
values="
M35,100 C 60 70, 65 90, 80 80 S 95 65, 110 80, 130 80, 135 90 L125, 150 45, 150z;
M33,65 C 60 60, 65 70, 80 65 S 95 75, 110 83, 130 60, 137 70 L125, 150 45, 150z;
M35,85 C 60 90, 65 80, 80 90 S 95 60, 110 90, 130 70, 135 80 L125, 150 45, 150z;
M35,80 C 60 70, 65 60, 80 70 S 95 70, 110 95, 130 90, 137 70 L125, 150 45, 150z;
M35,90 C 60 70, 65 90, 80 80 S 95 65, 110 80, 130 80, 135 90 L125, 150 45, 150z;
" />
</path>
<polygon points="20,5 150,5 125,150 45,150" fill="none" stroke="#000" stroke-width="3" />
</svg>
</div>
</div>
<div class="container">
<p>4단계</p>
<div id="four">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="200"
height="200">
<path d="M24,30 C 50 20, 65 10, 80 20 S 95 10, 110 20, 130 30, 147 10 L125, 150 45, 150z"
stroke="#E78484" fill="#E78484" stroke-width="3" stroke-linecap="round">
<animate repeatCount="indefinite" fill="#E78484" attributeName="d" dur="2s" attributeType="XML"
values="
M24,20 C 50 40, 65 30, 80 13 S 95 25, 110 15, 130 40, 147 15 L125, 150 45, 150z;
M26,40 C 50 20, 65 10, 80 20 S 95 30, 110 20, 130 13, 147 25 L125, 150 45, 150z;
M24,10 C 50 13, 65 25, 80 15 S 95 10, 110 30, 130 20, 147 15 L125, 150 45, 150z;
M26,35 C 50 10, 65 35, 80 30 S 95 20, 110 13, 130 25, 147 6 L125, 150 45, 150z;
M24,15 C 50 15, 65 10, 80 25 S 95 15, 110 20, 130 30, 147 25 L125, 150 45, 150z;
" />
</path>
<!-- 물튀기기 같은 시간의 애니메이션으로 안보이게 처리해야하나,,? -->
<path d="M155 10 C 160 5, 170 25, 165,30z" fill="#E78484">
<animate repeatCount="indefinite" fill="#E78484" attributeName="d" dur="2s" attributeType="XML"
values="
M0,0;
M0,0;
M0,0;
M155 10 C 158 5, 160 20 160 17z;
M155 10 C 160 5, 170 25, 165,25z;
M155 10 C 160 5, 170 25, 165,30z;
" />
</path>
<path d="M155 5 C 163 0, 170 15, 165,10z" fill="#E78484">
<animate repeatCount="indefinite" fill="#E78484" attributeName="d" dur="2s" attributeType="XML"
values="
M0,0;
M0,0;
M0,0;
M155 5 C 158 0, 160 7, 160,10z;
M155 5 C 160 0, 163 10, 164,10z;
M155 5 C 163 0, 170 15, 165,10z;
" />
</path>
<polygon points="20,5 45,150, 125,150 150,5" fill="none" stroke="#000" stroke-width="3" />
</svg>
</div>
</div>
<script src="./svg.js"></script>
</body>
</html>
function getRandom() {
const randomNumber = Math.floor(Math.random() * (40 - 1) + 1);
let randomText = document.getElementById("random");
randomText.innerText = randomNumber;
setCup(randomNumber);
}
function setCup(randomNumber) {
if(randomNumber < 11){
return drawCup("one");
}
if(randomNumber < 21){
return drawCup("two");
}
if(randomNumber < 31){
return drawCup("three");
}
if(randomNumber < 41){
return drawCup("four");
}
}
function drawCup(cupId) {
let cup = document.querySelector("#" + cupId);
let svg = cup.childNodes[1].cloneNode(true);
let cupArea = document.getElementById("cupArea");
// 자식요소 모두 삭제해서 대체하기
let last;
while (last = cupArea.lastChild) cupArea.removeChild(last);
cupArea.appendChild(svg);
}
getRandom();
let interval = setInterval(getRandom, 5000);