본문으로 건너뛰기

PlAnimateReveal

움직이는 가장자리 뒤로 내용이 드러납니다. 아무것도 움직이지 않고 어떤 색도 바뀌지 않는 유일한 등장이라, 이미 그려진 픽셀은 전부 최종 위치에 있습니다.

React
tsx
import { PlAnimateReveal } from 'plass-ui';

<PlAnimateReveal render={<h2 />}>Everything is where it was.</PlAnimateReveal>;

<PlAnimateReveal from="top" trigger="visible" duration={700}>
  <PlDivider />
</PlAnimateReveal>;
dart
import 'package:plass_ui/plass_ui.dart';

const PlAnimateReveal(child: PlTypography('Everything is where it was.', level: PlTypographyLevel.h3));

const PlAnimateReveal(
  from: PlassSide.top,
  trigger: PlassAnimateTrigger.visible,
  duration: Duration(milliseconds: 700),
  child: PlDivider(),
);

Props

Prop타입기본값설명
mode'in' | 'out''in'드러나는지 다시 덮이는지. out은 같은 와이프를 거꾸로 돌린 것이라, 열린 쪽으로 닫힙니다
from공통'top' | 'right' | 'bottom' | 'left''left'와이프가 시작하는 모서리. 라이브러리 전체가 그렇듯 물리적입니다 — 위에서 걷히는 제목은 어떤 쓰기 방향에서도 위에서 걷힙니다
fadebooleanfalse와이프 뒤에서 함께 나타납니다. 다른 모든 효과와 반대로 기본이 꺼짐입니다 — reveal은 fade가 아니라는 것이 이 효과의 전부이기 때문입니다
duration공통number520한 번 도는 데 걸리는 시간(ms). CSS 문자열이 아니라 숫자입니다
delay공통number0시작하기까지 기다리는 시간(ms)
easing공통stringthe house curveCSS가 쓰는 그대로의 이징 곡선
repeat공통number | 'infinite'1몇 번 반복할지. 끝없이 돌리려면 Infinity가 아니라 'infinite' — CSS에 그 단어로 그대로 쓰이기 때문입니다
alternate공통booleanfalse한 번 걸러 거꾸로 돌립니다. 반복이 처음으로 튀어 돌아가는 대신 되돌아옵니다
paused공통booleanfalse있는 자리에 멈춰 세웁니다
trigger공통'mount' | 'visible' | 'hover' | 'manual''mount'무엇이 시작시키는지. mount는 화면에 올라오자마자, visible은 스크롤되어 보일 때, hover는 포인터나 focus가 닿을 때, manual은 play가 시킬 때만
play공통booleantrigger가 manual일 때 실행합니다. false → true가 될 때마다 처음부터 다시 돕니다
once공통booleantruetrigger="visible"에서 처음 한 번만 돌릴지. 끄면 화면에 다시 들어올 때마다 다시 돕니다
threshold공통number0.2trigger="visible"에서 얼마나 보여야 보이는 것으로 칠지, 0에서 1 사이
timeline공통'auto' | 'view''auto'무엇이 애니메이션을 진행시키는지 — 시계인지 독자의 스크롤 위치인지. view는 duration, delay, repeat, trigger를 무시하고 range로 달립니다
range공통string'entry 0% cover 45%'CSS가 animation-range를 쓰는 그대로. timeline이 view일 때만 읽힙니다
stagger공통number0자식마다 delay에 더해지는 시간(ms). 0이면 상자 자체가 재생되고, 그 외에는 효과가 자식들로 옮겨 가면서 상자에서는 빠집니다
durationStep공통number0자식마다 duration에 더해지는 시간(ms). 음수도 되고, 0 아래로는 내려가지 않습니다
reverse공통booleanfalse마지막 자식부터 첫 자식까지 순서를 뒤집습니다. 순서만 뒤집히고 각 자식은 그대로 앞으로 재생됩니다
renderReactElement | (props, state) => ReactElement<div> 대신 다른 요소로 렌더링합니다
Prop타입기본값설명
modePlassAnimateModePlassAnimateMode.enter드러나는지 다시 덮이는지. exit는 같은 와이프를 거꾸로 돌린 것이라, 열린 쪽으로 닫힙니다. in이 Dart의 예약어라 enter/exit입니다
from공통PlassSidePlassSide.left와이프가 시작하는 모서리. 라이브러리 전체가 그렇듯 물리적입니다 — 위에서 걷히는 제목은 어떤 쓰기 방향에서도 위에서 걷힙니다
fadeboolfalse와이프 뒤에서 함께 나타납니다. 다른 모든 효과와 반대로 기본이 꺼짐입니다 — reveal은 fade가 아니라는 것이 이 효과의 전부이기 때문입니다
duration공통DurationDuration(milliseconds: 520)한 번 도는 데 걸리는 시간(ms). CSS 문자열이 아니라 숫자입니다
delay공통DurationDuration.zero시작하기까지 기다리는 시간(ms)
curve공통Curve?the house curveCSS가 쓰는 그대로의 이징 곡선
repeat공통int?1몇 번 반복할지. null이 멈추지 않음을 뜻합니다 — 적을 'infinite'가 없고, -1은 찾아봐야 하는 sentinel입니다
alternate공통boolfalse한 번 걸러 거꾸로 돌립니다. 반복이 처음으로 튀어 돌아가는 대신 되돌아옵니다
paused공통boolfalse있는 자리에 멈춰 세웁니다
trigger공통PlassAnimateTriggerPlassAnimateTrigger.mount무엇이 시작시키는지. mount는 화면에 올라오자마자, visible은 스크롤되어 보일 때, hover는 포인터나 focus가 닿을 때, manual은 play가 시킬 때만
play공통boolfalsetrigger가 manual일 때 실행합니다. false → true가 될 때마다 처음부터 다시 돕니다
once공통booltruetrigger="visible"에서 처음 한 번만 돌릴지. 끄면 화면에 다시 들어올 때마다 다시 돕니다
threshold공통double0.2trigger="visible"에서 얼마나 보여야 보이는 것으로 칠지, 0에서 1 사이
child * Widget무엇이 드러나는지

