이번에는 그림 앱을 만들어 볼 것이다!!
canvas를 이용해서 만들 것이다
<body>
<canvas></canvas>
<script src="js/app.js"></script>
</body>
일단 html 내에 canvas태그를 생성한다
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
그리고 js로 와서 일단 canvas를 가져오고 브러쉬를 만들기 위해서 context를 만들어야 한다.
canvas.getContext를 입력해 주는데, 2d와 3d 중 선택할 수 있다. (소문자임)
2d 그림앱를 만들 것이기 때문에 2d를 입력한다.
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
css로 캔버스 크기를 800x800px로 설정해 줌
캔버스의 좌표는 캔버스의 왼쪽 상단 끝부분부터 0,0 으로 시작한다.
canvas.width = 800;
canvas.height = 800;
ctx.fillRect(50, 50, 100, 200)
캔버스 크기 설정을 맨 위 두 줄과 같이 해 준다.
fillRect는 색을 채워주는 역할을 한다. (strokeRect는 선으로 이루어진 직사각형을 만들어 준다)
위처럼 입력하면 50,50 좌표부터 100x200 사이즈의 사각형 모양으로 색이 채워진다.
ctx.rect(50, 50, 100, 200);
ctx.fillStyle = "red";
ctx.fill();
이런식으로 rect만 적어주고 그 후에 fill(), stroke()를 이용해 색을 채울지 아니면 선으로 만들지 결정할 수도 있다.
fillStyle(또는 strokeStyle)을 이용하여 색을 지정해 줄 수 있다.
ctx.rect(50, 50, 100, 100);
ctx.fillStyle = "red";
ctx.fill();
ctx.beginPath()
ctx.rect(150, 150, 100, 100);
ctx.fillStyle = "blue";
ctx.fill();
각각의 도형들을 다른 색으로 지정해 주고 싶다면 중간에 beginPath()를 이용하여 도형간의 경로를 끊어줘야 한다.
ctx.moveTo(50, 50);
ctx.lineTo(150, 50);
ctx.stroke()
라인을 직접 그려줄 수도 있다.
이와 같은 선이 그려진다.
ctx.moveTo(50, 50);
ctx.lineTo(150, 50);
ctx.lineTo(150, 150);
ctx.lineTo(50, 150);
ctx.lineTo(50, 50);
ctx.stroke()
이렇게 하면 사각형이 만들어진다.
선의 굵기를 조절할 수 있다.
이번에는 원을 만드는 법을 배워서 사람 모양을 만들어 볼 것이다
ctx.arc(50, 50, 20, 0, 2 * Math.PI);
ctx.fill();
원은 arc()를 이용하여 만든다
(x, y, 반지름크기,시작각도, 종료각도) 순으로 입력한다.
이와 같이 만들어졌다.
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 800;
canvas.height = 800;
ctx.fillRect(200, 200, 15, 100);
ctx.fillRect(365, 200, 15, 100);
ctx.fillRect(260, 200, 60, 200);
ctx.arc(290, 120, 60, 0, 2 * Math.PI);
ctx.fill();
ctx.beginPath();
ctx.arc(270, 120, 10, Math.PI, 2 * Math.PI);
ctx.arc(310, 120, 10, Math.PI, 2 * Math.PI);
ctx.fillStyle = "white"
ctx.fill();
사람 만듦
클릭할 때마다 선 만들기
function onClick(event) {
console.log(event)
}
canvas.addEventListener("click", onClick)
함수에 event를 주고 콘솔로 확인해보면 클릭한 위치의 좌표값을 얻을 수 있다.
offsetX, offsetY가 우리가 클릭한 좌표값이다.(캔버스 안의 좌표)
function onClick(event) {
ctx.lineTo(event.offsetX, event.offsetY);
ctx.stroke();
}
canvas.addEventListener("click", onClick);
이 좌표값을 이용하여 lineTo를 입력하면
클릭할 때마다 좌표가 그려진다
canvas.addEventListener("mousemove", onClick);
click 대신 mousemove를 넣으면 마우스가 움직이는대로 그려진다.
const colors = [
"#d0d3ff",
"#ffdad0",
"#fffdd0",
"#ddffd0",
"#d0f9ff",
"#ffd0ee",
"#8a86ff",
"#ff86cb",
"#ff8686",
"#ffef86",
"#96ff86",
"#86cfff",
];
function onClick(event) {
ctx.beginPath();
const color = colors[Math.floor(Math.random() * colors.length)];
ctx.strokeStyle = color;
ctx.moveTo(0,0)
ctx.lineTo(event.offsetX, event.offsetY);
ctx.stroke();
}
canvas.addEventListener("mousemove", onClick);
moveTo를 0,0으로 지정해주면 00에서부터 마우스의 위치까지 직선이 그려지게 되고 이동할 때마다 계속 생성된다.
색을 가져오기 위해 색이 담긴 배열을 만들어주고, Math.ramdom을 이용하여 무작위로 색을 가져오도록 설정해준다.
색이 직선마다 다른 색으로 변하도록 하기 위해선 beginPath를 설정해줘서 경로를 끊어줘야 한다.
이번에는 마우스를 누른 상태에서만 그림이 그려지게 할 것이다.
let isPainting = false;
function onMove(event) {
}
function startPainting() {
isPainting = true;
}
function cancelPainting() {
isPainting = false;
}
canvas.addEventListener("mousemove", onMove);
canvas.addEventListener("mousedown", onMouseDown);
canvas.addEventListener("mouseup", onMouseUp);
mouseup과 mousedown을 이용한다. mousedown은 마우스를 누르고 있는 상태를 의미한다.
마우스를 누르면 inPainting을 true로 바꿔주자. 다시 떼면 false로 바꿔준다.
function onMove(event) {
if (isPainting) {
ctx.lineTo(event.offsetX, event.offsetY);
ctx.stroke();
return;
}
ctx.moveTo(event.offsetX, event.offsetY);
}
onMove 함수를 다음과 같이 작성한다.
만약 inPainting이 true인 상태이면 lineTo를 이용하여 마우스의 위치에 따라 선이 그려지도록 한다.
마지막에 return을 이용하여 함수를 끝내준다.
그림이 잘 그려진다.
canvas.addEventListener("mouseleave", onMouseUp);
mouseleave 이벤트를 추가해 줘서, 마우스가 캔버스 밖을 나갔다가 다시 들어왔을 때 선이 끊어지지 않고 계속 이어서 그려지는 버그를 없애준다.
선 굵기 바꾸기
<input id="line-width" type="range" min="1" max="10" value="5" step="0.1">
html안에 다음과 같은 input 태그를 추가한다.
min은 선의 최소 굵기, max는 최대 굵기가 될 것이다. value는 굵기의 기본값이다.
이런 바가 생긴다.
const lineWidth = document.getElementById("line-width");
ctx.lineWidth = lineWidth.value;
자바스크립트로 가져와서 다음과 같이 선의 기본 굵기를 가져온다.
새로고침을 해서 선을 그려보면 굵기가 굵어진 것을 알 수 있다.
이제 선의 굵기를 직접 조정할 수 있도록 해야 한다.
function onLineWidthChange(event) {
console.log{event.target.value}
}
lineWidth.addEventListener("change", onLineWidthChange);
이번에는 change이벤트를 추가해 준다.
함수를 이용해서 콘솔로 value 값을 확인해보면
바를 움직일 때마다 값이 출력되는 것을 볼 수 있다.
이 값을 이용해서 크기를 바꿀 수 있도록 할 것이다.
function onLineWidthChange(event) {
ctx.lineWidth = event.target.value;
}
onLineWidthChange함수를 이와같이 작성하고,
function onMove(event) {
if (isPainting) {
ctx.lineTo(event.offsetX, event.offsetY);
ctx.stroke();
return;
}
ctx.beginPath();
ctx.moveTo(event.offsetX, event.offsetY);
}
굵기를 바꿀 때 이전에 그렸던 선의 굵기까지 수정되지 않도록 onMove함수 혹은 cancelPainting함수로 와서 beginPath를 추가해서 경로를 끊어줘야 한다.