디자이너를 위한 코드 with Framer #6

Jiyong Ahn
11 min readMay 14, 2016

참고: 이 글은 2016년에 작성된 글입니다. 프로그래밍의 원리는 같지만 예제가 작동하지 않을 수 있습니다.

디자이너를 위한 코드 시리즈의 마지막 글이다. 프레이머에서 기본적으로 레이어를 만드는 것 부터 기초 프로그래밍에 해당하는 변수, 조건문, 반복문을 설명하면서 구현에 필요한 몇 가지 필요한 개념들도 함께 소개했다. 가급적이면 최소한의 개념으로 최대한의 시각적 결과물을 얻을 수 있도록 노력했지만 Framer로 처음 코드를 접하는 디자이너에게는 역시 쉽지 않았을 것이다.

나 역시 처음 코드를 접했을때 궁금한 부분에 대해서 누군가에게 물어보면 알려주는 사람은 너무나 당연하게 설명하기에 당최 이해가 가지 않았던 기억이 생생하다. 6개의 글로 기초에 대한 모든 설명은 할 수 없었지만 이 글을 읽고 나서는 적어도 ‘조금 노력하면 해 볼 수도 있겠구나’라는 기대감과 코드에 대한 흥미를 가지는데 조금이라도 일조할 수 있었다면 이 글을 쓰는데 투자한 시간이 아깝지 않을 것 같다. 흥미만 생긴다면 이 글에서 채워지지 않는 부분들은 Google이 모두 해결해 줄 것이다. :)

그럼 이제 앞서 소개한 변수, 조건문, 반복문을 지나서 -

function 함수

두둥 함수만 남았다.

전에 얘기한적이 있지만 함수에 대한 사전적 정의에 대해 다시 얘기해보려고 한다.

기능을 (수행)하다.

우리는 ‘기능을 하다.’ 라는 의미에 집중할 필요가 있다. 왜냐하면 이 의미가 실제로 예제를 작성해보기 이전에 함수에 대해 설명할 수 있는 모든 것이기 때문이다.

아마 Framer로 코딩을 하면서 모든 코드가 순차적으로 딱 한 번만 실행 될 것이라면 함수는 거의 쓸 필요가 없다. 그리고 온전히 Framer가 만들어 놓은 기능만 사용해도 적당한 예제를 만드는데에는 크게 문제가 없을 것이다. 하지만 실제로 코드를 작성하다보면 비슷하거나 똑같은 기능을 하는 코드가 어려군데에서 매우 빈번하게 사용된다. 이럴 때 함수를 사용하면 아주 유용하다.

함수에 대해서 좀 더 설명하기 전에 함수라는 이름에서 오는 거부감을 조금이라도 없애보고자 이 글에서는 함수라 부르지 않고 ‘기능’이라고 부르겠다.

이제부터 함수를 ‘기능’으로 설명한다.

우선 하나의 레이어를 x축으로 이동하는 애니메이션을 만들어 보겠다. 이제 이정도는 껌이져…?

단순한 애니메이션이다. 그럼 이제 여기에 빨간색 레이어 아래에 파란색 레이어를 추가해서 똑같이 x축으로 이동하도록 만들어 보자.

대충 오른쪽 결과물을 보고 #5에서 설명한 반복문을 떠올린다면 아주 좋은 현상이다. 코드에서 특정 결과물을 얻으려 할 때 어떤 코드를 쓰면 좋을지에 대해 정답은 없다. 본인이 아는 방식으로 효율적으로 코드를 짜면 그게 본인에게는 정답이 된다. 그럼 반복문으로 오른쪽 결과물을 만들어 보자.

만들어둔 레이어 두개를 array에 집어 넣고, 반복문으로 x축으로 이동하게 했다. 레이어를 만드는 것도 반복문의 index를 받아서 조건문을 통해 색깔과 y좌표를 다르게 지정하여 만들 수도 있지만 레이어 두개를 만드는데 굳이 조건문 까지는 쓰고 싶은 생각은 들지 않아서 그렇게 하지는 않았다. 이렇듯 코드는 상황에 따라 효과적인 방식이 있다. 물론 정답이라는게 아니라 본인이 작성하기에 효과적인 방식을 말하는 거다.

포토샵에서도 레이어에 색깔을 입히는 방법이 굉장히 다양하다는 것을 우리는 이미 알고 있다. shape자체에 컬러속성을 줄 수도 있고 레이어에 color overlay효과로 컬러를 줄 수도 있고 shape에 마스크를 만들어서 브러쉬로 색을 입혀줄 수도 있다. 하지만 우리는 그것을 그때 그때 상황에 맞게 효과적으로 사용한다.

코드에도 다양한 개념을 사용하는 것은 그런 맥락이다. 맨 처음 글에서 코드가 걸레짝이 되어도 된다고 말한 이유는 아직은 우리가 익힌 개념들을 효율적으로 쓰기 서툴기 때문에 종종 코드가 길어지게 되면 정말 개차반이 되기 때문이다.(정말 걸레…😢) 하지만 그렇게 비효율적으로 많이 작성해봐야 다음에 뭔가를 만들게 될 때 그런 사항을 미리 염두에 두고 시작할 수 있다.