네이티브 <div> 속성은 그대로 통과하고, render로 요소 자체를 바꿀 수 있습니다. 이 세트에서 render가 가장 자주 필요한 것이 이 컴포넌트입니다. reveal은 보통 이미 제 요소가 붙은 제목이나 구분선을 감싸기 때문입니다.

클립은 그리는 시점에 적용되므로 widget은 자기 크기 그대로 한 번 배치되고, 옆에 있는 것들은 다시 배치되지 않습니다. widthFactor를 준 Align과의 차이가 이것입니다. 그쪽은 상자 크기를 바꾸어 이웃들을 밀어냅니다.

from은 라이브러리 전체가 그렇듯 물리적입니다. top, right, bottom, left. 위에서 걷히는 제목은 어떤 쓰기 방향에서도 위에서 걷힙니다.

공유되는 열 가지 설정(duration, delay, easing, repeat, alternate, paused, trigger, play, once, threshold)은 모든 PlAnimate* 컴포넌트에서 같습니다. trigger의 네 값은 PlAnimateFade 페이지에 있습니다. timeline="view"range도 같은 자리에 있고, 효과를 시계가 아니라 독자의 스크롤 위치에 맡깁니다.

세 가지가 더 있고, 이들은 효과를 상자에서 떼어 안의 것들로 옮깁니다. stagger는 각 자식을 자기 위치만큼 뒤로 미루고, durationStep은 자식마다 앞의 것보다 길거나 짧은 재생 시간을 주며, reverse는 집합의 끝에서부터 시작합니다. 키프레임 하나짜리 효과 여섯 개 모두에 있고, PlAnimateFade 페이지에 설명이 있습니다.

등장 고르기

세트에는 도착하는 방법이 다섯 가지 더 있고, 그 하나하나가 도착하면서 요소의 무언가를 바꿉니다. 이것은 요소가 얼마나 그려졌는지를 바꾸고 그 외에는 아무것도 바꾸지 않습니다.

  • PlAnimateFade는 잉크를 바꿉니다. 어떤 크기의 글 덩어리에도 안전하고 가장 먼저 손이 가야 하는 것이지만, 흐려졌다 나타난 제목은 독자가 두 번 읽어야 하는 제목입니다.
  • PlAnimateSlide는 위치를 바꿉니다. "이건 어디선가 도착했다"고 말하는데, 두 섹션 사이에 처음부터 있어야 했던 구분선에 대해서는 거짓말입니다.
  • PlAnimateGrowPlAnimateZoom은 크기를 바꾸므로, 안의 글자가 매 프레임 리샘플링됩니다.
  • PlAnimateReveal은 둘 다 바꾸지 않습니다. 위치 자체가 정보인 곳에 쓰세요. 자기가 속한 문단 위의 제목, 두 섹션 사이의 구분선, 차트의 플롯 영역, 엉뚱한 자리에서 읽히면 안 되는 숫자 열.

