Dev./Self-Dev.

[Meme-Maker] Stroke, Fill 모드 선택 기능 추가

Astin9 2023. 3. 5. 01:11

노마드 코더에서 들을 수 있는 무료 강의 중, HTML/CSS/JS를 이용한 그림 앱 만들기가 시간도 짧고 재밌어보여서 듣게 되었다. 동영상 전체 시간은 2시간 내외정도지만, 코드를 이해하고 또 직접 타이핑하면서 하느라 4시간은 걸렸다... 거기에 마지막에 챌린지로 기능 하나를 추가하는데 2시간이 걸렸다.. 상당히 피곤하지만 그래도 자기 전에 기록을 남겨두면 좋을 것 같아서 블로그에 글을 적어보려고 한다!

 

 

 

뭘 만들었나?

 

 

GitHub - astinaus/paintjs

Contribute to astinaus/paintjs development by creating an account on GitHub.

github.com

 

MEME-MAKER

 

astinaus.github.io

간단하게 말하면 그림판이다. Canvas API를 활용하여 만들고, 그림을 그리거나 사진을 불러와 사진 위에 그림을 그릴 수도 있고, 텍스트 추가도 가능하며 다 그린 뒤에 파일로 저장할 수도 있다. 코드 구현 자체는 영상보면서 따라하면 금방 할 수 있다. HTML/CSS 부분은 그래도 어느정도 배운 상태라 이해가 잘 됐지만, 자바스크립트는 영상을 보면서 하는데도 머리가 아플 지경이었다. 앞으로 프론트엔드 스쿨에서도 자바스크립트를 배울텐데, 미리 자습을 많이 해둬야겠다..

 

 

추가한 기능

 

이 게시글에서 전체 코드는 다루지 않을 것이다. 무료 강의이고 노마드 코더 홈페이지에 회원가입만 하면 누구나 들을 수 있기 때문에 직접 가서 듣는게 좋을 것 같다.

 

바닐라 JS로 그림 앱 만들기 – 노마드 코더 Nomad Coders

HTML, CSS, JS

nomadcoders.co

 

나는 여기에 stroke / fill을 선택해서 그릴 수 있는 체크박스 기능을 추가하였다.

 

Stroke는 선, Fill은 선 안을 색으로 채운다.

 

checkbox? radio?

 

 

<input type="checkbox"> - HTML: HyperText Markup Language | MDN

<input> elements of type checkbox are rendered by default as boxes that are checked (ticked) when activated, like you might see in an official government paper form. The exact appearance depends upon the operating system configuration under which the brows

developer.mozilla.org

 

 

 

<input type="radio"> - HTML: Hypertext Markup Language | MDN

radio 유형의 <input> 요소는 보통 서로 관련된 옵션을 나타내는 라디오 버튼 콜렉션, 라디오 그룹에 사용합니다. 임의의 그룹 내에서는 동시에 하나의 라디오 버튼만 선택할 수 있습니다. 라디오

developer.mozilla.org

html input 태그에는 checkbox 타입과 radio 타입이 있다. 둘은 얼핏 보면 비슷하지만 가장 큰 차이가 있다.

checkbox는 하나의 값을 선택 또는 해제가 가능하여 중복 체크 또는 아무것도 체크하지 않을 수가 있다.

그러나 radio는 다수가 하나의 그룹으로 묶이며 그룹 중 하나만 선택할 수 있다.

즉, 다수의 체크박스는 동시에 체크가 가능하지만, 다수의 라디오(한 그룹)버튼은 동시에 한 개만 체크가 가능하다.

 

이렇게 보니 내가 구현하려는 기능은 radio로 짜면 된다는 걸 쉽게 알 수 있지만, 이걸 몰랐던 나는 무작정 체크박스로 어떻게든 코드를 짜려 했다. 구글링으로 중복체크를 허용하지 않는 코드를 적용시켜보고, 배우지도 않은 jQuery를 어떻게든 활용해보려고 머리도 굴렸다.. 물론 너무 어려워서 금방 포기했다.


 

window.onload