사설이 좀 길어졌는데, 만들던 예에서 좀 더 구체적인 상황을 놓고 생각해보자.

만약 x축으로 이동하는 레이어가 많이 등장하고 그게 순차적이지 않은 형태로 나타난다고 했을때 반복문을 쓰기는 애매하고 특정 코드는 자주 반복되는 상황…

이럴때 구세주가 바로 ‘기능’(함수)이다. 그럼 우리는 위와 같은 특정 상황에서 이런 기능을 만들어 사용할 수 있다.

레이어를 x축으로 이동시키는 기능! 을 만들자.

그럼, 이 기능을 만들기에 앞서서 기본적인 기능을 정의하는 문법을 짚고 넘어가자.

우리가 변수를 만들때나 레이어를 만들때 그리고 array를 만들때를 생각해보면 우리는 항상 이름을 적고 뒤에 대입할 무언가를 적어주었다. 기능을 만들때도 마찬가지로 기능을 담을 변수를 만들고 이름을 붙이는 것으로 시작한다. 실제 우리가 의사소통하는 언어와 달리 컴퓨터 언어는 예외란게 없다.

->화살표 아래에 코드로 정의하는 것이 실질적인 기능이 정의되는 부분이다. parameter는 한자로 번역했을때 매개변수다. 매개변수라는 단어를 사전에서 검색해보니 또 계속 어렵게 설명 하길래… 가장 알아듣기 쉬운 뜻으로 골라봤다. 둘 사이에서 양편의 관계를 맺어주는 변수.

쉽게 예를 들자면 이런식이다. 우리에게 냄비가 있다고 가정했을때 냄비에 생라면을 넣어 끓이면 라면이 되고 된장찌개 재료를 넣어 끓이면 된장찌개가 된다. 요리 만드는 기능을 가진 냄비라고 했을때. 재료는 parameter가 된다.

cookingPot = (재료) ->
print 재료 + "를 지지고 볶는중"

위 코드를 실행해보자. 아마 아무것도 나타나지 않을거다. 기능을 정의를 했으면 호출을 해야한다. 기능을 호출하는 방법은 뒤에 정의한 기능이름 뒤에 ()괄호를 붙이는 것이다. 이 괄호가 바로 parameter를 전달하는 곳이다. 기능을 정의하고 호출한다고 했을때 양편의 관계를 맺어주는 변수! (오. 괄호는 전에도 한번 설명한 적이 있다.)

tip1. parameter는 경우에 따라 정의하지 않아도 된다. 대신 호출할때 빈 괄호()는 꼭 붙여줘야한다.

그럼 아래에 이렇게 호출해보자.

cookingPot("떡볶이")

결과를 확인해보자! 떡볶이를 지지고 볶는중이랜다… 이제 우리는 우리가 만든 cookingPot으로 모든 요리를 할 수 있다!!

cookingPot("까르보나라")
cookingPot("알리오올리오파스타")
cookingPot("함박스테이크")
cookingPot("한우 1등급 스테이크")

이건 무슨 아바타 여자친구같은 느낌이지만… 뭐 어쨋든 하나의 cookingPot으로 다양한 요리를 해봤다… (음…….. 유쾌한 예제는 아니구나 👀)

좀 더 추상적으로 접근할 수도 있다. 우리는 지지고 볶는 냄비 하나만 썼지만 모든 요리를 지지고 볶는건 좀 그러니까 다양한 재료와 도구를 이용할 수 있게 기능을 만들어 보자.

cooking = (도구, 재료) ->
print 재료 + "을(를)" + 도구 + "에 넣어 요리하는 중입니다."
cooking("오븐", "빵반죽")
cooking("튀김기", "냉동포테이토")
cooking("전자렌지", "백종원 도시락")

parameter는 위와 같이 콤마로 구분하여 여러개가 들어갈 수도 있다. 이제 다양한 도구를 활용해서 다양한 요리를 할 수 있게 되었다!

이제 대충 연습이 끝났다. 텍스트 따위 출력되는건 디자이너에게 동기부여가 되지 않아... 그럼 이제 레이어를 x축으로 이동시키는 기능을 만들어보자. 우리는 불특정 레이어를 x축으로 이동시켜야 하기 때문에 layer를 parameter로 정의해야 한다.

movingX = (layer) ->
layer.animate
properties:
x: 550

movingX라는 기능을 만들었다. parameter이름을 layer로 명명했기 때문에 기능정의에서 layer이름을 사용하여 animate시켜준다. 그리고 전에 만들어둔 layerA를 방금 막 만든 따끈따끈한 movingX기능으로 이동시켜보자. (layer의 animate()를 사용했기 때문에 호출할 때 레이어가 아닌 형태의 값을 넣게 되면 오류가 난다.)

