All Articles

wecode 2주차_2일 TIL_CSS와 js로 이미지자르기(feat. Sprites)

image.png

스프라잇 샤워가 아닌 답답함과 고통만 가득이였던 sprites.. 찾아본 sprites는 쪽화면이라는 뜻이었다. 업계에선 많이 쓰이는 용어같은데 나만 몰랐어~

그리하여 시작된 나의 힘겨운 여정쓰…

  • 첫 시도 : p5 library를 이용해 json 파일로 이미지 쪼개기 (p5 알못이라 실패)
  • 2차시도 : canvas로 이미지 자르기 성공! but 함수 넣기 힘들어서 결국 포기
  • 3차시도 : 멘붕상태에서 결국 help 요청해 css로 이미지 자르기 성공!

이걸로 꼭 해봐야겠어!! 하고 마음 먹었다가 계속 안되고, 실패하고 갈아엎다보니 멘탈이 탈탈 털리는 하루였다. 앞으로 프로젝트 들어가면 이런 일들이 많아질텐데.. 지금 이 사소한 이미지 자르는 것에서부터 집착을 했으니 정말 ㅠㅠ 멘탈 관리를 잘 해야 할 것 같다!


CSS Imgae Sprites

sprites라고 검색하면 사실 내용이 잘 나오지 않는다.. 죄다 캔버스를 이용하거나 sprite.js 였나 외부 프로그램을 쓰는 것밖에 안 나온다. W3 school에 나오는 글도 잘 이해가 되지 않아서 3기 동기 가마니쓰의 도움을 받았다 ㅠㅠ 동기사랑은 나라사랑~~♬

background: url(이미지 경로) 0 0;

CSS 속성에 background 라는 attribute을 적고, image 경로와 좌표값(left, top)을 찍어준다.

#hero{
    background: url('./images/hero.png'); 
    background-position-x: 140px;
    position: absolute;
    width: 35px;
    height: 54px;
    left : 400px;
    top : 545px;
}

hero라는 id에 위와 같은 값들을 넣어주면… image.png

뙇! 이미지가 이렇게 뜬다. 지금 배경 위에 김영웅씨 이미지가 올라가 있지만.. 원래는 네 장짜리 그림이다. 이렇게!

image.png

근데 아무리 좌표값을 찍어봐도 도저히 이해가 가지 않았다… 왼쪽부터 아닌가.. 이상한데 그래서 또다시! 동기인 아기호랑이님의 도움을 받았다 ㅜㅜ 사고회로가 정지했다…사ㄹ…려ㅜ줘… baby Tiger 최고 ♥

image.png

저 네모네모한 그림을 원기둥모양으로 돌돌 말았다고 생각해보자 그러면 저 좌표가 찍히는 원리가 이해가 얼추 간다. 나는 왼쪽부터 숫자를 세어야 한다고 생각 했는데 그 반대였다..! 와우…!

여튼… 저 상태에서 left값과 bottom값을 추가해서 김영웅씨의 로딩 위치를 정해주면 된다. 영웅쓰를 중간에 띄웠으므로 인제 키보드 이벤트를 추가해줘야 한다

하루종일 이거 붙잡고 있으면서 블로그에 내용 정리하느라 시간을 굉장히 많이 썼는데.. 집 갈쯤 되니까 해결이 되긴 됐다! 물론 여러 사람들의 도움이 있긴 했지만.. 여튼 해냈다.. 기분이 조금 나아졌다!


원래는 여기까지지만! 여태까지 정리한 캔버스에 대한 내용이 너무 아까우니깐 canvas에 대해 내용도 남긴다 ㅜㅜ

Canvas 와 drawImage()

지난번 포스팅에서 살펴봤던 것처럼 캔버스는 html 태그이고, 이미지를 불러온다. 설명이 부실했던 것 같아서 다시 써보자면!!!

image.png

