[TIL] JS: 바닐라 JS로 그림판 만들기

송나은·2021년 1월 31일
0

JavaScript

목록 보기
11/23

그림판 만들기

그림판 바로가기

1. Canvas 만들기

⭐ canvas 안에서 마우스를 클릭할 때, 그림이 그려지도록 하기

✅ canvas에서 마우스를 클릭할 때 외에는 그림이 그려지면 안되기 때문에 painting 변수의 기본값을 false로 설정했다.

  • event.offsetX 마우스의 x좌표, event.offsetY 마우스의 y좌표를 가져왔다.
  • canvas.addEventListener() 함수로 canvas 내에서 마우스의 움직임에 따라 다른 함수가 실행되도록 하였다.
  • painting이 true 일 때, .beginPath()로 경로를 생성하고, .moveTo(x,y)의 x,y 좌표에서 부터 .lineto(x,y)의 x,y 좌표까지 .stroke() 선을 그린다.
    🧩 CanvasRenderingContext2D 을 참고하였다.
<canvas id="jsCanvas" class="canvas"></canvas>
//javascript

const canvas = document.getElementById("jsCanvas");
const ctx = canvas.getContext("2d");

const CANVAS_SIZE = 700;

canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;

//'그림을 그린다'의 기본값은 false
let painting = false;

function stopPainting(){
    painting = false;
}

function startPainting(){
    painting = true;
}

// 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);
}

2. 색상 파레트 만들기

⭐ 색상 팔레트를 클릭하여 원하는 색상으로 그릴 수 있도록 만들기

  • div를 생성하여 각각에 background-color를 부여하고, 색상 팔레트를 만들어 주었다.
  • color.addEventListener() 함수로 color를 클릭했을 때 함수가 실행되도록 했다.
  • event.target.style.backgroundColor 색상 팔레트의 색상을 불러왔다.
<!--색상 파레트 만들기-->
<div class="controls_colors" id="jsColors">
  <div class="controls_color jsColor" style="background-color:black"></div>
  <div class="controls_color jsColor" style="background-color:white"></div>
  <div class="controls_color jsColor" style="background-color:red"></div>
  <div class="controls_color jsColor" style="background-color:orange"></div>
  <div class="controls_color jsColor" style="background-color:green"></div>
  <div class="controls_color jsColor" style="background-color:blue"></div>
  <div class="controls_color jsColor" style="background-color:violet"></div>
 <div class="controls_color jsColor" style="background-color:grey"></div>
 <div class="controls_color jsColor" style="background-color:purple"></div>
</div>
//javascript

const ctx = canvas.getContext("2d");
const colors = document.getElementsByClassName("jsColor")

const INITIAL_COLOR = "#2c2c2c";

ctx.strokeStyle = "INITIAL_COLOR";
ctx.fillStyle = "INITIAL_COLOR";

// color를 골라 적용한다.
function handleColorClick(event){
    const color = event.target.style.backgroundColor;
    ctx.strokeStyle = color;
    ctx.fillStyle = color;
}

Array.from(colors).forEach(color=>
    color.addEventListener("click", handleColorClick)
);

3. Canvas 가득 채우기

⭐ Fill 버튼을 누르면 canvas를 가득 채울 수 있도록 만들기

✅ Fill 버튼을 클릭 후 실행 될 수 있도록 filling 변수의 기본값을 false로 설정했다.

  • canvas.addEventListener() 함수로 canvas 상자 내 클릭 시 함수가 실행되도록 했다.
  • ctx.fillRect(x,y,w,h) 사각형의 형태로 도형이 채워지는 함수로, CANVAS_SIZE 만큼 채워지도록 했다.
  • mode.addEventListener() 함수로 Fill 버튼 클릭 시 함수가 실행되도록 했다.
  • filling이 true 일 때, 값을 false로 바꾸고 mode.innerText 버튼 이름이 Paint로 바뀌도록 했다.
<!--Fill 버튼 만들기-->
<div class="controls_btns">
  <button id="jsMode">Fill</button>
</div>
//javascript

const canvas = document.getElementById("jsCanvas");
const ctx = canvas.getContext("2d");
const mode = document.getElementById("jsMode");

let filling =false;

const CANVAS_SIZE = 700;

// Fill / Paint 버튼 이름 변경하기
function handleModeClick(){
    if (filling === true){
        filling = false;
        mode.innerText = "Fill";
    } else {
        filling = true;
        mode.innerText = "Paint";
    }
}

if (mode){
    mode.addEventListener("click", handleModeClick);
}

// canvas를 클릭하면 canvas사이즈만큼 색이 채워진다.
function handleCanvasClick(){
    if(filling){
        ctx.fillRect(0,0,CANVAS_SIZE, CANVAS_SIZE);
    }
}

if(canvas){
  canvas.addEventListener("click", handleCanvasClick);}

4. 붓의 크기 조절하기

⭐ 붓의 크기를 조절할 수 있도록 하기

  • range의 min, max, value, step 값을 설정하여 0.1에서 5까지 0.1씩 조절할 수 있도록 했다.
  • range.addEventListener() 함수로 range 조절 시 함수가 실행되도록 했다.
  • ctx.lineWidth 2.5를 기본값으로 하고, event.target.value로 value값을 가져와 size에 변화를 주었다.
<!--Input type: range-->
<div class="controls_range">
  <input
         type="range"
         id="jsRange"
         min="0.1"
         max="5"
         value="2.5"
         step="0.1"
         />
</div>
//javascript

const ctx = canvas.getContext("2d");
const range = document.getElementById("jsRange");

ctx.lineWidth = 2.5;

// 붓의 크기를 변경한다.
function handleRangeChange(event){
    const size = event.target.value;
    ctx.lineWidth = size;
}

if(range){
    range.addEventListener("input", handleRangeChange);
}

5. 저장버튼 만들기

⭐ 마우스 우클릭 방지
⭐ 저장 버튼을 클릭하면 png 형태로 저장되도록 하기

  • preventDefault()를 이용하여 마우스 우클릭의 default 값인 contextmenu가 나오지 않도록 했다.
  • toDataURL()로 png 형태의 이미지 data URL을 반환한다.
    🧩 toDataURL
  • link.download a의 하위요소로 링크로 가는 대신 다운로드를 할 수 있다.
<!--Save 버튼 만들기-->
<div class="controls_btns">
  <button id="jsSave">Save</button>
</div>
//javascript

const canvas = document.getElementById("jsCanvas");
const saveBtn = document.getElementById("jsSave")

// 마우스 우클릭 방지
function handleCM(event){
    event.preventDefault();}

if(canvas){
  canvas.addEventListener("contextmenu", handleCM);}

// 이미지 저장
function handleSaveClick(){
    const image = canvas.toDataURL();
    const link = document.createElement("a");
    link.href = image;
    link.download = "PaintJS";
    link.click();
}  

if (saveBtn){
    saveBtn.addEventListener("click", handleSaveClick)
}

Review

  • 지우개, 실행취소도 만들어 보자 !
profile
그때그때 공부한 내용과 생각을 기록하는 블로그입니다.

0개의 댓글