movingX(layerA)

단순히 위 결과물을 얻기위해 기능을 만들었다기 보다는 기능을 하나 만들어 놓았기 때문에 앞으로 x축으로 이동시키고 싶을 때 두고두고 쓸 수 있게 되었다.

이 기능을 좀 더 효과적으로 만드려면 어떻게 해야할까. 이 기능을 오른쪽으로 550px만 이동하도록 되어있다. 하지만 상황에 따라 10px이 될 수도 있고 300px을 이동시켜야 할 상황이 있을 수도 있다. 그럼 그 값을 받게 하기 위해서 두번째 parameter를 추가해보자.

offset 이라는 parameter를 추가했다. 이제 좀 더 효과적인 기능이 되었다.

이렇게 기능을 만들어두면 다양한 상황에 효과적으로 사용할 수 있다. 예를들어 layerA는 그냥 바로 움직이게 하고 layerB는 클릭해야 움직이게 해보자.

이렇게 유용한 movingX라니…ㅠ.ㅠ 이제 자주쓰는 것들은 기능으로 만들어서 사용해보자. 훨씬 효율적인 코드가 될 수 있을 것이다.

그럼 마지막으로 framer의 onClick이벤트 문법의 비밀을 한번 파헤쳐 보자. 전에 클릭이벤트에 대해 작성할때는 framer 매직을 사용했지만, 이제 우리는 저 코드를 이해할 수 있는 지점에 와있다.

layerB.onClick (event) ->
블라블라

Framer는 레이어 속성에 onClick이벤트를 사용할 수 있게 만들어 두었다. 우리가 함수를 만들던 것과 비슷하게 말이다. 그래서 onClick에 대해 정의한 코드는 우리의 코드창에서 확인 할 수는 없지만 호출할 수는 있는 것이다. 이런 것들이 바로 Framer Docs에서 확인해봐야 할 것들이다. 우리가 만든 것이 아니기에 사용법을 확인하기 위해서 말이다.

그런데 왜 onClick과 (event)사이에 띄어쓰기가 있는 것일까… 원래 기능을 호출해서 사용할때는 functionName()이런식으로 붙여서 사용하는데…

이건 coffeeScript의 축약식 문법 때문이다. 전에 한 번 설명했지만 커피스크립트는 수많은 괄호들의 늪에서 해방시켜주었다. 띄어쓰기는 사실 괄호로 감싸진 코드가 바로 올때 괄호를 생략할 수 있게 한 것이다.

그래서 위 코드는 이렇게 써도 똑같이 동작한다.

layerB.onClick((event) -> movingX(this, 500))

layerB의 onClick기능을 호출하는데 여기서는 parameter가 하나의 값을 연결해주는게 아닌 또 다른 기능(함수)을 연결해준다! 클릭이 되면 어떤 기능을 할지는 내가 적어주어야 하는 것이다. 결과적으로 onClick기능이 하는 일은 클릭된 것을 감지하고 매개로 받은 기능을 실행시켜주는 일을 담당하고 있는거라고 보면 된다.

보통 기능을 정의할때 우리는 호출하기 위해 이름을 붙이지만 여기서는 한번 쓰여지고 마는 기능이기 때문에 이름이 없는 함수 형태로 쓰여지는 것이다.

그럼 onClick에서 우리가 정의할 기능에 붙은 event라는 parameter는 또 뭘까. 이건 클릭했을때 마우스가 클릭된 이벤트에 대한 정보를 parameter로 받는 것이다.

layerB.onClick (event) ->
movingX(this, 500)
print event.x
print event.y

이렇게 해서 레이어를 클릭해보면 마우스가 클릭된 좌표를 가져올 수 있다. 물론 이런것들은 또 framer Docs에서 단어 공부를 하다보면 보게 될 것 들이다.

여기까지 함수에 대해 설명했다. 눈치챈 사람이 없었으면 좋겠지만 어려운 설명을 피하기 위해 약간의 개발용어의 오용이 들어가 있다. 😉

아무튼, 조금은 반복적이더라도 최대한 어렵지 않게 하려고 노력했는데 어쩔수 없이 조금은 개념적인 허들이 있을거라 생각된다. 그럴땐 역시 해답은 엄청나게 비효율적으로 작성하고 개고생(?) 하다보면 어쩔 수 없이 이 개념을 받아 들이는 날이 오게 된다고 믿자. 이제부터는 수많은 삽질, 연습도 해보고 프레이머 홈페이지에 있는 예제들 코드도 많이 보고. 만들고 싶은게 있는데 할 줄 모르면 Docs도 보고 Google에도 물어보고 하다보면 어느새 코드가 친근하게 느껴질 것이다.

그럼 이만 디자이너를 위한 코드 with Framer시리즈의 마지막 글을 마치도록 한다. (물론 다른 주제로 코드, Framer에 대해 글을 쓸수는 있겠지만.)

부디 이번에는 코드의 벽을 허물어 보시기를!

--

--