canvas 자체로는 그냥 빈 캔버스를 생각하면 될것 같다! canvas 태그를 html에 추가해도 아무 일도 일어나지 않는다. 그냥 빈 종이기 때문쓰.. 여기다가 getContext 함수를 이용해서 context를 랜더링 해줘야지 화면에 무언가를 그려낼 수 있다. 이 순서가 맞는지 모르겠지만 나는 일단 이렇게 했다!

  • html
    -html에 canvas 태그를 심는다 끝!
    -js로 넘어가시오
  • js
    -new Image 메소드로 파일의 사진을 불러오고 src로 이미지 파일 경로 연결쓰
    -불러온 이미지를 화면에 띄울 수 있게 onload 함수를 만들고, 아래에 작성할 init함수를 그 안에 연결
    -Elementby뭐시기(Class 혹은 Id)로 html에 심어놓은 canvas태그를 DOM으로 불러와 canvas라는 변수에 대입
    -ctx라는 변수에 2d이미지를 불러올 수 있도록 getContext메소드 쓰기
    -init함수 안에 drawImage메소드를 이용해 캔버스에 심어놓은 이미지 불러오기

여기서 ctx가 무슨뜻일까 정말정말정말 궁금했는데 별거 아니였다! CTO도 KTX도 아닌, context의 줄임말이였다 ㅎ…

let hero = new Image()
hero.src = './images/hero.png';
window.onload = function() {
    init()  
}

let canvas = document.getElementById('hero')
let ctx = canvas.getContext('2d')

function init() {
  ctx.drawImage(hero,0,0,35,54,0,0,35,54) // 앞모습
// ctx.drawImage(hero,35,0,35,54,0,0,35,54) // 뒷모습
//  ctx.drawImage(hero,70,0,35,54,0,0,35,54) // 왼쪽모습
// ctx.drawImage(hero,105,0,35,54,0,0,35,54) // 오른쪽모습
}

image.png 김영웅씨는 앞뒤왼오 모습이 4개나 되서 하나씩 잘라주기 위해 drawImage 좌표값을 각각 다르게 줘서 잘라봤다. 일단 앞모습을 제외하고 다 주석처리 해놨는데 김영웅씨를 움직일 때 각각의 모습을 살려야 할 것 같다

drawImage의 인자들을 살펴보자면… 요소가 많아도 너무 많다.. 그래서 넘넘 헷갈려서 나도 다 찍어보면서 확인했다 ㅠㅠ context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

왼쪽부터 순서대로.. 이미지, 자르는 기준점의 x축, 자르는 기준점의 y축, 자르려는 이미지가 기준점의 x축으로부터 얼마나 떨어져 있는가, 자르려는 이미지가 기준점의 y축으로 얼마나 떨어져있는가, 이미지를 띄울 위치의 x축, 이미지를 띄울 위치의 y축, 이미지의 가로길이, 이미지의 세로길이

글로 써보고 종이에 직접 좌표를 찍어보니까 이제야 이해가 간다! 뿌듯뿌듯~ 그림으로 보면 더 이해가 쉽지요~ image.png

나는 김영웅씨를 게임 화면의 중앙에 띄워야 하기 때문에 이미지를 띄울 위치의 x축과 y축을 다시 설정했다! 처음엔 무작정 CSS로 띄울 생각을 했는데 어쩐지 안 먹힌다더라니.. drawImage에 값을 줘야했군!!! 근데 문제가 생겼다… 김영웅씨의 전체길이보다 더 큰 값의 숫자를 입력하면 화면에 출력이 되지 않는다…

해결책1: html로 돌아가서 canvas에 배경과 동일한 width와 height 값을 주었다 해결책2 : ctx.drawImage에 이미지를 띄우고 싶은 위치의 좌표값을 설정한다

ctx.drawImage(hero,0,0,35,54,400,545,35,54)

800*600의 이미지라 처음엔 400, 600의 값을 주었지만, y축을 캐릭터가 벗어나기 때문에 화면에 나타나지 않았다. 그래서 y축에는 적당히 600보다 작은 값인 545의 값을 줬다. 그 결과…

image.png

드디어 김영웅씨 센터로 진출 성공~ 센터의 주인공은 ↖나야나~ 나야나↗ 이제 김영웅씨가 움직일 수 있도록 key event를 줘야하는데 그것은 다음 시간에 다시~~♬

Reference

sprite

canvas