famo.us 코드 분석글은 정확한 글이 아니라 공부하면서 정리한 글이라 정확하지 않고 개인적인 의견들이 난무합니다. 정리하는 용도이니 추후 정리가 완료되면 좀 더 정확한 내용을 올릴 예정이니 나중에 정리된 글을 보세요.


앞에선[링크] famo.us에서 Render Tree를 알아봤고 이번에는 Render Tree의 레이아웃을 어떻게 하는지 알아본다.

앞에서 봤듯이 DOM Tree가 아니라 자체 Render Tree을 가지고 있고 레이아웃도 일반적으로 CSS로 하는게 아니라 famo.us에서 제공하는 레이아웃 방법을 사용한다.

레이아웃하는 방법은 Transforms와 Modifiers을 사용하면 된다.


Transforms

Transforms는 이름에서 나오는 느낌처럼 이미지처럼 걍 CSS3을 Transform을 자바스크립트로 옮긴 객체라고 생각하면 된다.

Transforms은 정적인 객체로 쉽게 translate, scale..을 관리할 수 있다. 내부적으로 css의 matrix3d을 사용하기 때문에 4X4 matrix 형식으로 다루는데 16개의 원소가 있는 배열로 관리한다.

Transforms은 아래와 같은 메서드들을 가지고 있고 아래와 같이 반환한다.


다른 메서드들이야 다를건 없는데 inFront, behind는 css의 z-index처럼 노드의 상하를 조절할 때 사용한다. 내부적으론 translateZ을 걍 살짝 추가한다.

Transform는 그냥 사용되지 않고 Scene Graph(보이는 노드들)에 붙여 이동할 때 사용한다.

var surface = new Surface({
        size: [50, 50],
        properties: { background: 'red' }
    });

    var modifier = new Modifier({
        transform : Transform.translate(100, 100, 0)
    });

    context.add(modifier).add(surface);

그리고 아래와 같이 다수개의 Transform들을 합치거나 기존의 Transform에 추가하여 사용하곤 한다.



Modifiers

Transform은 사실 현재 상태를 나타내는 객체로 혼자서 움직이거나 하지 못한다. 위에서 본 예제처럼 Modifiers에 붙여 Scene Graph에 붙여 사용한다. 그리고 Modifiers는 기본적으로  사이즈나 크기등을 조절할 수 있다.

크기의 경우, 아래와 같이 Surface에 size을 undefined로 하고 Modifirer에 지정하면 undefined의 경우 Surface에 사용한다. 만약 Surface의 값이 다 가지고 있다면 Modifiers의 값을 사용하고 있지 않다. 그래서 크기가 유동적이라면 Surface에서 등록하지 않고 Modifiers에서 등록하면 될 것 같다.


  var sizeModifier = new Modifier({size: [200, 200]});

  var surface = new Surface({
    size: [undefined, 100],
    properties: { background : 'red' }
  });

  context.add(sizeModifier).add(surface);


정렬의 경우, 문서에는 Origin,Align의 방법이 있는데 실제 코드에는 origin밖에 없다.

문서가 좀 더딘듯. origin은 몇가지가 지원되며 아래와 같다.



잼있게도 DOM을 직접 움직인다면 margin으로 처리했을 수 있는데 모두 계산하여 translate로 이동한다.


레이아웃을 사용할 때는 Modifiers을 사용한다고 했는데 이게 두가지 방법이 있다.

하나는 StateModifier, 다른 하나는 Modifier이다.

StateModifier는 push-based라고 하고 Modifier는 pull-based라고 한다.

말은 어렵지만, StateModifier는 내부적으로 모든 Transitionable(Translate...)들이 있어 Modifier에 설정하여 넣으면(push) 된다.

var surface = new Surface({
    size: [70, 70],
    properties: { background: 'red' }
});

var stateModifier = new StateModifier({
    opacity: 1
});

context.add(stateModifier).add(surface);

// animate the opacity from 1 to 0 over 500ms using a linear easing curve
stateModifier.setOpacity(
    0,
    {curve: 'linear', duration : '500'},
    function() { console.log('animation finished!') }
);


Modifier는 내부적으로 Transitionable가 없는 빈 상태로 아래와 같이 Transitionable을 연결하여 Modifier에서 Transitionable의 값을 가져와서(pull) 적용할 수 있다.


var surface = new Surface({
    size: [70, 70],
    properties: { background: 'red' }
});

var modifier = new Modifier();

context.add(modifier).add(surface);

// the opacityGetter
var opacityState = new Transitionable(1);

modifier.opacityFrom(opacityState);

// animate the opacity from 1 to 0 over 500ms using a linear easing curve
opacityState.set({
    Transform.translate(100, 0, 0),
    {curve : 'linear', duration : 500},
    function(){ console.log('animation finished!'); }
});

 

이번에는 레이아웃하는 방법등을 알아봤다, 좀더 자세한 내용은 아래 링크를 참고하면 된다.


https://famo.us/guides/layout

Posted by 전용우
,