radio 타입을 찾아내 중복 체크 현상도 해결하고 이제 기능을 구현하면 되겠구나 하던 차에 한 가지 신경쓰이는 점이 있었다. 

 

페이지가 로드되면, Stroke나 Fill에 체크가 하나도 안되어있다. 사실 내가 짠 코드가 완벽하진 않기 때문에 체크가 안되어있어도 사용은 가능하다. 그렇다 하더라도 사용자 입장에서는 아무 체크도 안되어있기 때문에 체크를 해야 한다고 느낄 것이다. 이것은 사용자에게 불필요한 동작을 요구하는 셈이 되므로 불친절한 느낌을 줄 수 있다고 생각했다.

 

이를 해결하기 위해 찾아본 결과, window.onload()를 이용하면 해결할 수 있다는 걸 알게 되었다.

window.onload() 는  자바스크립트에서, 페이지가 로드되면 자동으로 실행되는 전역 콜백함수이다. 위에서부터 순차적으로 동작하는 인터프리터 언어적 특성으로 인해, 함수 작성 위치에 따라 에러가 발생할 수 있는데 이를 방지해주는 함수이다. 이 함수를 이용해 페이지가 로드될 때, Stroke 모드를 기본적으로 체크하도록 설정하였다.

 


 

선택자 ...

 

이제 태그는 작성했으니, 자바스크립트에서 태그를 선택해 이벤트 핸들링을 해야하는데.. 태그 선택하는데도 여러번 실패를 겪었다... 너무 헷갈린다 ㅠㅠ

 

1. document.getElementById

태그에 주어진 id 값으로 선택하는 선택자이다. 처음엔 라디오 박스 두 개에 각각 id를 주고, 각각 체크 상태를 확인해서 처리하려고 했다. 하지만 작성하다보니 코드가 너무 길어지는 문제점이 생겼다. id가 2개니 함수처리도 2개를 해야하고... 뭔가 말로 설명하기도 어려운 그런 문제들.. 도저히 답이 안보여서 10분 만에 때려친 방법이었다..

 

 

 

2. document.getElementByName

태그에 주어진 name 값으로 선택하는 선택자인데, id는 중복이 안되는 고유값이지만  name은 중복이 되기 때문에 radio 태그 전부에 name값을 radio로 주고 한꺼번에 처리하려고 했다. 근데 요놈이 이상한게, 배열의 형태로 선택한다고 한다.

그래서 이 녀석으로 처리를 하려면, for 구문으로 배열 하나하나에 접근해서 처리해야 한다는 거다. 처음엔 이걸 몰랐어서 콘솔로그에 찍히는 null 값을 보고 멘붕이 왔었다... 구글링을 통해 배열로 처리해야 한다는 사실을 알았을 땐 얼마나 허무했던지... 배열 요소가 2개밖에 없긴 했지만 for 구문을 작성해 처리를 하다보니 코드가 길어지고 복잡해지는 느낌이 들어 이 방법도 폐기했다.

 

 

3. document.querySelector

최종적으로 사용하게된 선택자는 이녀석이다.

 

input 태그들을 label 태그로 감싸고, label 에 id값을 radio-group으로 줘서 label 태그를 참조하여 해결했다.

 

이벤트 처리 함수

 

각 라디오 박스 체크에 따라 isFill 값을 true 혹은 false로 처리하고,

cancelPainting() 함수에서 이를 처리해줬는데, 이 함수는 mouseup 동작에 맞춰서 실행되므로, 아래 움짤처럼 모양의 틀을 그린 뒤, 마우스를 뗌과 동시에 모양이 색으로 칠해지는 것이다. 그냥 fill을 적용해서 그리는 것보다 이쁘게 그려지기도 하고, 따로 처리하는 것보다 코드도 간단해서 이렇게 처리하게 되었다.

 

 

 

마무리 및 느낀점

  • 자바스크립트는 너무 어려운 것 같다... 내가 해낼 수 있을까??
  • 다음에는 텍스트 글꼴이랑 텍스트 크기를 조절할 수 있는 기능도 추가해 볼 것이다.