> 웹 프론트엔드 > CSS 튜토리얼 > XSTATE와 Svelte 애니메이션을 조정합니다

XSTATE와 Svelte 애니메이션을 조정합니다

Lisa Kudrow
풀어 주다: 2025-03-25 09:35:14
원래의
317명이 탐색했습니다.

XSTATE와 Svelte 애니메이션을 조정합니다

이 게시물은 Svelte 프로젝트에서 사용될 수 있으므로 Xstate에 대한 소개입니다. Xstate는 JavaScript 생태계에서 독특합니다. DOM을 응용 프로그램 상태와 동기화하지는 않지만 FSM (Finite State Machine)으로 모델링하여 응용 프로그램의 상태를 관리하는 데 도움이됩니다.

주 머신과 공식 언어에 대한 깊은 다이빙은이 게시물의 범위를 벗어나지 만 Jon Bellah는 다른 CSS 트릭 기사에서 그렇게합니다. 지금은 FSM을 흐름도로 생각하십시오. 흐름도에는 기포로 표시되는 여러 상태가 있으며 한 상태에서 다음 상태로 이어지는 화살표가있어 한 상태에서 다음 상태로의 전환을 나타냅니다. 주 머신은 주에서 나오는 화살이 하나 이상이거나 최종 상태 인 경우 전혀 아무도 없을 수 있으며, 화살표가 상태를 떠나 같은 상태로 돌아갈 수도 있습니다.

모든 것이 압도적으로 들리면 긴장을 풀면 모든 세부 사항에 대해 활기차고 느리고 느리게 진행됩니다. 현재로서는 응용 프로그램을 상태 머신으로 모델링 할 때 응용 프로그램이 다른 "상태"를 생성 할 것입니다. 응용 프로그램이있을 수 있습니다 (GET… State Machine… 상태?). Xstate는 국가를“상태”와 국가 간의 화살표를“행동”이라고 부릅니다.

우리의 예

Xstate는 학습 곡선을 가지고있어 가르치기가 어려워집니다. 사용 사례가 너무 고조되면 불필요하게 복잡해 보일 것입니다. Xstate가 빛나는 응용 프로그램의 코드가 약간 얽힌 경우에만 가능합니다. 이것은 그것에 대한 글을 까다 롭게 만듭니다. 그렇다고 말하면, 우리가 살펴볼 예제는 자동 완성 위젯 (때로는 AutoSuggest라고 함) 또는 클릭 할 때 선택할 항목 목록을 공개하는 입력 상자입니다. 입력을 입력 할 때 필터링 할 수 있습니다.

이 게시물에서는 애니메이션 코드를 정리하는 방법을 살펴 보겠습니다. 시작점은 다음과 같습니다.

이 게시물에 대해 불필요한 조각이 제거되지만 Svelte-Helpers 라이브러리의 실제 코드입니다. 입력을 클릭하고 항목을 필터링 할 수는 있지만 항목, 호버 등을 통해 "화살표 다운"을 선택할 수 없습니다.이 게시물과 관련이없는 모든 코드를 제거했습니다.

우리는 항목 목록의 애니메이션을 살펴볼 것입니다. 입력을 클릭하고 결과 목록이 먼저 렌더링되면 애니메이션을 다운합니다. 입력하고 필터링하면 목록 크기의 변경이 더 크고 더 작습니다. 입력이 초점을 잃거나 ESC를 클릭하면 목록의 높이를 0으로 애니메이션하고 페이딩 한 다음 DOM (이전이 아닌)에서 제거합니다. 더 흥미롭고 (그리고 사용자에게 좋은) 물건을 만들기 위해, 우리가 마감에 사용하는 것과 다른 스프링 구성을 사용하여 목록이 조금 더 빨리 닫히거나 뻣뻣 해지므로 불필요한 UX가 화면에 너무 오래 머지 않아도됩니다.

왜 내가 DOM의 안팎으로 애니메이션을 관리하기 위해 Svelte 전환을 사용하지 않는지 궁금하다면, 사용자가 열릴 때 목록의 크기를 애니메이션하고, 사용자가 필터링 될 때, 전환 사이에 조정하는 것이 단순히 스프링 업데이트가 돔에서 요소를 제거하기 전에 0을 끝내기 위해서는 단순히 더 어렵 기 때문입니다. 예를 들어, 사용자가 애니메이션을 사용하는 것처럼 목록을 빠르게 입력하고 필터링하면 어떻게됩니까? 우리가 볼 수 있듯이 Xstate는 이와 같이 까다로운 상태 전환을 쉽게 만듭니다.

