Lynx

Scale Feedback

Lynx에서 Main Thread 기반의 SEED Scale Feedback을 적용하는 방법을 알아봅니다.

Engine ≥ 3.6

SEED의 Scale Feedback은 누르는 동안 요소를 살짝 줄여 입력이 도달했음을 즉시 전달합니다. 고정된 배율을 쓰지 않고 렌더된 크기에서 배율을 계산하므로 작은 아이콘 버튼과 화면 폭을 채우는 요소가 비슷한 눌림 거리로 반응합니다.

@seed-design/lynx-react는 ScaleFeedback과 useScaleFeedback을 공개합니다. 하나의 영역을 줄일 때는 ScaleFeedback을, 터치 영역과 축소할 요소가 다를 때는 useScaleFeedback을 사용하세요.

Scale 계산 방식

렌더링된 폭과 높이를 기준으로 배율을 계산합니다. 아직 보이지 않아 크기가 0인 요소는 처음 누를 때 다시 측정합니다.

basis = max(height, width / 4, 24)
scale = (basis - 2) / basis

축소량, 폭 보정값, 최소 기준 길이의 의미는 Scale Foundation에서 확인할 수 있습니다.

ScaleFeedback으로 Self Scale 적용하기

하나의 시각 영역에 Self Scale을 적용할 때는 ScaleFeedback으로 감쌉니다.

import { ScaleFeedback } from "@seed-design/lynx-react";

function Pressable() {
  return (
    <ScaleFeedback>
      <view>
        <text>눌러 보세요</text>
      </view>
    </ScaleFeedback>
  );
}

ScaleFeedback은 animation target인 native view를 렌더링하며 flatten={false}를 적용합니다.

wrapper의 크기나 이벤트 전파가 원하는 터치 영역과 다르면 useScaleFeedback으로 trigger와 target을 직접 지정하세요.

useScaleFeedback으로 Self와 Content Scale 적용하기

훅은 터치를 받는 요소와 축소할 요소의 props를 나누어 반환합니다.

import { mergeProps, useScaleFeedback } from "@seed-design/lynx-react";

function Pressable() {
  const { scaleFeedbackTriggerProps, scaleFeedbackTargetProps } = useScaleFeedback();

  return (
    <view {...mergeProps(scaleFeedbackTriggerProps, scaleFeedbackTargetProps)}>
      <text>눌러 보세요</text>
    </view>
  );
}
Lynx 예제를 불러오는 중입니다.

scaleFeedbackTargetProps에는 flatten={false}가 포함됩니다. target에 객체를 그대로 전달하세요.

기존 이벤트와 ref 합성하기

같은 요소에 여러 props 객체를 전달할 때는 mergeProps()를 사용하세요. 같은 이름의 이벤트와 ref를 덮어쓰지 않고 합성합니다.

<view
  {...mergeProps(scaleFeedbackTriggerProps, scaleFeedbackTargetProps, userProps)}
  flatten={false}
/>

사용자 props는 마지막에 전달합니다. 같은 이름의 사용자 이벤트가 먼저 실행되고, 일반 값은 뒤의 값이 우선합니다. animation target의 flatten={false}는 유지하세요.

mergeProps()는 이벤트의 전파 방식이나 실행 스레드를 바꾸지 않습니다. Background callback은 useScaleFeedback 옵션으로 전달하세요.

브라우저 미리보기는 구조와 기본 상호작용을 확인하는 용도입니다. 실제 Scale Feedback 동작은 Lynx Explorer에서 확인하세요.

Self와 Content 선택하기

두 방식의 차이는 target 위치입니다.

방식TriggerTarget
Self액션 영역같은 액션 영역
Content바깥 액션 영역안쪽 콘텐츠

Self Scale은 두 props를 같은 요소에 전달합니다. Content Scale은 trigger props를 바깥 요소에, target props를 안쪽 콘텐츠에 전달합니다.

const { scaleFeedbackTriggerProps, scaleFeedbackTargetProps } = useScaleFeedback();

return (
  <view {...scaleFeedbackTriggerProps}>
    <view {...scaleFeedbackTargetProps}>{children}</view>
  </view>
);

Checkbox, Radio, Switch처럼 넓은 영역이 터치를 받고 일부 요소만 줄어드는 경우에도 Content Scale을 사용합니다.

Main Thread와 Background Thread

Main Thread는 레이아웃 측정, 터치 처리, animation 실행을 담당합니다. Background Thread callback에는 비즈니스 로직을 둡니다.

Main Thread 함수 안에서는 React state, 네트워크 요청, NativeModule을 사용하지 마세요.

애니메이션과 Rootage 값

Scale은 Element.animate()로 실행하므로 target에 선언된 색상 transition을 덮어쓰지 않습니다.

값Rootage source현재 값
Duration$duration.pressed-scale150ms
Easing$timing-function.pressed-scalecubic-bezier(0, 0, 0.15, 1)

터치를 끝내거나 취소하면 현재 지점에서 scale(1)로 돌아갑니다.

동작 줄이기

useScaleFeedback은 GlobalProps.motion을 따릅니다.

motion동작
"reduced"배율을 1로 유지
그 외Scale Feedback 적용

누르는 도중 "reduced"로 바뀌거나 컴포넌트가 비활성화되면 scale(1)로 돌아갑니다.

disabled, loading, 중첩 target

  • disabled: true이면 축소하지 않습니다. Loading 상태에도 같은 값을 전달하세요.
  • 이미 축소되는 상위 요소 안에는 Scale Feedback을 중복 적용하지 않습니다.
  • 훅이 target의 transform을 사용합니다. 기존 transform을 유지하려면 전용 콘텐츠 layer를 target으로 두세요.

React와의 차이

  • React는 CSS :active와 변수를 사용하고, Lynx는 Element.animate()를 사용합니다.
  • Lynx는 일부 컴포넌트의 안쪽 콘텐츠만 축소하므로 웹과 눌림 표현이 다를 수 있습니다.
  • React의 ScaleFeedback은 wrapper를 만들지 않지만 Lynx는 native view wrapper를 렌더링합니다.
  • 직접 만든 Scale Feedback의 중첩 축소를 끄는 API는 없습니다.
  • 프로젝트 전체에서 끄려면 GlobalProps.motion을 "reduced"로 지정합니다.

API

ScaleFeedback

Prop

Type

useScaleFeedback

Prop

Type

Prop

Type

참고 자료

Last updated on

목차