JS와 캔버스로 왠지 친숙한 둥글게 말려있는 디자인의 선택상자를 만들어보았습니다.
당시 만들던 웹앱 컨셉이 애플스타일이었고, 날짜 선택기를 만들 때도 최대한 그러한 분위기를 내고 싶었습니다.
캔버스를 활용해서 만드는 것에는 성공했으나 더 보편적으로 사용할 수 있도록 만들고 싶었고, 성능 개선에 대한 욕심도 났습니다.
그래서 시간이 지난 후 새롭게 만들어보자는 생각을 했습니다.
최대한 기존 html사용법을 그대로 답습하여 만들 수 있도록 하는데 초점을 맞추었습니다.
html의 SELECT태그를 그대로 이용하여 미려한 디자인으로 바꾸어줍니다.
SELECT태그를 그대로 사용하기 때문에 만약 캔버스를 사용하지 못하는 웹환경이더라도 사용에 지장이 없습니다.
"selected" 속성을 그대로 사용할 수 있으며, 전용 "infinite" 속성을 부여하면 처음과 끝이 이어져 무한히 스크롤할 수 있게됩니다.
글꼴, 글자색과 배경색상은 style을 통해 변경할 수 있습니다.
onchange 이벤트도 그대로 발생하기 때문에 대부분의 경우에 SELECT 다루듯이 하더라도 괜찮습니다.
사용자는 손가락을 튕기거나, 클릭하여, 혹은 마우스 스크롤을 하여 선택할 수 있습니다.
기존에 만들었던 코드는 스파게티를 넘어 짜파게티 상태였기 때문에 완전히 새롭게 만들게 되었습니다.
그래도 기존에 만들어 본 것을 다시 만드는 것이어서 처음처럼 어렵지는 않았습니다.
우선 객체지향적인 관점으로 만들어야겠다는 생각을 하게 되었습니다.
몇 가지 이유가 있었습니다.
우선 한번에 여러개를 사용할 수 있도록 하고 싶었습니다.
기존 코드에서는 여러개의 요소를 동시에 사용하기 번거로운 구조였습니다.
또한 스파게티 코드가 되는 것을 막기위해 더 읽기 쉽고, 유지보수가 용이하게 코드를 작성하고 싶었습니다.
기존 코드는 버그 수정을 하려면 처음부터 끝까지 다 읽어봐야했고, 하나를 수정하면 다른 쪽에서 문제가 발생하곤 했습니다.
결론적으로 더 짜임새있고 확장성이 있는 코드를 만들기 위해서 객체지향을 이용하기로 했습니다.
자바스크립트에서 객체지향을 적용하기 위해서 클래스구조를 이용했습니다.
둥글게 말린 디자인이기도 하고, 손끝에서 움직이는 느낌을 내기 위해서는 최적화가 매우 중요했습니다.
모양이 유사하더라도 프레임이 많이 끊기면 애플의 그것과 같은 느낌이 잘 살지 않았습니다.
그래서 개발하는 동안 가장 오래 고민한 부분이 최적화였습니다.
둥근 디자인을 위한 연산과정을 줄이기 위해서 다양한 방법을 시도해보았습니다.
높이에 따른 삼각함수의 연산을 미리 전처리해두고 배열에 담아두는 방식으로 연산횟수를 줄일 수 있었고, 캔버스에서 실제 변경되는 부분만을 렌더링하는 방식으로 연산 범위를 줄일 수 있었습니다.
offscreen 캔버스에 작업 한 뒤 onscreen 캔버스로 업데이트 하는 방식도 적용해두었고, 리스트를 캔버스에 한번에 그려둔 뒤 필요한 부분을 가져오는 방식을 통해 글자의 렌더링을 줄여 최적화할 수 있었습니다.
폰트가 로딩되기전에 컴포넌트가 먼저 생성되어 기본 글꼴로 적용되는 문제가 있었습니다.
해당 문제는 내부에 option의 내용을 미리 작성해두고 document.fonts.ready 후에 컴포넌트가 생성되도록 하여 해결할 수 있었습니다.
한편 크로미움엔진과 애플웹킷엔진의 캔버스를 다루는 방식이 상이하여 발생하는 문제도 있었습니다.
이 문제는 무한히 스크롤이 가능해지는 "infinite" 기능을 만들 때 발생했습니다.
크로미움엔진은 캔버스의 범위 밖을 렌더링하려하면 캔버스에서 보이는 부분만 그리고 캔버스 밖은 공백으로 그렸지만, 애플웹킷엔진은 아예 범위 밖으로 넘어가지 못하게 끝자락에 맞추어 렌더링했습니다.
이는 결국 더 까다로운 애플웹킷엔진을 기준으로 맞추어 해결했습니다.
현재 preset 기능을 만들고 있습니다.
이 기능이 완성되면 날짜선택기와 같은 요소를 더 쉽게 만들 수 있게 되며, 써드파티로도 더 확장이 가능해집니다.
추후에 "disabled" 속성이나 "multiple" 속성을 이용할 수 있도록 할 예정입니다.
또한, 키보드를 통한 조작이나 시각장애인을 위한 접근성에 대해서 고민해볼 생각입니다.