PlAnimateLighting
무언가의 바깥을 도는 빛입니다. 무엇을 움직여서가 아니라 빛으로 시선을 끕니다. 이 라이브러리가 "여기"라고 말하면서 "그리고 움직였다"고 말하지 않는 유일한 방법입니다.
import { PlAnimateLighting } from 'plass-ui';
<PlAnimateLighting size="lg" color="primary">
<PlCard size="lg" title="Recommended">
…
</PlCard>
</PlAnimateLighting>;import 'package:plass_ui/plass_ui.dart';
const PlAnimateLighting(
size: PlassSize.lg,
child: PlCard(size: PlassSize.lg, title: Text('Recommended'), child: Text('…')),
);Props
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| color공통 | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'primary' | 빛이 그려지는 계열. 호는 지나가면서 그 계열의 두 끝 사이를 돕니다 — solid 채움과 같은 규칙입니다 |
| glow | string | — | 의미론적 계열이 원하는 바가 아닐 때의 CSS 색. color를 덮어쓰고, 그러면 호는 도는 것을 멈춥니다 — 색 하나는 돌아갈 곳이 없습니다 |
| size공통 | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | 빛이 따라가는 radius. 안에 있는 것과 맞아야 합니다. 아니면 내용이 이미 둥글게 깎아 낸 모서리를 빛이 잘라 냅니다 |
| spread | number | 3 | 빛이 내용 바깥으로 뻗는 거리(px) |
| arc | number | 50 | 윤곽선 중 한 번에 밝아지는 각도. 작으면 달리는 불꽃, 크면 훑고 지나가는 빛입니다 |
| blur | number | 5 | 빛의 부드러움(px). 0이면 가장자리가 딱 떨어지는 쐐기라 빛이 아니라 도형으로 읽힙니다 |
| reverse | boolean | false | 빛을 반대 방향으로 돌립니다 |
| duration공통 | number | 3000 | 한 번 도는 데 걸리는 시간(ms). CSS 문자열이 아니라 숫자입니다 |
| delay공통 | number | 0 | 시작하기까지 기다리는 시간(ms) |
| easing공통 | string | the house curve | CSS가 쓰는 그대로의 이징 곡선 |
| repeat공통 | number | 'infinite' | 'infinite' | 몇 번 반복할지. 끝없이 돌리려면 Infinity가 아니라 'infinite' — CSS에 그 단어로 그대로 쓰이기 때문입니다 |
| alternate공통 | boolean | false | 한 번 걸러 거꾸로 돌립니다. 반복이 처음으로 튀어 돌아가는 대신 되돌아옵니다 |
| paused공통 | boolean | false | 있는 자리에 멈춰 세웁니다 |
| trigger공통 | 'mount' | 'visible' | 'hover' | 'manual' | 'mount' | 무엇이 시작시키는지. mount는 화면에 올라오자마자, visible은 스크롤되어 보일 때, hover는 포인터나 focus가 닿을 때, manual은 play가 시킬 때만 |
| play공통 | boolean | — | trigger가 manual일 때 실행합니다. false → true가 될 때마다 처음부터 다시 돕니다 |
| once공통 | boolean | true | trigger="visible"에서 처음 한 번만 돌릴지. 끄면 화면에 다시 들어올 때마다 다시 돕니다 |
| threshold공통 | number | 0.2 | trigger="visible"에서 얼마나 보여야 보이는 것으로 칠지, 0에서 1 사이 |
| render | ReactElement | (props, state) => ReactElement | — | <div> 대신 다른 요소로 렌더링합니다 |
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| color공통 | PlassColor | PlassColor.primary | 빛이 그려지는 계열. 호는 지나가면서 그 계열의 두 끝 사이를 돕니다 — solid 채움과 같은 규칙입니다 |
| glow | Color? | — | 의미론적 계열이 원하는 바가 아닐 때의 CSS 색. color를 덮어쓰고, 그러면 호는 도는 것을 멈춥니다 — 색 하나는 돌아갈 곳이 없습니다 |
| size공통 | PlassSize | PlassSize.md | 빛이 따라가는 radius. 안에 있는 것과 맞아야 합니다. 아니면 내용이 이미 둥글게 깎아 낸 모서리를 빛이 잘라 냅니다 |
| spread | double | 3 | 빛이 내용 바깥으로 뻗는 거리(px) |
| arc | double | 50 | 윤곽선 중 한 번에 밝아지는 각도. 작으면 달리는 불꽃, 크면 훑고 지나가는 빛입니다 |
| blur | double | 5 | 빛의 부드러움(px). 0이면 가장자리가 딱 떨어지는 쐐기라 빛이 아니라 도형으로 읽힙니다 |
| reverse | bool | false | 빛을 반대 방향으로 돌립니다 |
| duration공통 | Duration | Duration(milliseconds: 3000) | 한 번 도는 데 걸리는 시간(ms). CSS 문자열이 아니라 숫자입니다 |
| delay공통 | Duration | Duration.zero | 시작하기까지 기다리는 시간(ms) |
| curve공통 | Curve? | the house curve | CSS가 쓰는 그대로의 이징 곡선 |
| repeat공통 | int? | null | 몇 번 반복할지. null이 멈추지 않음을 뜻합니다 — 적을 'infinite'가 없고, -1은 찾아봐야 하는 sentinel입니다 |
| alternate공통 | bool | false | 한 번 걸러 거꾸로 돌립니다. 반복이 처음으로 튀어 돌아가는 대신 되돌아옵니다 |
| paused공통 | bool | false | 있는 자리에 멈춰 세웁니다 |
| trigger공통 | PlassAnimateTrigger | PlassAnimateTrigger.mount | 무엇이 시작시키는지. mount는 화면에 올라오자마자, visible은 스크롤되어 보일 때, hover는 포인터나 focus가 닿을 때, manual은 play가 시킬 때만 |
| play공통 | bool | false | trigger가 manual일 때 실행합니다. false → true가 될 때마다 처음부터 다시 돕니다 |
| once공통 | bool | true | trigger="visible"에서 처음 한 번만 돌릴지. 끄면 화면에 다시 들어올 때마다 다시 돕니다 |
| threshold공통 | double | 0.2 | trigger="visible"에서 얼마나 보여야 보이는 것으로 칠지, 0에서 1 사이 |
| child * | Widget | — | 무엇이 빛나는지 |
네이티브 <div> 속성은 그대로 통과합니다. color는 여기서 Plass prop이라 통과에서 제외되고, render로 요소 자체를 바꿀 수 있습니다.
glow는 CSS 색 문자열이 아니라 Color?입니다. spread와 blur는 논리 픽셀 단위의 double이고, arc는 도 단위입니다.
size는 안에 있는 것의 radius와 맞아야 합니다. 빛은 wrapper 자신의 모서리를 따라가므로, xs Lighting 안의 lg 카드는 카드가 이미 둥글게 깎아 낸 네 모서리에서 빛이 삐져나옵니다.
빛은 내용 위가 아니라 뒤에, 자기만의 stacking context 안에 있습니다. 그래서 안에 있는 것은 바뀌지도 덮이지도 않고, 내용은 그대로 읽힙니다.
공유되는 열 가지 설정 — duration, delay, easing, repeat, alternate, paused, trigger, play, once, threshold — 은 모든 PlAnimate* 컴포넌트에서 같습니다. 다만 repeat의 기본값이 여기서는 'infinite'입니다.
Examples
color
호는 지나가면서 계열의 두 끝 사이를 돕니다. 라이브러리의 모든 채워진 표면이 따르는 규칙 그대로입니다. 평평한 색의 호는 페인트일 텐데, 여기에 페인트는 없습니다. 의미론적 계열이 원하는 바가 아니라면 glow가 CSS 색 하나를 받고, 그때는 호가 돌아갈 곳이 없습니다.
arc, blur and spread
윤곽선 중 한 번에 얼마나 밝아지는지, 빛이 얼마나 부드러운지, 내용 바깥으로 얼마나 뻗는지입니다. 작은 호는 모서리를 달리는 불꽃이고, 큰 호는 훑고 지나가는 빛입니다. blur={0}에서는 빛이기를 그만두고 도형이 됩니다.
Accessibility
prefers-reduced-motion에서는 호가 도는 것을 멈추고 고른 빛이 됩니다. 장식은 남고 움직임은 사라집니다.- 빛은 스크린리더에게 아무 말도 하지 않고, 그럴 필요도 없습니다. 그것이 표시하고 있는 것 — 처리 중인 행, 추천되는 요금제 — 은 내용에도 적혀 있어야 합니다.
- 화면에 하나만. 세 개가 빛나는 페이지에는 지금 눈길을 끄는 하나가 없습니다.
- 플랫폼에서 애니메이션이 꺼져 있으면(
MediaQuery.disableAnimations) 호가 도는 것을 멈추고 고른 빛이 됩니다. 장식은 남고 움직임은 사라집니다. - 빛은 스크린리더에게 아무 말도 하지 않고, 그럴 필요도 없습니다. 그것이 표시하고 있는 것은 내용에도 적혀 있어야 합니다.
- 화면에 하나만. 세 개가 빛나는 화면에는 지금 눈길을 끄는 하나가 없습니다.
React 빌드와 다른 점
| React | Flutter | 이유 |
|---|---|---|
glow가 CSS 색 문자열 | Color? | 프레임워크에 이미 타입이 있습니다. |
::before 위의 conic gradient | 자식 뒤 Positioned 레이어 위의 SweepGradient | 가상 요소가 없습니다. 레이어는 clipBehavior: Clip.none인 Stack의 첫 자식이라, 빛이 내용 바깥까지 닿으면서도 그 아래에 있습니다. |
각도를 애니메이션하려는 @property | sweep 위의 GradientRotation | 움직이는 것은 레이어가 아니라 그러데이션 자신의 회전입니다. 레이어를 돌리면 4분의 1 회전마다 모서리가 내용 밖으로 튀어나오고, CSS가 요소 대신 각도를 애니메이션하는 이유도 같습니다. |
filter: blur() | ImageFiltered | 같은 필터에 대한 프레임워크 자신의 이름입니다. |
render | — | Flutter에는 다형적 요소가 없습니다. |
duration, delay가 밀리초 | Duration | 프레임워크에 이미 타입이 있습니다. |
easing이 CSS 문자열 | curve, Curve | 같은 것에 대한 Dart 자신의 이름입니다. |
repeat: number | 'infinite' | int?, null이 멈추지 않음 | 적을 'infinite'가 없고, -1은 caller가 찾아봐야 하는 sentinel입니다. |
trigger="visible"이 IntersectionObserver | 가장 가까운 Scrollable을 봅니다 | 여기에는 observer가 없습니다. 위에 scrollable이 없으면 볼 것이 없으므로 그냥 돕니다. |
prefers-reduced-motion | MediaQuery.disableAnimations | 플랫폼 자신의 신호입니다. |
className, style | — | 통과시킬 class 목록도 style 속성도 없습니다. |