캔버스 생성(width, height 반드시 필요)
<canvas id="jsCanvas" class="canvas" width=700 height=700></canvas>
css 테두리 그림자
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08);
버튼 클릭시 살짝 줄어드는 효과
.controls__btns button:active{
transform: scale(0.98);
}
button, input 등 브라우저에서 기본적으로 적용되어있는 style을 초기화 시키는 방법
button { all: unset; }
range버튼 만들기
<input type="range" id="jsRange" min="0.1" max="5" value="2.5" step="0.1"/>
마우스 x,y좌표 받아오기
function onMouseMove(e){
const x = e.offsetX
const y = e.offsetY
}
- screenX / screenY : 모니터 화면 기준 좌표
- pageX / pageY : 전체 문서 기준 좌표
- clientX / clientY : 현재 보여지는 창 기준 좌표
- offsetX / offsetY : 대상 노드 기준 좌표
이벤트 등록
// 마우스 이동
canvas.addEventListener('mousemove', onMouseMove)
// 마우스 클릭
canvas.addEventListener('mousedown', startPainting)
// 마우스 클릭 해제
canvas.addEventListener('mouseup', stopPainting)
// 마우스 화면 밖으로 이동
canvas.addEventListener('mouseleave', stopPainting)
캔버스 기능 구현(path 사용)
// context 생성
const canvas = document.getElementById("jsCanvas")
const ctx = canvas.getContext("2d")
// Default 설정
ctx.fillStyle = 'white' // 채우기 색
ctx.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE) // 배경색 적용
ctx.strokeStyle = "#2c2c2c" // 라인 색
ctx.lineWidth = 2.5 // 라인 두께
function onMouseMove(e) {
const x = e.offsetX
const y = e.offsetY
if (!painting) {
ctx.beginPath() // path 생성
ctx.moveTo(x, y) // path 시작 좌표 설정
} else {
ctx.lineTo(x, y) // path와 현재 좌표 연결
ctx.stroke() // strokeStyle로 path 채우기
}
}
context : canvas 요소 안에 픽셀에 접근할 수 있는 방법
Canvas Rendering Context2D
채우기 기능
const CANVAS_SIZE = 700
ctx.fillStyle = '#2c2c2c'
function handleCanvasClick(e) {
if (filling) {
ctx.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE)
}
}
canvas.addEventListener('click', handleCanvasClick)
context menu 제거(캔버스 화면에서 우클릭시 나오는 메뉴)
function handleCM(e) {
e.preventDefault()
}
canvas.addEventListener('contextmenu', handleCM)
이미지 파일 생성
function handleSaveClick(e) {
const image = canvas.toDataURL() // URL 생성(디폴트 png)
const link = document.createElement('a') // 링크 생성
link.href = image // URL 연결
link.download = 'PaintJS[EXPORT]' // 파일 이름
link.click()
}