문제를 범죄합니다

지금까지 예제의 코드를 살펴 보겠습니다. 목록이 열릴 때 제어 할 수있는 개방형 변수가 있으며 DOM에 있는지 여부를 제어 할 수있는 결과 목록 방문 가능한 속성이 있습니다. 또한 목록이 마감중인 과정에 있는지 여부를 제어하는 ​​폐쇄 변수도 있습니다.

28 행에는 입력이 클릭되거나 집중 될 때 실행되는 입력 메소드가 있습니다. 지금은 그것이 열려 있고 결과를 true로 설정할 수 있다는 점에 유의하십시오. 입력은 사용자가 입력을 입력 할 때 호출되고 True로 설정됩니다. 이는 입력이 집중 될 때 사용자가 클릭하여 탈출하여 닫히고 타이핑을 시작하여 다시 열 수 있습니다. 물론, 입력 블러 기능은 예상 할 때 실행되며 true로 닫히고 거짓으로 열립니다.

이 엉망진창을 골라서 애니메이션이 어떻게 작동하는지 살펴 보겠습니다. 상단의 SlideInspring과 불투명도에 주목하십시오. 전자는 목록을 위아래로 미끄러 뜨리고 사용자 유형으로 크기를 조정합니다. 후자는 숨겨져있을 때 목록을 사라집니다. 우리는 주로 SlideInspring에 중점을 둘 것입니다.

SetSpringDimensions라는 함수의 괴물을 살펴보십시오. 이것은 슬라이드 스프링을 업데이트합니다. 중요한 작품에 초점을 맞추면서 우리는 몇 가지 부울 속성을 취합니다. 목록이 열리면 오프닝 스프링 구성을 설정하고 {hard : true} 구성을 통해 목록의 너비를 즉시 설정 한 다음 높이를 설정합니다. 우리가 닫히면, 우리는 0으로 애니메이션을하고, 애니메이션이 완료되면 결과적으로 resultStiversible을 false로 설정합니다 (마감 애니메이션이 중단되면 Svelte는 약속을 해결 하지 못할 정도로 콜백이 실행되지 않을 것입니다). 마지막으로,이 방법은 사용자가 필터링하는 결과 목록의 크기가 변경 될 때마다라고도합니다. 우리는 이것을 관리하기 위해 다른 곳에서 크기 조정기를 설정했습니다.

스파게티

이 코드를 재고를 봅시다.

  • 목록이 열려있는 경우 추적하는 개방형 변수가 있습니다.
  • 목록이 DOM에 있어야하는 경우 추적하는 resultsListVisible 변수가 있습니다 (닫기 애니메이션이 완료된 후에는 False로 설정).
  • 목록이 닫는 과정에있는 경우 추적하는 닫는 변수가 있으며, 입력 초점/클릭 핸들러에서 확인하여 사용자가 위젯이 완료되기 전에 신속하게 다시 참여하면 마감 애니메이션을 뒤집을 수 있습니다.
  • 우리는 또한 우리가 네 가지 다른 곳에서 부르는 세트 스프링 분류를 가지고 있습니다. 목록이 열리거나 닫히거나 열린 동안 크기 조정하는지에 따라 스프링을 설정합니다 (즉, 사용자가 목록을 필터링하는 경우).
  • 마지막으로, 우리는 결과가 DOM 요소 렌더링을 나열 할 때 실행되는 결과를 Listrendered svelte 동작을 가지고 있습니다. 그것은 우리의 resizeobserver를 시작하고 DOM 노드가 마운트를 마치면 false로 닫는 것을 설정합니다.

버그를 잡았습니까? ESC 버튼을 누르면 False로만 열려 있습니다. True로 폐쇄를 설정하고 SetSpringDimensions를 호출하는 것을 잊었습니다 (False, True). 이 버그는이 블로그 게시물에 의도적으로 고안되지 않았습니다! 그것은이 위젯의 ​​애니메이션을 점검 할 때 저지른 실제 실수입니다. Escape 버튼이 잡히는 위치로 입력 된 코드를 복사하거나 새 기능으로 이동하여 두 곳에서 호출 할 수 있습니다. 이 버그는 근본적으로 해결하기 어렵지 않지만 코드의인지 부하가 ​​증가합니다.

우리가 추적하는 많은 것들이 있지만, 최악의 경우이 상태는 모듈 전체에 흩어져 있습니다. 위에서 설명한 상태를 가져 와서 Codesandbox의 Finds Feature를 사용하여 해당 상태가 사용되는 모든 장소를보십시오. 파일을 가로 질러 커서가 튀는 것을 볼 수 있습니다. 이제이 코드를 처음 사용하여 이해하려고 노력한다고 상상해보십시오. 이 모든 상태 조각의 성장하는 정신 모델을 추적 해야하는 정신 모델을 추적해야하며, 존재하는 모든 장소를 기반으로 어떻게 작동하는지 알아냅니다. 우리는 모두 거기에있었습니다. 짜증나. Xstate는 더 나은 방법을 제공합니다. 어떻게 보자.

Xstate 소개

조금 뒤로 물러 봅시다. 사용자가 상호 작용함에 따라 이벤트가 발생하여 부작용을 유발하고 새로운 상태로의 전환이 발생하는 이벤트와 함께 어떤 상태가 있는지에 대한 위젯을 모델링하는 것이 더 간단하지 않습니까? 물론, 그러나 그것이 우리가 이미하고있는 일입니다. 문제는 코드가 어디에나 흩어져 있다는 것입니다. Xstate는 우리에게 이러한 방식으로 상태를 올바르게 모델링 할 수있는 능력을 제공합니다.

기대치 설정

Xstate가 마술처럼 우리의 복잡성을 마술처럼 사라질 것으로 기대하지 마십시오. 우리는 여전히 스프링을 조정하고, 개방 및 마감 상태를 기준으로 스프링 구성을 조정하고, 핸들 크레인스를 조정해야합니다. Xstate가 우리에게 제공하는 것은이 상태 관리 코드를 추론하기 쉬운 방식으로 중앙 집중화하고 조정할 수있는 능력입니다. 실제로, 우리의 전체 라인 수는 주 머신 설정의 결과로 약간 증가 할 것입니다. 봅시다.

첫 번째 상태 기계

바로 뛰어 들어 맨 뼈 상태 기계의 모습을 보자. Xstate의 FSM 패키지를 사용하고 있습니다.이 패키지는 최소 1KB 번들 크기로 최소한의 Xstate 버전 인 Xstate 버전을 사용하고 있으며 라이브러리에 적합합니다. 전체 Xstate 패키지와 같은 고급 기능은 많지 않지만 사용 사례에는 필요하지 않으며 이와 같은 소개 게시물을 원하지 않을 것입니다.

상태 기계의 코드는 아래에 있으며 대화식 데모는 Code Sandbox에서 끝납니다. 많이 있지만 곧 갈 것입니다. 그리고 분명히, 그것은 아직 작동하지 않습니다.

 Const Statemachine = Createmachine (
  {
    초기 : "초기",
    문맥: {
      오픈 : 거짓,
      노드 : null
    },
    상태 : {
      초기의: {
        on : {Open : "Open"}
      },
      열려 있는: {
        에: {
          렌더링 : {액션 : "렌더링"},
          크기 조정 : {action : "resize"},
          닫기 : "폐쇄"
        },
        진입 : "오픈"
      },
      마감 : {
        에: {
          Open : {target : "Open", Action : [ "Resize"]},
          폐쇄 : "닫혀"
        },
        입장 : "닫기"
      },
      닫기 : {
        에: {
          오픈 : "오픈"
        },
        입장 : "폐쇄"
      }
    }
  },
  {
    행동 : {
      열기 : 할당 (context => {
        return {... 컨텍스트, 오픈 : true};
      }),
      렌더링 : 할당 ((context, evt) => {
        const {node} = evt;
        반환 {... 컨텍스트, 노드};
      }),
      닫다() {},
      크기 조정 (컨텍스트) {},
      닫기 : 할당 (() => {
        return {open : false, node : null};
      })
    }
  }
);
로그인 후 복사

위에서 아래로 가자. 초기 속성은 초기 상태의 내용을 제어하며,“초기”라고 불렀습니다. 컨텍스트는 상태 기계와 관련된 데이터입니다. 결과 목록이 현재 열려 있는지 여부와 동일한 결과 목록의 노드 객체에 대해 부울을 저장하고 있습니다. 다음으로 우리는 주를 본다. 각주는 주 재산의 핵심입니다. 대부분의 주에서는 우리가 재산과 진입 속성을 가지고 있음을 알 수 있습니다.

이벤트를 구성합니다. 각 이벤트마다 새로운 상태로 전환 할 수 있습니다. 우리는 행동이라고 불리는 부작용을 실행할 수 있습니다. 또는 둘 다. 예를 들어, 개방형 이벤트가 초기 상태 내부에서 발생하면 개방 상태로 이동합니다. 렌더링 된 이벤트가 열린 상태에서 발생하면 렌더링 된 동작을 실행합니다. 그리고 열린 이벤트가 마감 상태 내부에서 발생하면, 우리는 열린 상태로 전환하고 크기 조정 조치를 실행합니다. 대부분의 상태에서 볼 수있는 입력 필드는 주가 입력 될 때마다 자동으로 실행되도록 조치를 구성합니다. 우리는 여기에 필요하지 않지만 종료 조치도 있습니다.

우리는 여전히 몇 가지 더 덮을 것입니다. 상태 기계의 데이터 또는 컨텍스트가 어떻게 변할 수 있는지 살펴 보겠습니다. 우리가 컨텍스트를 수정하기위한 행동을 원할 때, 우리는 그것을 할당하고 행동에서 새로운 컨텍스트를 반환합니다. 처리가 필요하지 않으면 새 상태를 직접 전달하여 할당 할 수 있습니다. 우리의 행동이 컨텍스트를 업데이트하지 않는다면, 즉 부작용에 대한 것이면, 우리는 행동 함수를 할당으로 랩핑하지 않고 필요한 부작용 만 수행합니다.

주 머신의 변화에 ​​영향을 미칩니다

우리는 주 머신에 대한 멋진 모델을 가지고 있지만 어떻게 실행 합니까? 우리는 해석 기능을 사용합니다.

 const statemachineservice = 해석 (statemachine) .start ();
로그인 후 복사

이제 StateMachineservice는 실행중인 상태 머신으로, 이벤트를 호출하여 전환과 행동을 강요 할 수 있습니다. 이벤트를 시작하기 위해, 우리는 Send를 호출하여 이벤트 이름을 전달한 다음 선택적으로 이벤트 개체를 전달합니다. 예를 들어, 결과가 DOM에서 먼저 마운트 할 때 실행되는 Svelte 조치에서 다음과 같습니다.

 stateMachineserVice.send ({type : "rended", node});
로그인 후 복사

이것이 바로 렌더링 된 작업이 결과 목록의 노드를 가져 오는 방법입니다. 나머지 autocomplete.svelte 파일을 둘러 보면 모든 임시 상태 관리 코드가 단일 라인 이벤트 디스패치로 대체됩니다. 입력 클릭/초점의 이벤트 핸들러에서는 열린 이벤트를 실행합니다. ResizeObserver는 크기 조정 이벤트를 발사합니다. 등.

잠시 잠시 멈추고 Xstate가 우리에게 무료로 제공하는 것에 감사드립니다. Xstate를 추가하기 전에 입력을 클릭하거나 집중할 때 실행되는 핸들러를 살펴 보겠습니다.

 함수 inputEngaged (evt) {
  if (폐쇄) {
    setSpringDimensions ();
  }
  Open = true;
  resultsListVisible = true;
}
로그인 후 복사

전에, 우리는 우리가 문을 닫고 있는지 확인하고, 그렇다면 슬라이딩 스프링의 재 계산을 강요했습니다. 그렇지 않으면 우리는 위젯을 열었습니다. 그러나 이미 열려있을 때 입력을 클릭하면 어떻게 되었습니까? 동일한 코드가 다시 ran. 다행히도 그것은 실제로 중요하지 않았습니다. Svelte는 우리가 개방하고 이미 보유한 값에 대한 결과를 다시 표시 할 수 있는지 신경 쓰지 않습니다. 그러나 이러한 우려는 Xstate에서 사라집니다. 새 버전은 다음과 같습니다.

함수 inputEngaged (evt) {
  statemachineservice.send ( "Open");
}
로그인 후 복사

우리의 주 머신이 이미 열린 상태에 있고 우리가 열린 이벤트를 시작한다면, 해당 상태에 대해 구성된 열린 이벤트가 없기 때문에 아무 일도 일어나지 않습니다. 결과가 닫히면 입력이 클릭 될 때의 특수 처리? 이는 State Machine 구성에서 바로 처리됩니다. 폐쇄 상태에서 실행될 때 오픈 이벤트가 크기 조정 작업에 어떻게 대처되는지 확인하십시오.