배치 비용도 다섯 중 가장 쌉니다. 배치할 것이 없기 때문입니다. 래퍼도, overflow 상자도, 흐름에 들어가는 두 번째 요소도 없습니다. 클립은 요소를 덜 그릴 뿐이고, 주변 페이지는 무슨 일이 있었는지 끝내 알지 못합니다.

Examples

from

네 모서리이고, mode="out"은 열린 쪽으로 닫힙니다.

React

fade

기본이 꺼짐이고, 이는 이 prop을 제공하는 다른 모든 효과와 반대입니다. 켜는 것은 등장을 한 번에 둘 요구하는 일이고, 이 효과를 고른 이유는 보통 그 첫 번째가 문제였기 때문입니다.

Accessibility

  • prefers-reduced-motion에서는 애니메이션이 통째로 걷히고 내용이 그냥 거기 있습니다. 클립도 함께 걷히므로 반쯤 그려진 채 남는 것은 없습니다.
  • 도는 동안 아무것도 리플로우되지 않고 아무것도 리샘플링되지 않습니다. fade만큼 글 덩어리에 안전하고, 크기를 바꾸는 어떤 것보다 안전합니다.
  • 잘려 있는 부분도 문서 안에 있고 그대로 읽힙니다. 이것은 등장이지 숨기는 방법이 아닙니다. 없어야 한다면 unmount하세요.
  • 같은 요소에 caller가 것은 clip-path는 효과가 도는 동안 덮어써집니다. 둘 중 하나는 래퍼에 두세요.
  • 플랫폼에서 애니메이션이 꺼져 있으면(MediaQuery.disableAnimations) 효과가 통째로 걷히고 내용이 그냥 거기 있습니다.
  • 도는 동안 아무것도 다시 배치되지 않습니다. 클립은 그리는 시점에 일어나므로 widget도 그 옆의 것도 크기가 바뀌지 않습니다.
  • 잘려 있는 부분도 트리 안에 있고 semantics에도 있습니다. 이것은 등장이지 숨기는 방법이 아닙니다.

React 빌드와 다른 점

ReactFlutter
clip-path: inset()clipper를 준 ClipRect같은 사각형을 각 플랫폼이 부르는 이름으로 부른 것입니다.
mode="in" | "out"PlassAnimateMode.enter / .exitin은 Dart의 예약어입니다.
renderFlutter에는 요소를 바꿔 끼울 자리가 없습니다.
duration, delay가 밀리초Duration프레임워크에 이미 그 타입이 있습니다.
easing이 CSS 문자열curve, Curve같은 것을 Dart가 부르는 이름입니다.
repeat: number | 'infinite'int?, null이면 멈추지 않음여기에는 쓸 'infinite'가 없고, -1은 찾아봐야 아는 표식이 됩니다.
IntersectionObserver를 쓰는 trigger="visible"가장 가까운 Scrollable을 지켜봄여기에는 observer가 없습니다. 위에 scrollable이 없으면 지켜볼 것이 없으므로 그냥 돕니다.
prefers-reduced-motionMediaQuery.disableAnimations플랫폼 자신의 신호입니다.
stagger, durationStep, reverseReact 빌드는 효과를 자식들 자신에게 써 넣으므로 호출자의 레이아웃은 그대로입니다. Flutter에는 집합을 배치할 스타일시트가 없어서, 차등을 준 효과는 행이나 열까지 자기가 가져야 합니다. 그것이 바로 PlAnimateAppear이고, 그것을 여섯 개 더 만드는 일이 됩니다.
timeline="view"animation-timeline은 여기에 대응물이 없는 CSS 속성입니다. Flutter에서 스크롤 연동 효과는 ScrollPosition으로 구동하는 AnimationController이고, 위젯이 prop으로 받는 것이 아니라 애플리케이션 자신의 배선입니다.
className, style통과시킬 class 목록도 style 속성도 없습니다.

Released under the MIT License