canvas는 HTML의 태그로서 캔버스 스크립트 API 또는 WebGL API와 함께 사용하여
그래픽과 애니메이션을 그릴 수 있습니다.
출처 : https://developer.mozilla.org/ko/docs/Web/HTML/Element/canvas
위의 설명대로, canvas는 web에서 그래픽, 애니메이션을 그릴 수 있게 도와주는 태그이다.
이 태그는 canvas API와 함께 사용하여 web에서 그림을 그리는 기능을 제공한다.
canvas API는 JS와 HTML 캔버스 엘리먼트를 통해 그래픽을 그리기 위한 수단을 제공합니다. 무엇보다도 애니메이션, 게임 그래픽, 데이터 시각화, 사진 조작 및 실시간 비디오 처리를 위해 사용됩니다.
canvas API는 주로 2D 그래픽에 중점을 두고 있습니다. WebGL API 또한 canvas 엘리먼트를
사용하며, 하드웨어 가속 2D 및 3D 그래픽을 그립니다.
출처 : https://developer.mozilla.org/ko/docs/Web/API/Canvas_API
초기의 코드는 위와 같다.
구문
var atx = canvas.getContext(contextType)contextType
캔버스에 연관된 드로잉 컨텍스트를 정의하는 컨텍스트 식별자를 갖는 DOMString 입니다.위의 메서드는 캔버스의 드로잉 컨텍스트를 반환합니다.
컨텍스트 식별자가 지원되지 않을 경우 null을 반환합니다.
출처: https://developer.mozilla.org/ko/docs/Web/API/HTMLCanvasElement/getContext
getContext()메서드를 할당한 ctx를 기준으로 그림을 그리는 기능들이 작동한다고 생각하면 된다.
위의 코드를 보면,
css 파일에서 캔버스 태그의 width와 height 크기를 설정하였는데 js파일에서도 canvas의 width와 height 크기를 설정한 것을 알 수 있다.
그래픽 캔버스 요소
width : 좌표 공간의 너비입니다. CSS 픽셀 단위로, 기본값은 300입니다.
height: 좌표 공간의 높이입니다. CSS 픽셀 단위로, 기본값은 150입니다.캔버스 크기 조절 : CSS vs HTML
캔버스의 표시 크기는 CSS로도 수정할 수 있습니다.
그러나, CSS를 사용할 경우 렌더링 과정에서 CSS 크기에 맞추기 위해 이미지의 크기를 조절하므로, 최종 그래픽이 변형될 수 있습니다. 따라서 캔버스 태그의 width와 height 특성을 통해 직접 크기를 바꾸는 것이 좋습니다. HTML에서 직접 할 수도 있고, JS를 사용할 수도 있습니다.
출처 : https://developer.mozilla.org/ko/docs/Web/HTML/Element/canvas
캔버스의 크기를 css에서 지정하면 그래픽이 변형될 수도 있다고 한다.
예를 들어 마우스로 그림을 그릴 때 마우스로 그림을 그릴 때 커서의 위치와는 상관없이 다른 곳에 그림이 그려지는 경우가 있는데 이는 그래픽이 변형되었다고 할 수 있다.
HTML 또는 JS에서 캔버스의 크기를 설정하였다면 CSS에서 따로 크기를 설정할 필요는 없다.
캔버스 태그 위에서 발생하는 이벤트에 따라서 함수를 정의하였다.
마우스의 누르고 땠을 때는 경우에 따라 painting의 값이 true/false로 나뉜다.
이는 마우스를 누른 상태로 그림을 그리는 함수를 작성하기 위한 코드로 이후에 코드에서 painting의 값(마우스 상태)에 따라 그림을 그릴지 말지를 결정한다.
마우스로 그림을 그릴 때 제일 먼저 해당 마우스 커서의 위치를 알아야 한다.
마우스가 이동할 때마다 해당 event의 값을 console에 출력해보면 매우 다양한 값이 있다는 것을 알 수있다. 캔버스에서 마우스로 그림을 그릴 때 필요한 값은 offsetX와 offsetY 값이다.
offset 값 말고도 client, layer, page 등에서 x와 y값을 제공하지만 offset 값을 사용하는 이유는 offset의 값은 이벤트가 일어나는 대상에서의 x,y값이기 때문이다.
여기에선 이벤트가 일어나는 캔버스 위에서의 x와 y 값을 가리킨다.
MouseEvent.offsetX
The offsetX read-only property of the MouseEvent interface provides the offset in the X coordinate of the mouse pointer between that event and the padding edge of the target node.
출처: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX
해당 내용의 출처 : https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes
경로를 이용하여 도형을 만들 때에는 몇가지 추가적인 단계를 거쳐야 합니다.
- 경로를 생성합니다.
- 그리기 명령어를 사용하여 경로상에 그립니다.
- 경로가 한번 만들어졌다면, 경로를 렌더링 하기 위해서 윤곽선을 그리거나 도형 내부를 채울 수 있습니다.
마우스로 그림을 그릴 때 4가지 메서드를 사용하였다.
4가지 메서드는 getContext()를 할당한 ctx를 기준으로 작동한다.
CanvasRenderingContext2D.beginPath()
새로운 경로를 만든다.
경로가 생성됐다면, 이후 그리기 명령들은 경로를 구성하고 만드는데 사용하게 된다.
해당 메서드는 하위 경로 목록을 비움으로써 새 경로를 시작한다.
CanvasRenderingContext2D.moveTo()
펜을 x와 y로 지정된 자표로 옮깁니다.
실제로 어떤것도 그리지 않지만 경로의 일부가 된다. 이는 펜이나 연필을 종이위에서 들어 옆으로 옮기는 것으로 이해하면 된다.
캔버스가 초기화 되었거나 beginPath() 메서드가 호출되었을 떄, 특정 시작점 설정을 위해 moveTo() 함수를 사용하는 것이 좋다. 또한 moveTo() 함수는 연결되지 않은 경로를 그리는데에도 사용할 수 있다.
CanvasRenderingContext2D.lineTo()
현재의 드로잉 위치에서 x와 y로 지정된 위치까지 선을 그린다.
이 메서드는 선의 끝점의 좌표가 되는 x와 y의 두개의 인자가 필요하다.
시작점은 이전에 그려진 경로에 의해 결정되며, 이전 경로의 끝점이 다음 그려지는 경로의 시작점이 된다. 또한 시작점은 moveTo() 메서드를 통해 변경될 수 있다.
경로를 수정하는 다른 메서드와 마찬가지로 이 메서드는 직접 렌더링하지 않는다.
경로를 캔버스에 그리기 위해서는 fill() 또는 stroke() 메서드를 사용해야 한다.
CanvasRenderingContext2D.stroke()
윤곽선을 이용하여 그린다.
해당 메서드는 현재 또는 지정된 경로를 현재 스트로크 스타일로 윤곽선을 그린다.
스트로크는 경로의 중앙에 정렬되는데 스트로크의 절반은 안쪽, 절반은 바깥쪽이 그려진다.
스트로크는 non-zero winding rule을 사용하는데 이는 경로 교차점이 채워진다는 것을 의미한다.
디시 위의 코드를 보자.
첫번째 방법과는 다르게 closePath가 추가 되었다.
위의 코드는 다음과 같다.
CanvasRenderingContext2D.closePath()
현재 하위 경로의 시작 부분과 연결된 직선을 추가한다.
shape이 이미 닫혔거나 점이 하나만 있으면 이 함수는 아무 작업도 수행하지 않는다.
이 메서드는 직접적으로 아무것도 그리지 않는다. stroke() 또는 fill() 메서드를 사용하여 그릴 수 있다.
그림 그리기 코드를 1번과 2번으로 작성하였지만 1번 코드에 문제점이 있다는 것을 알게 되었다.
1번 코드는 설명하자면, 마우스의 클릭상태에 따라 startPainting과 stopPainting으로 painting의 값을 변경해가며 그림을 그리는 상태를 조절하는 함수이다.
그리고 onMouseMove를 통해 그림을 그리게 되는데 이때 1번 코드는 onMouseMove 함수 안에 if(!paiting) 이라는 조건문을 걸어 그림이 중지(완성) 시키는데 이 부분이 문제이다.
즉, 마우스가 움직이는 중 if(!painting)이 되어야 한다는 것인데, onMouseMove로 그림을 그리다 마우스에 손을 떼고 다시 움직여야 if(!panting) 이후의 코드가 작동한다는 것이다. 만약 마우스를 움직이다 마우스에 손을 떼고 그 이후에 마우스를 움직이지 않으면 if(!paiting) 코드가 작동하지 않는다. 그러므로 1번 코드 보단 2번 코드를 사용해야한다.
캔버스 위로 그림을 그리는 것에 다양한 스타일을 지정할 수 있다.
즉, 그림 도구의 색이나 형태를 변경할 수 있다.
선의 색
strokeStyle = color선의 굵기
lineWidth = value;선의 끝모양
lineCap = type
이외에도 다양한 스타일을 적용할 수 있다.
https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors