use-animated-state.mjs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { useState, useLayoutEffect } from 'react';
  2. import { useConstant } from '../../utils/use-constant.mjs';
  3. import { makeUseVisualState } from '../../motion/utils/use-visual-state.mjs';
  4. import { createBox } from '../../projection/geometry/models.mjs';
  5. import { VisualElement } from '../../render/VisualElement.mjs';
  6. import { animateVisualElement } from '../interfaces/visual-element.mjs';
  7. const createObject = () => ({});
  8. class StateVisualElement extends VisualElement {
  9. constructor() {
  10. super(...arguments);
  11. this.measureInstanceViewportBox = createBox;
  12. }
  13. build() { }
  14. resetTransform() { }
  15. restoreTransform() { }
  16. removeValueFromRenderState() { }
  17. renderInstance() { }
  18. scrapeMotionValuesFromProps() {
  19. return createObject();
  20. }
  21. getBaseTargetFromProps() {
  22. return undefined;
  23. }
  24. readValueFromInstance(_state, key, options) {
  25. return options.initialState[key] || 0;
  26. }
  27. sortInstanceNodePosition() {
  28. return 0;
  29. }
  30. }
  31. const useVisualState = makeUseVisualState({
  32. scrapeMotionValuesFromProps: createObject,
  33. createRenderState: createObject,
  34. });
  35. /**
  36. * This is not an officially supported API and may be removed
  37. * on any version.
  38. */
  39. function useAnimatedState(initialState) {
  40. const [animationState, setAnimationState] = useState(initialState);
  41. const visualState = useVisualState({}, false);
  42. const element = useConstant(() => {
  43. return new StateVisualElement({
  44. props: {
  45. onUpdate: (v) => {
  46. setAnimationState({ ...v });
  47. },
  48. },
  49. visualState,
  50. presenceContext: null,
  51. }, { initialState });
  52. });
  53. useLayoutEffect(() => {
  54. element.mount({});
  55. return () => element.unmount();
  56. }, [element]);
  57. const startAnimation = useConstant(() => (animationDefinition) => {
  58. return animateVisualElement(element, animationDefinition);
  59. });
  60. return [animationState, startAnimation];
  61. }
  62. export { useAnimatedState };