물론, 우리는 이전에서 ESC 키 버그를 수정했습니다. 이제 키를 누르면 단순히 가까운 이벤트가 발생합니다.

마무리

결말은 거의 반 임시 적입니다. 우리는 이전에하고 있던 모든 일을 가져 와서 단순히 우리의 행동 중 올바른 장소로 옮겨야합니다. Xstate는 코드를 작성해야 할 필요성을 제거하지 않습니다. 그것은 구조화되고 명확한 장소 만 제공합니다.

 {
  행동 : {
    열기 : 할당 ({open : true}),
    렌더링 : 할당 ((context, evt) => {
      const {node} = evt;
      const dimensions = getResultsListDimensions (노드);
      itemsheightobserver.observe (노드);
      불투명도 스프링 (1, {hard : true});
      Object.Assign (SlideInspring, Slide_Open);
      SlideInspring.update (prev => ({... prev, width : dimensions.width}), {
        하드 : 사실입니다
      });
      SlideInspring.set (치수, {hard : false});
      반환 {... 컨텍스트, 노드};
    }),
    닫다() {
      불투명 스프링 (0);
      Object.Assign (SlideInspring, Slide_Close);
      슬라이드 인스프링
        .update (prev => ({... prev, height : 0})))))
        . (() => {
          statemachineservice.send ( "폐쇄");
        });
    },
    크기 조정 (컨텍스트) {
      불투명 스프링 (1);
      SlideInspring.set (getResultsListDimensions (Context.Node));
    },
    닫기 : 할당 (() => {
      ItemSheightObserver.unobserve (resultslist);
      return {open : false, node : null};
    })
  }
}
로그인 후 복사

잡동사니

우리의 애니메이션 상태는 주 머신에 있지만 어떻게 꺼내 나요? 우리는 결과 목록 렌더링을 제어하기 위해 열린 상태가 필요하며,이 데모에는 사용되지 않지만이 자동으로 큰 위젯의 실제 버전에는 현재 강조 표시된 항목을보기에 스크롤하는 것과 같은 것들에 대한 결과 목록 Node가 필요합니다.

Statemachineservice에는 상태 변경이있을 때마다 발사되는 구독 방법이 있습니다. 당신이 전달하는 콜백은 컨텍스트 객체를 포함하는 현재 상태 기계 상태로 호출됩니다. 그러나 Svelte는 슬리브에 특별한 속임수를 가지고 있습니다. $ : 부수적 인 구문은 구성 요소 변수 및 svelte 매장에서만 작동하지 않습니다. 또한 구독 방법이있는 객체와도 작동합니다. 즉, State Machine과 이와 같이 간단한 것으로 동기화 할 수 있습니다.

 $ : ({Open, node : resultStlist} = $ stateMachineserVice.context);
로그인 후 복사

정기적 인 파괴, 일부 파렌은 일이 올바르게 구문 분석 할 수 있도록 도와줍니다.

개선을위한 영역으로서 여기에서 한 가지 빠른 참고 사항. 현재 우리는 부작용을 수행하고 상태를 업데이트하는 몇 가지 조치가 있습니다. 이상적으로, 우리는 이것을 부작용을위한 두 가지 동작으로 나누고 다른 하나는 새로운 상태에 할당을 사용하여 나누어야 할 것입니다. 그러나 나는이 기사가 가능한 한 간단하게 유지하기로 결정했습니다.이 기사는 XSTATE의 도입을 완화하는 데 도움이되기로 결정했습니다.

여기 데모가 있습니다

이별 생각

이 게시물이 Xstate에 대한 관심을 불러 일으키기를 바랍니다. 복잡한 상태를 관리하기 위해 매우 유용하고 사용하기 쉬운 도구라는 것을 알았습니다. 우리는 표면을 긁 었음을 아십시오. 우리는 최소한의 FSM 패키지에 중점을 두었지만 전체 Xstate 라이브러리는 중첩 상태에서 약속에 대한 일류 지원에 이르기까지 여기에서 다룬 것보다 훨씬 더 많은 것을 할 수 있으며 상태 시각화 도구도 있습니다! 나는 당신이 그것을 확인할 것을 촉구합니다.

행복한 코딩!

위 내용은 XSTATE와 Svelte 애니메이션을 조정합니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