Skip to content

kimkyeseung/polyshaper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Polyshaper

Introduction

Polyshaper는 업로드한 이미지를 기반으로 색상을 자동으로 채워주어 일러스트레이터나 포토샵보다 편하고 빠르게 로우 폴리 이미지를 제작할 수 있는 로우 폴리 이미지 제작 어플리케이션입니다.

Tryout

https://polyshaper.netlify.app/

Period

2018년 10월 20일 ~ 11월 2일

Prerequisites

  • Chrome Browser(권장)

Installation

git clone https://github.com/kimkyeseung/polyshaper.git
npm install
npm start

Feature

  • 메인페이지에서 이미지를 업로드할 수 있습니다.
  • 이미지 파일을 드래그 앤 드랍으로 업로드 할 수 있습니다.
  • 업로드한 파일이 10MB 이내의 이미지 파일인지 검사하여 아닐시 경고창을 표시합니다.
  • 이미지 업로드 후 마우스 클릭으로 점을 찍을 수 있습니다.
  • 점이 세 개가 찍히면 자동으로 삼각형이 형성되고 해당 영역의 이미지 색상 평균 값으로 채워집니다.
  • 만들어진 삼각 폴리에는 각 꼭지 점마다 스냅이 생겨 일정 거리 이내의 영역을 클릭하게 되면 점에 물리도록 되어있습니다.
  • EditMode로 변경시 (단축키 : Ctrl(command) + E) 만들어진 면의 영역을 수정할 수 있습니다. (기본 : AddMode)
  • EditMode에서는 Ctrl(command) + E + 마우스 클릭으로 해당 셀을 직접 선택하여 색상을 원하는 색상으로 변경할 수 있습니다.

Polyshaper

  • VarianceCellsize를 조정하고 Auto Populate 기능으로 남은 배경을 자동으로 완성시킬 수 있습니다.
  • Variance : 각 폴리 들의 랜덤한 정도를 조정합니다. 0 부터 1까지 입력 가능하며 0이면 모든 셀이 가지런한 정삼각형이, 1이면 불규칙적이고 자유도가 높은 모양이 됩니다. (기본 0.4)
  • Cellsize : 각 폴리의 크기를 결정합니다. 셀의 크기가 작아질 수록 이미지의 선명도가 높아지지만 폴리아트의 느낌이 줄어들고 속도가 느려지게 됩니다. 기본 크기는 60px이며 최소 10px에서 최대 200px로 설정해두었습니다.
  • AddMode에서 점을 찍고 삼각형을 완성시키지 않은채 에딧모드로 변경하면 점은 취소되어 사라집니다.
  • AddMode에서 점을 찍고 삼각형을 완성시키지 않은채 Esc를 누르면 점은 취소되어 사라집니다.
  • Auto Populate 시에 생기는 폴리 이미지는 유저가 만든 폴리와는 별개로 컨트롤 되며 유저가 만든 폴리 아래에 있는 레이어로 취급됩니다.
  • Download Image 버튼을 통하여 제작한 폴리 이미지를 저장할 수 있습니다.
  • Reset Picture 버튼을 통하여 업로드한 이미지를 없애고 새로 이미지를 업로드할 수 있습니다.

Polyshaper

Tech Stack

  • 자바스크립트(ES2015+)를 기본으로 제작하였습니다.
  • Redux 라이브러리를 사용한 Flux 아키텍처 기반 설계를 하였습니다.
  • React, Webpack, CSS Modules을 사용한 컴포넌트 베이스 UI 아키텍처를 구현하였습니다.
  • HTML5 Canvas를 이용하여 그래픽 아트웍을 구현하였습니다.

Continuous Integration

  • 소스관리/빌드/테스트/배포의 지속적인 통합을 위한 CircleCI를 사용하였습니다.

Deployment

netlify를 이용하여 github repository를 배포하였습니다.

Version Control

  • Client, Server의 GIT Repoitory를 구분하여 독립적인 관리를 하였습니다.

Planning

  • Trello를 이용하여 일정을 관리하여 진행하였습니다.

Test

Jest와 Enzyme를 이용하여 Reducer및 Component 단위 테스트 구현

challenge

사각형이 아닌 영역의 색상값 추출하기

Polyshaper의 처음 기획 당시 가장 큰 관건이었습니다. 유저가 클릭하여 만들어낸 임의의 삼각형의 색상값만 추출이 되지 않는다면 이 프로젝트의 시작조차할 수 없었을 것입니다. Stack Overflow와 여러 기술 블로그, 개발 커뮤니티를 찾아다녔지만 저와 같은 목적으로 저와 같은 고민을 하는 사람은 없었습니다. 다행히 생각보다 쉽게 해결되었습니다.

색상을 추출하기 위해선 빈 캔버스에 해당 이미지를 새로 그려야했습니다. 폴리가 그려질 캔버스와 같은 위치에 같은 크기의 캔버스를 포개고 세개의 점을 좌표로 받아서 삼각형을 만든 후 clip()으로 이미지를 삼각형만큼 오렸습니다. 처음엔 createElement(‘img’) -> drawImage() -> beginPath() -> closePath() -> clip() -> getImageData() 순으로 코드를 작성하였는데 생각대로 진행되지 않았고 clip()drawImage()보다 선행되어야만 제가 원하는 결과를 얻을 수 있었습니다.

