F#번외편 Framer X Beta 와의 만남

대기번호 1751번. 초대장을 손꼽아 기다려 왔는데, 드디어 Your Framer X Beta invite라는 제목의 메일을 받았다. 왔네왔어. 다운로드를 받습니다.
일단 지금 난 너무 떨리므로, 어떤 것도 제대로 해 볼 수 없을 것이다. 그보다는 Framer와 언어부터 다르기 때문에 건드릴 수 없다는 것을 알고 있다.
대략적인 리뷰를 해 보도록 하겠다.

기분탓인가 다운로드 속도는 왜 이리도 느린 것인가. 빨리빨리. 설치 빨리빨리.

첫화면을 접한 소감

외관이 몹시 심플하다. 베타 버전에서 가장 중요한 네 가지 메뉴만을 보여주고 있다. 정식 버전의 메인화면은 어떨지 기대가 된다.
video를 누르면 지금까지 예고해 왔던 소개 영상들을 볼 수 있다.
그다음 Docs. Docs는 Framer를 공부할 때도 가장 많이 활용하는 편이다. 이번에도 열심히 활용할 수 있길 바라며 첫 페이지를 읽기 시작했다. 프레이머X 는 그야말로 뛰어난 디자인툴이자 설계 툴이자 개발툴이라 소개하는 글이었는데, 여기서 또 그동안 예고 영상을 보며 아쉬워 했던 부분을 짚어준다. 코드를 짜지 않고도 뛰어난 화면 설계가 가능하지만 코드 짜는 것을 즐긴다면 그또한 프레이머X가 최고의 환경이라니. 그럴수가. 디자인과 프로토타이핑을 각각 별개로 만들어왔던 다른 툴들의 단점을 극복했다는 점에서는 Framer 버전도 나름 괜찮은 수준이었다고 생각했었다. 그런데 Framer X 에서 더욱 발전된 형태를 자부하는 것 같아 궁금증은 대폭발이다. 아직 자바스크립트나 리액트에 대한 개념도 없기 때문에 화면 설계 이상으로 해 보기에는 무리가 있는 듯하다.

예제 다뤄보기

그래서 시작을 해 보기 전에 https://framer.com/x/examples 에 있는 예제들을 하나씩 살펴보기로 했다.
linking, stack, scrolling, components의 네 가지 예시가 있다.

좌측에는 Tools, Layers, Components, Store의 네 개 메뉴로 구성돼 있다. 아이콘의 디자인이 많이 변경되었는데, 특히 Frame에 대한 아이콘이 많은 변신을 했다. 예전보다 굉장히 함축적이지만 약간은 귀여운 스타일로 변경된 것 같다. 굉장히 깔끔해졌다는 느낌이다. 메뉴를 쭈욱 살피다가 Day Mode를 발견하고 눌러 보았다.

음 그래, 안그래도 스케치같다고 예전부터 생각했었지. 그런데 더 스케치 같네. 난 프레이머 유저니까 새로 선보인 Night Mode를 쓰도록 하겠다.

튜토리얼 예제들을 통해 알 수 있었던 것. 일단 화면 설계를 굉장히 쉽게 할 수 있다. 따로 플러그인 설치가 없이 바로 flow를 그릴 수 있고 인터렉션까지 간편하게 구현할 수 있었다. 프로토파이 + 인비전 + 플린토 등 의 기능이 다양하게 포함되어 있는 듯한 느낌을 받았다. 튜토리얼대로 간단하게 버튼의 더블클릭과 단축키 몇 개 만으로도 동적인 화면이 구성되는 것에 조금 감동을 받긴 했다. 개인적으로 마스터 버튼은 스케치의 심볼보다 더 간편했다. 포토샵의 스마트 오브젝트와도 비슷했는데, 어떤 식의 링크가 걸려 있는지 모르겠지만 화면 자체에서 버튼의 스타일을 변경하니 다른 화면의 버튼들도 자동으로 변경된다. 디자인 시스템을 만들기에 적당하지 않을까 기대가 된다. 스크롤 컴포넌트 안에 어떤 컨텐츠가 들어갈 지도 간단하게 선택하면 끝이다. 나니….그동안 기초 다지기를 했던 것 같은 느낌이다. 코드를 입력하는 설렘과 재미가 있었는데, 이젠 그럴 필요도 없어졌다.

