mdn의 캔버스 튜토리얼 따라하기
참고 : 캔버스 튜토리얼
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Example</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas1" width="300" height="300"></canvas>
<canvas id="canvas2" width="150" height="150">The current time</canvas>
<script src="scripts/myCanvas2.js"></script>
</body>
</html>
var sun = new Image();
var moon = new Image();
var earth = new Image();
function init() {
sun.src = "images/3nee_20.jpg";
moon.src = "images/3nee_20.jpg";
earth.src = "images/3nee_20.jpg";
window.requestAnimationFrame(drawSolarSystem);
}
function drawSolarSystem() {
var ctx = document.getElementById("canvas1").getContext("2d");
/*
* 애니메이션 장면 단계
* 1. 캔버스 비우기(clearRect())
* 2. 캔버스 상태 저장
* 3. 장면 그리기
* 4. 상태 복원
*
* 애니메이션 제어
* 정해진 시간마다 그리기 함수 실행
* 1. 예정된 변경(window.setInterval(), window.setTimeout())
*/
// 새로운 그림을 기존 그림 위에 그리는 방식
ctx.globalCompositeOperation = "destination-over";
ctx.clearRect(0,0,300,300); // 캔버스 비우기
ctx.fillStyle = "rgb(0 0 0 / 40%)"; // 지구 그림자
ctx.strokeStyle = "rgb(0 153 255 / 40%)";
ctx.save();
// 좌표 원점 캔버스 중앙으로 이동
ctx.translate(150,150);
// 지구
var time = new Date();
ctx.rotate(
((2*Math.PI) / 60) * time.getSeconds() + // 1초당 각도 계산
((2*Math.PI) / 60000)* time.getMilliseconds(), // 밀리초당 각도 계산
);
ctx.translate(105,0); // 지구 위치로 이동
ctx.fillRect(0,-12,40,24); //지구 그림자 그리기
ctx.drawImage(earth, -12, -12, 30, 30);
// 달
ctx.save();
// 원점이 지구인 상태에서 각도 회전
ctx.rotate(
((2*Math.PI) / 6) * time.getSeconds() +
((2*Math.PI) / 6000)* time.getMilliseconds(),
);
// 거리를 벌려 지구를 도는 것처럼 보이게
ctx.translate(0, 28.5);
ctx.drawImage(moon, -3.5, -3.5, 10, 10);
ctx.restore(); // moon의 상태 복원
ctx.restore(); // 전체 변환 상태 복원
ctx.beginPath();
ctx.arc(150, 150, 105, 0, Math.PI * 2, false); // 지구궤도
ctx.stroke();
ctx.drawImage(sun,125,125,50,50);
window.requestAnimationFrame(drawSolarSystem);
}
init();
function clock() {
const now = new Date();
var canvas = document.getElementById("canvas2");
var ctx = canvas.getContext("2d");
ctx.save();
ctx.clearRect(0,0,150,150);
ctx.translate(75,75);
ctx.scale(0.4,0.4);
ctx.rotate(-Math.PI / 2);
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.lineWidth = 8;
ctx.lineCap = "round";
// 시 세팅
ctx.save();
for(let i=0; i<12; i++) {
ctx.beginPath();
ctx.rotate(Math.PI / 6);
ctx.moveTo(100, 0);
ctx.lineTo(120, 0);
ctx.stroke();
}
ctx.restore();
// 분 세팅
ctx.save();
ctx.lineWidth = 5;
for(let i=0; i<60; i++) {
if(i%5 !== 0) {
ctx.beginPath();
ctx.moveTo(117, 0);
ctx.lineTo(120, 0);
ctx.stroke();
}
ctx.rotate(Math.PI / 30);
}
ctx.restore();
// 현재 시간 세팅
const sec = now.getSeconds();
const min = now.getMinutes();
const hr = now.getHours() % 12;
ctx.fillStyle = "black";
canvas.innerText = `The time is: ${hr}:${min}`;
// 시침
ctx.save();
// 시간은 30도, 분은 6도, 초는 0.1도이므로 각 시분초에 해당 각을 곱하여 최종 시간각 계산
// 시계바늘들이 서로 다른 속도로 회전, 분침이 시침보다 60배 초침이 분침보다 60배 빠르다
ctx.rotate(
(Math.PI / 6) * hr + (Math.PI / 360) * min + (Math.PI / 21600) * sec,
);
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20, 0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
// 분침
ctx.save();
ctx.rotate((Math.PI / 30) * min + (Math.PI / 1800) * sec);
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-28, 0);
ctx.lineTo(112,0)
ctx.stroke();
ctx.restore();
// 초침
ctx.save();
ctx.rotate((sec * Math.PI) / 30);
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30, 0);
ctx.lineTo(83,0);
ctx.stroke();
// 중앙 동그라미
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2, true);
ctx.fill();
// 초침 끝 동그라미
ctx.beginPath();
ctx.arc(95,0,10,0,Math.PI*2, true);
ctx.stroke();
// ctx.fillStyle = "rgb(0 0 0 / 0%)";
// ctx.arc(0,0,3,0,Math.PI*2, true);
// ctx.fill();
ctx.restore();
// 시계 틀
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = "#325FA2";
ctx.arc(0,0,142,0,Math.PI*2, true);
ctx.stroke();
ctx.restore();
window.requestAnimationFrame(clock);
}
window.requestAnimationFrame(clock);
짜려면 머리가 돌아가야하는데 0부터 만들라고하면 만들 수 있으려나... 🫠
'Frontend > HTML' 카테고리의 다른 글
[HTML/canvas] 장애물을 피해 마우스 움직이기 게임 (0) | 2024.02.26 |
---|---|
[HTML/canvas] Basic animations(2/2) (0) | 2024.02.26 |
[HTML/canvas] Compositing and clipping (0) | 2024.02.22 |
[HTML/canvas] 변형 (transformations) (1) | 2024.02.22 |
[HTML/canvas] 스타일과 색 적용하기 (0) | 2024.02.21 |