Meme Maker 구현하기
<input type="file" accept="image/*" id="file" />
파일을 선택하는 인풋은 type 을 file 로,
여기선 영상은 필요하지 않으므로 accept 속성에 image/* 를 설정하여 이미지 포맷만 가능하게 지정한다.
// 파일 받기
function onFileChange(evt) {
console.dir(evt.target);
}
fileInput.addEventListener('change', onFileChange);
파일을 선택하고 콘솔을 확인하면, target의 files 에 내가 넣어준 이미지가 존재함을 볼 수 있다.
이 파일은 이제 브라우저의 메모리에 존재하게 되고
브라우저의 url 을 받아오면 해당 이미지를 볼 수 있게 된다.
// 파일 받기
function onFileChange(evt) {
const file = evt.target.files[0];
const url = URL.createObjectURL(file);
console.log(url);
}
fileInput.addEventListener('change', onFileChange);
target의 files 배열에 접근하여 넣어준 이미지가 0번째에 있으므로 읽어오고,
url 은 URL의 createObjectURL() 메서드로 접근할 수 있다. 해당 파일을 넣어주면 아래와 같은 콘솔이 뜬다.
blob:http://127.0.0.1:5500/4155fa20-bd5f-4701-beb5-8b362b928ed8
blob 을 포함한 내용을 주소창에 넣어주면 해당 이미지가 브라우저 메모리에 잘 읽혔음을 확인할 수 있다.
다만 이 주소는 현실의 인터넷에 존재하는 것이 아닌, 로컬 브라우저에서만 처리된 것이다.
// 파일 받기
function onFileChange(evt) {
// console.dir(evt.target);
const file = evt.target.files[0];
const url = URL.createObjectURL(file);
// console.log(url);
const image = new Image(); // <img />
image.src = url;
image.onload = function() {
ctx.drawImage(image, 0, 0, 500, 500);
}
}
fileInput.addEventListener('change', onFileChange);
url 을 받아와서, new Image() 로 img 태그를 만들어주고, src 를 읽어온 url 로 넣어준다.
그다음 이미지가 onload (다 읽어와주면) 되면 콜백함수를 넣어줘서 실행되게 해준다.
컨텍스트의 drawImage(이미지태그, x, y, width, height) 로 넣어주면 된다.
Text 넣어주기
text 를 넣어주기 위한 input 필드와 캔버스를 더블 클릭하면 그 텍스트가 보이게끔 만드려고 한다.
그렇다면 텍스트 값을 가져와서 strokeText 나 fillText 메서드를 사용해주면 되는데,
이때 lineWidth 가 그림 그리는 크기에 맞춰져 있어서 글자가 깨져나오게 된다.
이를 막기 위해선 글자를 출력할 땐 lineWidth 를 1로 바꾸고, 원래의 설정값으로 돌아가게 만드는 방법을 써야 하는데
이를 위한 메서드가 save 와 restore 이다.
function onDoubleClick(evt) {
ctx.save();
const txt = textInput.value;
ctx.lineWidth = 1;
ctx.strokeText(txt, evt.offsetX, evt.offsetY);
ctx.restore();
}
canvas.addEventListener('dblclick', onDoubleClick);
- ctx.save 는 현재 컨텍스트의 상태를 저장
- ctx.restore 는 저장된 컨텍스트의 상태를 다시 불러옴
이제 글자 크기를 조절하려면 옆에 사용하던 range 바를 이용한다.
강의에선 하드코딩했는데 이런식도 가능하다.
function onDoubleClick(evt) {
const txt = textInput.value;
if(txt === '') return;
ctx.save();
ctx.font = `${ctx.lineWidth * 12}px ` + 'serif';
ctx.lineWidth = 1;
ctx.fillText(txt, evt.offsetX, evt.offsetY);
ctx.restore();
textInput.value = '';
}
canvas.addEventListener('dblclick', onDoubleClick);
기준은 12px 로 했음!
브러쉬의 끝을 둥글게 만들기
컨텍스트의 lineCap 속성을 바꿔주면 되는데, 기본값이 squre 이므로 round 로 바꿔준다.
ctx.lineCap = 'round';
이미지 저장하기
function onSaveClick() {
const url = canvas.toDataURL();
const a = document.createElement('a');
a.href = url;
a.download = 'myDrawing.png';
a.click();
onDestroyClick();
}
saveBtn.addEventListener('click', onSaveClick);
canvas 의 이미지를 url로 만드는 메서드가 toDataURL() 이며,
해당 url을 a링크의 href 속성에 넣어주고, a링크에는 download 라는 속성이 있는데, 넣어주는 값은 다운로드될 때 이름이 됨
해당 속성을 넣어주면 클릭되는 순간 해당 이미지가 다운로드 된다!
싱기하당
CSS 로 간단하게 꾸며주기
여기선 몰랐던 개념들만 포스트하려고 한다.
input의 file 타입을 꾸미는 방법 ---> for 속성에 id를 넣어주면 해당 input 을 대신하여 label을 사용해줄 수 있다!
<label for="file">
Add Photo
<input type="file" accept="image/*" id="file" />
</label>
그래서 기존의 input은 display none 처리 해버리고 label을 꾸며주자.
for 안에 값을 id명으로 잘 넣었다면 굳이 저렇게 감싸주지 않아도 정상적으로 작동한다.
기초 완성!
챌린지 코드 - 폰트의 크기와 종류 변경...
일단 폰트 크기는 range 로 변경할 수 있는 상태이다.
종류 변경을 위해서
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font
위 문서 내용을 참고했다.
input 의 accept 속성의 값들은 위와 같은 값이 들어간다고 한다.
폰트의 확장자의 경우, TTF와 OTF 가 대표적으로 알고 있어서 두가지만 허용시켰다.
<label for="font-file">
Change Font
<input type="file" accept=".TTF,.OTF" id="font-file" />
</label>
, 로 구분된다고 해줘서 그렇게 해줬고 테스팅을 위해서 아무 폰트나 다운 받아보았다.
이 폰트를 쓰는 곳이 많아서 예뻐서 다운.
// 원하는 폰트로 변경하기
let newFont = 'serif';
async function onChangeFont(evt) {
const font = evt.target.files[0];
const url = URL.createObjectURL(font);
newFont = new FontFace('newFont', `url(${url})`);
await newFont.load().then((loadedFont) => {
console.log(loadedFont);
document.fonts.add(loadedFont);
})
}
fontFile.addEventListener('change', onChangeFont);
공식 문서대로 이렇게 했고
여기서 조금 헤맸는데 font 적용해줄 때 new FontFace에서 지어준 'newFont' 부분이 문자열이 되어야 제대로 설정된다.
ctx.font = `${ctx.lineWidth * 12}px ` + (newFont === null ? newFont : 'newFont');
이거때문에 자꾸 FontFace Object가 찍혀서 안되는 바람에 공식 문서를 쥐잡듯이 찾았다.. 이리 쉬운걸 ㅠㅠ
위의 삼항조건문은 혹시 폰트를 넣지 않았을 때 예외처리를 해준것이다. 원래 지정했던 serif 가 들어가있음.
그외 Stroke 와 Fill 선택 버튼 및 그리는대로 fill 해주는 등 챌린지가 있었지만... 여기까지!
충분히 canvas 와 친해진 기분이다.
'Web Study > 노마드코더' 카테고리의 다른 글
노마드코더 python 웹스크래퍼 만들기 - 2 (0) | 2023.06.15 |
---|---|
노마드코더 python 웹 스크래퍼 만들기 - 1 (0) | 2023.06.14 |
노마드코더 JS로 그림 앱 만들기 - 2 (0) | 2023.06.09 |
노마드코더 JS로 그림 앱 만들기 - 1 (0) | 2023.06.08 |
바닐라 JS 크롬 앱 만들기 (6~8) (0) | 2023.02.27 |