그럼 너무나 재미있던, 코드탭은 어디에 숨겨 놨는가.

하, 코드탭은 정말 숨어있는 게 맞았구나. 이건 정말 개발자를 위한 혜택이 아닐까? 기본으로 사용하고 있는 에디터를 이용해 코드 편집을 하는 거라고 한다.
설치되어 있는 개발 툴로도 가능하다지만 Docs에서 추천하는 Visual Studio Code와 플러그인을 설치했다. 그리고 .tsx형식의 파일을 수정하라는데?
지금까지 겪어보지 않은 일이기에, 여기서부터 멘붕을 겪는다. Framer에서는 작업하다 막히는 부분에서 Docs를 눌러 바로바로 도움을 받았는데, 이건 어디서 Docs를 찾는 것인가.
그리고 Visual Studio Code에서는 어떻게 프레이머 작업 파일에 코드를 연결시킬 수 있는지도 잘 모르겠다.

그러다 나보다 먼저 x를 받은 유저의 영상을 보니, 새 컴포넌트를 code로 만들겠다는 창을 사용하고 있었다.
바로 인터페이스 좌측 하단의 이 영역이다. from Code를 선택하고 생성하니Visual Studio Code에서 새로운 창이 열렸다.

뭐라고 써 있는 건지 알아들을 수가 없구나. 커피스크립트 공부한 게 정녕 이렇게 무쓸이 되는 것이란 말인가?

오오 그런데 프레이머의 커피스크립트와 html 마크업 등을 공부한 덕분인지, 기본 코드를 분석하는 것이 생각했던 것만큼 막히지는 않았다. 용어 등등에서 차이를 느꼈지만 그래도 조금은  읽을 수 있다는 것이 스스로 놀랍다. 조금만 열심히(아니 아주 열심히) 공부하면 Framer X를 디자인, 개발 툴로서 아주 유용하게 사용할 수 있지 않을까 싶다. 툴도 더 설치해라 git도 설치해라 뭐 진입 장벽이 사실 매우 높아진 것 같지만. 거기다 리액트의 ㄹ 자도 모르는 나에게 프레이머 X는, 너무 어렵다!

– 대략 맛본 후기 끝 –

F#8 stateCycle()로 Toggle Switch Button 만들기

좀 있으면 Framer X Beta를 받아볼 수 있다. 이미 받아서 사용하고 있는 사람들도 있다. 인터랙션을 바로 사용 가능하게 하는 라이브러리가 생겼더라. 그걸 바로 끌어다 사용하는 예고편 영상을 보았다. 드래그 앤 드롭을 했을 뿐인데 그냥 움직인다. 나는 그런 걸 수동으로 코드 짜는 재미를 이제야 맛보고 있는데, 동적인 요소를 키트로 만든 라이브러리라니 약간 김이 샌다. 뭐 간편하게 인터랙티브 프로토타입을 구현할 수 있다는 점에서는 어마어마한 장점이 될 거라 생각한다. 그래도 컴포넌트의 동작에 관해서는 직접 코드로 짜 보고 싶었는데, 아쉽다.

그래서 간단하게 toggle switch button을 만들어보았다.

#Layer

먼저 레이어는 토글버튼의 bg와 핸들링 할 수 있는 스위치 버튼의 두 가지다. 이때 버튼의 크기는 고정 좌표로 하지 않고 계산하는 방식을 택했다. 스위치 버튼의 크기에 따라서 toggleBG 의 사이즈도 조절되도록 짜 보았다. toggleBG의 가로사이즈는 switchBtn의 사이즈의 두배에 패딩값의 두 배를 더한 값이다. 그리고 switchBtn의 maxX를 toggleBG width값의 2분의 1로 설정하면, 토글 스위칭의 on/off위치는 toggleBG의 2분의 1기준에서 좌,우로 이동하게 설정하기 편하다.

