클론 코딩

노마드코더 : 그림판 만들기(Vanilla JS) -3. JS, 완성본

식초 2020. 10. 29. 22:14

Canvas 이벤트 /

2D Context /

path로 좌표 연동 /

색 바꾸기 /

붓 크기 /

채우기 모드 /

이미지 저장

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//canvas는 픽셀을 다루는 html5의 요소이다
const canvas = document.getElementById('jsCanvas');
const ctx = canvas.getContext('2d'); //context는 안에서 픽셀 컨트롤
const colors = document.getElementsByClassName('jsColor'); //HTML Collection이 생긴다
const range = document.getElementById('jsRange');
const mode = document.getElementById('jsMode');
const saveBtn = document.getElementById('jsSave');
 
const INITIAL_COLOR = '#2c2c2c';
const CANVAS_SIZE = 700;
 
//canvas에게 높이와, 너비를 지정해준다
canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;
 
ctx.fillStyle = 'white'//canvas 기본 배경색을 흰색으로 한다
ctx.fillRect(00, CANVAS_SIZE, CANVAS_SIZE);
ctx.strokeStyle = INITIAL_COLOR; //context안에 있는 선의 색
ctx.fillStyle = INITIAL_COLOR;
ctx.lineWidth = 2.5//context안에 있는 선의 너비
 
let painting = false//그리기 기본값을 false로 한다
let filling = false//채우기 기본값은 false
 
function stopPainting() {
  painting = false//그리기를 멈춘다
}
 
function startPainting() {
  painting = true;
}
 
function onMouseMove(event) {
  const x = event.offsetX; //offset은 캔버스만 관계된 좌표
  const y = event.offsetY;
  if (!painting) {
    //그림 그리지 않을때
    ctx.beginPath(); //path(선)의 시작
    ctx.moveTo(x, y); //(보이진 않지만) 이동할때 좌표생성
  } else {
    ctx.lineTo(x, y); //lineTo의 좌표에 path가 그려진다(보이진 않지만)
    ctx.stroke(); //stroke는 path를 선으로 그린다
  } //lineTo와 stroke는 마우스를 움직일때마다 생긴다
}
 
function handleColorClick(event) {
  const color = event.target.style.backgroundColor;
  ctx.strokeStyle = color; //선의 색을 클릭한 색으로 바꾼다
  ctx.fillStyle = ctx.strokeStyle; //채우기 색과  선의 색이 같게 한다
}
 
function handleRangeChange(event) {
  const size = event.target.value;
  ctx.lineWidth = size;
}
 
//채우기 버튼
function handleModeClick() {
  if (filling === true) {
    //채우기가 아님이 맞을때
    filling = false//채우기 실행
    mode.innerText = 'Fill'//mode 버튼의 글자를 fill로 바꾼다
  } else {
    filling = true;
    mode.innerText = 'Paint';
  }
}
 
//캔버스 클릭 배경 채우기
function handleCanvasClick() {
  if (filling) {
    //채우기가 false일때 = 그리기일때
    ctx.fillRect(00, CANVAS_SIZE, CANVAS_SIZE); //fillRect(): 캔버스 사이즈만큼 사각형 채운다
  }
}
 
//오른쪽 저장 버튼 재설정
function handleCM(event) {
  event.preventDefault(); //기본값 막음: 오른쪽 클릭해도 저장버튼 안뜬다
}
 
//저장하기
function handleSaveClick() {
  const image = canvas.toDataURL(); //캔버스의 데이터를 URL로 이미지 만든다, 기본값은 png
  const link = document.createElement('a');
  link.href = image; //download는 이름으로 지정해야 한다
  link.download = 'PaintJS[🎨]'//download는 a의 속성이다, 링크로 다운로드하라고 한다, URL 대신에
  link.click(); //Fake 클릭
}
 
if (canvas) {
  canvas.addEventListener('mousemove', onMouseMove); //마우스 움직일때
  canvas.addEventListener('mousedown', startPainting); //클릭했을때
  canvas.addEventListener('mouseup', stopPainting); //마우스 뗐을때
  canvas.addEventListener('mouseleave', stopPainting); //캔버스를 벗어났을때
  canvas.addEventListener('click', handleCanvasClick); //클릭했을때 캔버스
  canvas.addEventListener('contextmenu', handleCM); //클릭했을때 저장
}
 
Array.from(colors).forEach((color) =>
  color.addEventListener('click', handleColorClick),
);
 
//input을 조절했을때, 함수가 실행된다
if (range) {
  range.addEventListener('input', handleRangeChange);
}
 
//채우기 버튼 클릭했을때, 함수 실행
if (mode) {
  mode.addEventListener('click', handleModeClick);
}
 
//저장 버튼 클릭했을때, 함수 실행
if (saveBtn) {
  saveBtn.addEventListener('click', handleSaveClick);
}
 
cs

 

 

 

완성♥

 

sigcho.github.io/Painting_Board_JS/

 

PaintJS

 

sigcho.github.io