whatisthis?
javaScript. Painting App 구현 - (3) 2D context 본문
지난 회차 진행사항
- app.js 이벤트리스너 (mouse event) 작성
const canvas = document.getElementById("jsCanvas");
let painting = false;
function stopPainting() {
painting = false;
}
function onMouseMove(event) {
const x = event.offsetX;
const y = event.offsetY;
}
function onMouseDown(event) {
painting: true;
}
function onMouseUp(event) {
stopPainting(); // 함수 호출 ㅡ painting = false
}
if(canvas) {
canvas.addEventListener('mousemove',onMouseMove); // 마우스가 위에 있을때
canvas.addEventListener('mousedown', onMouseDown); // 마우스 클릭시
canvas.addEventListener('mouseup', onMouseUp); // 마우스 클릭 놓았을때
canvas.addEventListener('mouseleave', stopPainting); // 마우스 떠날때
}
< canvas >
- HTML의 element 이다.
- context를 갖는다. ( = 픽셀에 접근할 수 있음 )
const canvas = document.getElementById('jsCanvas');
const ctx = canvas.getContext('2d'); // 2d 컨텍스트를 가져옴
HTMLCanvasElement.getContext() 메소드는 element의 컨텍스트(렌더링될 그리기의 대상)를 얻는다.
예제> 초록색 사각형(Rectangle) 그리기
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 150, 100);
app.js
const canvas = document.getElementById("jsCanvas");
const ctx = canvas.getContext("2d");
canvas.width = 700;
canvas.heigth = 700;
// Default
ctx.strokeStyle = "#2c2c2c";
ctx.lineWidth = 2.5;
let painting = false;
function stopPainting() {
painting = false;
}
function startPainting() {
painting = true;
}
function onMouseMove(event) {
const x = event.offsetX;
const y = event.offsetY;
if(!painting) {
ctx.beginPath();
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
ctx.stroke();
}
}
if(canvas) {
canvas.addEventListener('mousemove',onMouseMove);
canvas.addEventListener('mousedown', startPainting);
canvas.addEventListener('mouseup', stopPainting);
canvas.addEventListener('mouseleave', stopPainting);
}
- 우선, getContext("2d")를 해서 element의 컨텍스트(렌더링될 그리기의 대상)를 얻는다.
- 그 다음 디폴트값으로 설정을 한 다음 (strokeStyle과 lineWidth)
- StartPainting 함수를 만들어서 painting = true를 하는 동작을.
>> mousedown일때 startPainting함수를 실행한다.
로직을 살펴보면
마우스 클릭시 = startPainting
마우스 떼면 = stopPainting
캔버스 벗어나면 =stopPainting
마우스 움직이면 = onMouseMove
결국엔 paiting변수를 true와 false로 바꿔주는 것이고,
실질적으로 x좌표와 y좌표를 가진 onMouseMove함수를 설계해야함.
function onMouseMove(event) { const x = event.offsetX; const y = event.offsetY; if(!painting) { ctx.beginPath(); ctx.moveTo(x, y); } else { ctx.lineTo(x, y); ctx.stroke(); } }
위와 같이 작성하였는데,
📌 painting이 false이면?
ㅡ 1. 맨처음 상황 (painting변수는 false로 초기화됨)
2. 마우스 떼었을때
3. 마우스가 캔버스 벗어났을 때
>> beginPath (Path를 만들기 시작) ㅡ moveTo(x, y) 해당 x,y가 바뀔때마다 Path가 이동
📌 painting이 true면? (마우스 클릭시)
lineTo(x, y) ㅡ line(선)이 이동. 즉 그려진 path대로 선이 이어짐
stroke(); ㅡ 그림
💡 반드시 canvas의 크기를 줘야함.
>> 픽셀 modifier로서의 width * height 를 지정.
❓ 문제 발생
canvas.width와 canvas.height를 700으로 설정했더니
이상하게 그려진다.
canvas.width = document.getElementsByClassName("canvas")[0].offsetWidth;
canvas.height = document.getElementsByClassName("canvas")[0].offsetHeight;
위와 같은 코드로 대체했더니 정상작동함.
왜?
>> width , height 값에 700, 700 주면 오류생길 여지가 있으므로 캔버스 크기를 가져와야함.
굳이 왜 id로 안가져오고 getElementsByClassName()으로 가져옴?
>> 우리가 <canvas>태그에 직접 width, height를 준게 아니고 css로 주었기 때문에
css를 적용시킨 클래스를 가져와야함.
그리고, class로 가져오면 클래스는 중복 가능이므로 값이 하나더라도 배열(array)의 형태로 가져옴.
따라서, 뒤에 [0]을 붙여서 배열의 첫번째 요소를 가져온 것임.
offsetWidth는 무엇?
>> HTML 요소인 <canvas>의 너비.
즉, 엘리먼트의 크기를 구하려면 offsetWidth를 가져와야함.
참고
- offsetWidth : 엘리먼트 전체 크기 (패딩, 보더, 스크롤바 포함)
- clientWidth : 창에서 실제로 보여지고 있는 컨텐츠의 크기. (패딩 포함. / 보더,스크롤바는 X)
- scrollWidth : 보이는 것과 상관없이 실제 컨텐츠의 크기. (전체 스크롤바 ㅡ 숨겨진 영역 포함)
REFERENCE
Nomadcoder - Free Course
'PRACTICE > SELF' 카테고리의 다른 글
javaScript. Painting App 구현 - (5) Brush Size (1) | 2022.02.02 |
---|---|
javaScript. Painting App 구현 - (4) Change Color (0) | 2022.02.02 |
javaScript. Painting App 구현 - (2) Canvas Event (0) | 2022.02.02 |
javaScript. Painting App 구현 - (1) HTML/CSS (0) | 2022.02.02 |
javaScript. 턴제 게임 - 텍스트 기반 RPG (下) (0) | 2022.01.31 |