background = new BackgroundLayer
switchBtn = new Layer
width: 40
height: 40
borderRadius: 40
backgroundColor: “white”
padding = 4
toggleBG = new Layer
width: switchBtn.width * 2 + padding * 2
height: switchBtn.height + padding * 2
borderRadius: switchBtn.width
backgroundColor: “rgba(150, 150, 150, 0.2)”
toggleBG.center()
switchBtn.parent = toggleBG
switchBtn.maxX = toggleBG.width / 2
switchBtn.y = Align.center()

#States

이번에도 역시 stateCycle()을 이용한다. default와 다른 한 개의 state가 필요하므로, 간단하게 bg 컬러만 변경 되도록 설정했다. background의 경우, 디폴트를 제외한 두 가지의 state가 돌도록 했다. 버튼의 애니메이션 옵션에는 time을 짧게 주고, bg는 해가 뜨고 질 때의 느낌으로 조금 느리게 변하도록 했다.

background.states =
day :
backgroundColor: “#70B9DF”
night :
backgroundColor: “#19265A”
toggleBG.states.on =
backgroundColor: “#99CC66”
switchBtn.states.on =
minX: toggleBG.width / 2
toggleBG.animationOptions =
time: 0.3
switchBtn.animationOptions = toggleBG.animationOptions
background.animationOptions =
time: 3

#Events

이벤트는 정말 간단하다. 클릭 시 스테이트가 돌도록 하면 끝. 이때 switchOn이라는 변수를 지정 해주고 시작은 true로 한다.
switchOn = !switchOn 의 의미는 토글의 두 가지 상태가 다른 상황이라는 것에 대한 정의를 내려 주는 것 같다. 같은 버튼이지만 각 state로 전환되었을 때 다른 기능을 한다는 뜻인 듯. designhow라는 사이트에서 해 준 튜토리얼 강의를 보고 알게 되었는데, 스터디를 통해 좀 더 자세히 알아봐야겠다.

switchOn = true
“}”>switchBtn.onClick (event, layer) ->
switchOn = !switchOn
background.stateCycle([“day”, “night”])
toggleBG.stateCycle()
switchBtn.stateCycle()

구현 화면 보러 가기 >

F#7 Layer.stateCycle()로 두더지 잡기

 

F#6을 포스팅하면서 머릿속을 스쳐간 ‘두더지 잡기 게임’을 간단하게 만들어 보았다.

이번에 유용하게 쓴 코드를 세 가지 추려 본다면 이것이다.

Utils.randomNumber()

Utils.delay 숫자, ->

Layer.stateCycle()

#LAYER

레이어는 가로로 3개를 먼저 반복시켜주고, 3개 묶음을 다시 세로로 3회 반복시켜 총 9개의 홀에서 두더지가 튀어나오도록 했다.

for i in [0…3]
gameBox = new Layer
width: 280
height: 100
backgroundColor: “”
y: i * 100
parent: gameArea
for i in [0…3]
realHole = new Layer
width: 60
height: 80
borderRadius: 80
backgroundColor: “”
clip: true
parent: gameBox
x: i * 100 + 10
#hole의 maxY값을 realHome의 높이값으로 지정했다. 이것은 눈속임
hole = new Layer
width: 60
height: 60
borderRadius: 60
backgroundColor: “#AED4CD”
maxY: realHole.height
parent: gameBox
x: i * 100 + 10
hole.sendToBack()
#두더지 얼굴 만들기
moleBody = new Layer
width: 50
height: 100
borderRadius: 65
parent: realHole
x: Align.center
y: Align.bottom(+72)
backgroundColor: “#D56829”
clip: true

 

두더지의 생김새가 매우 간단하기 때문에 프레이머의 코드 탭에서 얼굴을 표현해보기로 했다. 얼굴에는 약간의 하이라이트를 주고 눈썹, 눈, 입 레이어를 추가해 반복시켜주었다. 이때 양쪽 눈썹의 각도와 입의 크기는 Utils.randomNumber() 를 이용해 다양한 표정을 레이어링 해 보았다.

다음은 점수를 표시할 텍스트레이어. F#5에서 공부했던, 클릭 시 증가하는 카운트를 위한 레이어 세팅이다.

count = 0
score = new TextLayer
text: count + ” 마리 잡았다!”
x: Align.center()
y: gameArea.maxY + 40
color: “lightgray”
fontSize: 20
fontWeight: 700
textAlign: “center”

 

