애플 웹사이트의 맥북 프로 16인치를 보면 볼 수 있는 인터랙션 디자인으로 스크롤을 내리면 한 이미지가 화면 가득 채워질 때까지 서서히 크기가 커진다.
화면을 가득 채울 만큼 이미지가 커지고 나면 다음 이미지가 밑에서부터 서서히 올라오는데, 이 부분을 오늘 구현해봤다.
처음에는 새로운 이미지를 담을 canvas를 한 개 추가하여 밑에서부터 이미지를 올라오게 할 생각이었다. 하지만 이 방법은 서서히 이미지를 올라오게 할 수 없어서 실패했다.
다음 방법으로 기존의 canvas의 밑에서부터 drawImage로 새로운 이미지를 그리면 될 것 같다고 생각을 했고, 이를 위해서는 drawImage의 인수로 들어갈 수 있는 좌표 높이와 이미지의 높이를 알아야 했다.
Syntax : ctx.drawImage(image, dx, dy, dWidth, dHeight);
즉, dy와 dHeight를 구해야 했다. dx와 dWidth는 구할 필요가 없었는데 단순하게 캔버스 처음부터 캔버스의 width만큼 칠하면 되기 때문이다.
dy는 canvas의 총 높이부터 시작해서 0까지 감소하도록 값을 할당했고, dHeight는 반대로 0부터 canvas의 총 높이까지 증가하도록 값을 할당했다.
이렇게 되면 처음에는 높이가 0인 이미지에서부터 canvas의 높이를 가진 이미지까지 들어가게 된다고 생각했기 때문이다.
코드를 모두 완성하고, 스크롤을 내려 확인을 해본 결과 원하는 대로 동작은 하지만 이미지가 서서히 드러나는 것이 아니라 하나의 완성된 이미지 자체가 높이만큼의 비율로 점점 커지는 것을 볼 수 있었다.
이유는 당연하게도 이미지를 자르고 하는 과정이 없었기 때문에 첫 번째 인수로 전달한 이미지 자체의 크기만 변해서 canvas에 들어가는 것이었다.
이제는 도저히 방법을 찾을 수 없다고 생각해서 강의를 봤고, drawImage메소드에 다른 Syntax가 있는 것을 확인했다.
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
s = source image
d = destination image
위의 인수가 할당되면 알아서 계산해서 이미지가 그려지는 것이다.
인수가 많아서 알아보기 힘들 수 있지만, s와 d만 구분할 줄 알면 된다.
간단하게 s는 원본 이미지를 말하며 원본 이미지의 x,y좌표와 넓이, 높이를 인수로 입력하게 되면 입력된 값을 토대로 이미지를 가져오는 것이다.
그리고 d는 이전에 계속 사용하던 값으로, 실제 canvas에 그려지는 image이다.
이것에 대한 자세한 설명은 MDN - drawImage 를 참조하면 된다.
이 방법을 사용해서 원본 이미지의 아래부분부터 윗부분까지 가져와서 canvas에 이미지를 그릴 수 있었고, 원본 이미지의 크기와 canvas의 크기가 같지 않았다면 이미지의 비율을 구해야 하는 대참사가 일어날 뻔했지만 다행히도 크기가 같았기 때문에 s와 d에 같은 값을 할당해 주었다.
이제 부드럽게 이미지가 바뀌고, 이미지가 모두 바뀌었을 때 scale을 기존 이미지 scale의 반값으로 설정해 점차 이미지가 작아지게 했고, 완전히 작아진 후에는 position을 변경해 주어 아래에 있는 content가 보이도록 margin-top을 주었다.
이 과정은 그렇게 어렵지 않았다.
이렇게 애플 웹사이트의 인터렉션 디자인을 클론 코딩하는 것을 마무리했고, 이제 더 부드러운 스크롤과 더 좋은 성능을 위해 리팩토링을 할 차례이다.
리팩토링까지 마무리하면 나만의 사이트를 만들어 볼 생각이다.
현재 scale이 반으로 줄어들고 다음 content가 나올 때 사이즈를 변경하면 사이트가 이상하게 변하는 버그를 발견했고, 이를 해결하기 위해 여러 가지 방법을 사용해봤지만 해결하지 못했다.
가장 쉬운 방법은 사이즈를 변경할 때 아예 새로 고침을 한 것과 같이 로드를 시킨 다음 로드가 모두 완료되면 화면에 표시해 주는 것이라고 생각한다.
하지만 현재 왜 이런 오류가 발생하는지 이유를 알고 싶은데 모든 코드를 다 뜯어봐도 이유를 알 수가 없다. 내일 다시 봐야겠다.