삼각형의 이미지 데이타 얻기

ctx.getImageData(sx, sy, sw, sh) 매소드는 이미지 데이터를 얻을 사각형 영역의 네 좌표만 받기 때문에 어쩔 수 없이 삼각형이 포함된 영역 전체의 좌표를 구하여야 하였습니다. ctx.getImageData()의 리턴 값(의 .data)은 단순히 픽셀 하나당 rgba의 순서로 이루어진 배열이었습니다. alpha 값이 제공되지 않았더라면 조금더 복잡한 연산이었을텐데 alpha값이 제공되고 사각형 중 삼각형의 영역이 아닌 부분의 alpha가 0이어서 쉽게 필터링할 수 있었습니다. 데이터를 자세히 살펴보니 안티앨리어싱이 적용된 것인지 alpha값이 0, 255 이렇게 두 값이 아닌 많은 중간값이 적용되어있었습니다. 저는 어느정도 확실한 이미지만을 얻는게 좋겠다고 생각이 들어서 200 이상의 값만 걸러 색상값으로 구하였습니다. 그리고 ~~연산자에 대해 알게되었는데 Math.floor()와 같은 결과를 얻을 수 있지만 더 빠르게 결과를 얻을 수 있다고 합니다.

자동으로 완성시키기 (Auto Polpulate)

아트웍이라는 것은 무슨 툴을 사용하더라도 노력과 시간이 필요할 수 밖에 없습니다. 색상의 값을 자동으로 구해준다 하더라도 각 폴리의 모든 꼭지점은 사용자가 클릭한 좌표를 토대로 존재하기 때문에 모든 점을 사용자가 클릭해야 한다는 점이 오래걸리고 귀찮게 여겨지는게 당연하다고 생각하였습니다. 그래서 저는 유저가 몇개의 폴리를 만들고 나면 그 폴리를 토대로 자동으로 완성되는 기능이 있기를 바랐습니다. 결론적으로 유저가 만든 폴리의 좌표를 토대로 남은 부분을 자동으로 채울 수는 없었지만 자동 완성된 배경을 하위 레이어로 추가하는 방법을 선택하였습니다.

그리는 방식은 삼각형 한 번, 역삼각형 한 번 교차로 그려냅니다. 처음 그렸던 삼각형의 오른쪽 두 점은 그 다음 그려질 역삼각형의 왼쪽 두 점이 됩니다. 그 역삼각형의 오른쪽 두 점은 다시 오른쪽에 위치할 삼각형의 왼쪽 두 점이 됩니다. colmaxCol이 되면 col은 0이되고 low는 + 1 되어 두 번째 줄부터는 역삼각형, 삼각형의 순서로 다시 삼각형이 그려지게 됩니다. 그렇게 화면을 가득 채울때까지 반복하게 됩니다.

일러스트레이터로 구현한 폴리 이미지 드로잉 메커니즘 일러스트레이터로 구현한 폴리 이미지 드로잉 메커니즘

일러스트레이터로 구현한 폴리 이미지 드로잉 메커니즘

캔버스에 그려진 폴리를 선택하기

캔버스에 그려진 이미지는 말 그대로 이미지이기 때문에 DOM의 엘리먼트처럼 따로 이벤트를 추가하거나 선택할 수 있는 개념이 아니었습니다. 그럼에도 불구하고 저는 각각의 폴리를 선택할 수 있어야 한다고 생각했습니다. 디지털 작업이니만큼 한 번 추가한 것으로 끝이 아니라 편집 및 수정이 가능해야만 툴로써의 가치가 있다고 생각하였기 때문입니다. 각 폴리 셀들은 x, y의 세 좌표로 이루어져 하나의 면을 구성하고 있습니다. 마우스를 폴리 위에 올렸을 때 마우스의 좌표(x, y)가 해당 폴리 위에 있는지 아닌지 확인하는 함수를 만들어야 했습니다.

이 곳을 참고하여 점이 삼각형 위에 위치하면 true를, 그렇지 않으면 false를 리턴하는 함수를 변형시켜 적용하였습니다.

Things to do

2주 동안의 완성을 목표로 좀 더 완성도를 높은 어플리케이션을 구현하고 싶어 Server는 애초에 기획에서 제외하였습니다. 가능한 정교하고 디테일하게 기능 구현을 하려고 하였으며 기능 구현 가능 여부가 불확실했던 상황이있었지만 잘 마무리 되어서 기쁘게 생각합니다. 처음 기획했던 기능을 구현하고 나서는 계속해서 단축키를 비롯한 디테일한 UI의 개선이 욕심이 있습니다.

  • 배경 및 사용자 추가 폴리 레이어 시각화 및 개별 컨트롤 가능하게 하기 (포토샵처럼)
  • 각 폴리 셀 별 테두리 두께 및 색상 입력 가능하게 하기
  • firebase 등을 이용하여 완성된 이미지 DB나 스토리지에 보관하여 갤러리 게시판 만들어 업로드하기
  • 실행취소(Undo) 및 실행취소취소(Redo) 기능추가 하기
  • 전반적인 UI 개선으로 좋은 사용자 경험 제시하기
  • Code Refactoring
  • Integration Test