#STATES

두더지가 랜덤하게 튀어나오려면 애니메이션에 대한 코드를 어떤 식으로 작성해야 하는 것일까. 반복문은 나의 취약점이다. 반복해 준 레이어를 통에 넣는 순간 어찌할 바를 모르게 된다. 레이어링까지는 간단히 해결 하였는데…그 다음부터 스멀스멀 멘붕이 오기 시작함.

이 9마리 두더지들에게 각각 인덱스 번호를 매겨주어야 하는 게 아닐까? 그리고 튀어오르는 애니메이션 하나를 정의한 다음, 두더지 번호들을 랜덤하게 호출하면 랜덤하게 튀어나오려나? 그럴싸하다고 생각했는데, 그래서 이걸 코드로 어떻게 짜야 하는 것일까?

머리를 굴려보고 굴려보다 우연히 유튜브 강의를 보게 되었다. 강의는 이것 https://youtu.be/hSIdPgCkEBw

stateCycle()이 이렇게 유용하게 쓰이는구나! 그렇다면 지금까지 생각했던 애니메이션 구조를 버리고 이걸 이용해 보도록 하겠다. 두더지가 들어가 있을 때의 상태를 기본으로 하고, 튀어오르는 state를 설정한다. stateCycle()의 기본 사이클은 ‘디폴트와 설정한 값’이다. state의 세팅이 끝났으면, 바로 애니메이트 시켜 준다. 이때 delay값을 1초부터 3초까지 랜덤으로 지정해 놓았으므로, 두더지들이 제각각 튀어오르는 동작은 성공했다.

for i in [0…9]
moleBody_array[i].states.pop =
y: 10
opacity: 1
options:
time: 0.4
curve: Spring(damping: 0.3)
delay: Utils.randomNumber(1,3)
moleBody_array[i].animate(“pop”)

두더지 게임에서는 때리기 전에 숨기도 한다. 그래서 다시 들어가도록 Utils.delay를 이용해 두더지들이 아무 때나 숨도록 하였다. 이때 digtime은 랜덤하게 지정했는데, 그랬더니 희한한 눈속임 기능이 구현되었다. 이미 랜덤한 시간에 튀어오르고 숨고를 반복하고 있는 와중에 또다시 digtime이라는 변수를 설정해 주었기 때문에, 어떤 때는 두더지가 한번에 숨기도 했다. 스터디 시간에는 digtime을 고정값으로 변경해 보았는데, 그때 나오는 결과도 흥미로웠다.

Utils.delay digtime, ->
for i in [0…9]
moleBody_array[i].stateCycle()

#EVENTS

사용한 이벤트는 아래의 한가지다. 간단하게 요약해 보면, 클릭했을 때 state가 바뀌는 것이다. 카운트는 1씩 증가하는데, 두더지가 튀어올랐을 때 때리는 경우에만 카운트가 증가하도록 설정했다. 두더지가 튀어오르는 state를 보면 y값이 10이므로, y가 10이면 카운트를 증가시키는 코드를 넣어 주었다. 그리고 두더지를 때리면 숨어야 하므로, click했을 때 state가 바뀌도록 설정했다. 그리고 애니메이션이 끝나도 다시 튀어올라야 하므로, onAnimationEnd 이벤트를 주고 pop이라는 state로 다시 애니메이트 시켜줬다.

moleBody_array[i].onClick ->
hammer.play()
if this.y == 10
count += 1
score.text = count + ” 마리 잡았다!”
score.color = “black”
this.stateCycle(time: 0.4, curve: Spring(damping: 0.4))
#stateCycle이 끝나면 다시 애니메이션을 시작해줌.
moleBody_array[i].onAnimationEnd ->
this.animate(“pop”)

 

그래서….이 게임은 무한대다. ㅋㅋㅋ

재미있는 요소로 공부하는 것도 좋은 방법이라 생각한다. 하고싶은 걸 만들면서 공부할 수 있으니까 그만큼 성취감도 높아지는 듯.
나의 튜토리얼은 계속 된다. 진정한 GUI 인터랙션을 만들기 전까지는 일단.

구현 화면 보러 가기 >