Solid examples

Spring animations

import { Component } from "solid-js";
import { spring } from "motion";
import { Motion } from "@motionone/solid";

const App: Component = () => (
  <Motion.div
    animate={{
      rotate: 90,
      "background-color": 'yellow'
    }}
    transition={{
      delay: 1,
      easing: spring()
    }}
  />
);
  
export default App;

Exit animations

import { Component, createSignal, Show } from "solid-js";
import { Motion, Presence } from "@motionone/solid";

const App: Component = () => {
  const [toggle, setToggle] = createSignal(true);
  return (
    <div class="container">
      <Presence exitBeforeEnter>
        <Show when={toggle()}>
          <Motion.div
            initial={{ opacity: 0, scale: 0.6 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.6 }}
            transition={{ duration: 0.3 }}
          />
        </Show>
      </Presence>
      <button onClick={() => setToggle(!toggle())}>
        Toggle
      </button>
    </div>
  );
};

export default App;

Animate between components

import { Component, createSignal } from "solid-js";
import { Motion, Presence } from "@motionone/solid";
import { Rerun } from "@solid-primitives/keyed";

const App: Component = () => {
  const [count, setCount] = createSignal(1);
  const increment = () => setCount((p) => ++p);
  return <>
    <Presence exitBeforeEnter>
      <Rerun on={count()}>
        <Motion
          initial={{ opacity: 0, x: 50 }}
          animate={{ opacity: 1, x: 0, transition: { delay: 0.05 } }}
          transition={{ duration: 0.1 }}
          exit={{ opacity: 0, x: -50 }}
        >
          {count()}
        </Motion>
      </Rerun>
    </Presence>
    <button onClick={increment}>Next</button>
  </>;
};
  
export default App;

SVG loading spinner

import { Component, createSignal, mergeProps } from "solid-js";
import { Motion } from "@motionone/solid";
import { Repeat } from "@solid-primitives/range";

const App: Component<{ offset: number, segments: number }> = (props) => {
  props = mergeProps({ offset: 0.09, segments: 8 }, props);
  return (
    <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
      <Repeat times={props.segments}>
        {i => (
          <g class="segment">
            <Motion.path
              d="M 94 25 C 94 21.686 96.686 19 100 19 L 100 19 C 103.314 19 106 21.686 106 25 L 106 50 C 106 53.314 103.314 56 100 56 L 100 56 C 96.686 56 94 53.314 94 50 Z"
              style={{
                transform: 'rotate(' + (360 / props.segments) * i + 'deg)'
              }}
              animate={{ opacity: [0, 1, 0] }}
              transition={{
                offset: [0, 0.1, 1],
                duration: props.offset * props.segments,
                delay: i * props.offset,
                repeat: Infinity,
              }}
            />
          </g>
        )}
      </Repeat>
    </svg>
  );
};
  
export default App;

SVG path drawing

import { Component, createSignal, mergeProps } from "solid-js";
import { Motion } from "@motionone/solid";

const App: Component = (props) => {
  const draw = (progress) => ({
    // This property makes the line "draw" in when animated
    strokeDashoffset: 1 - progress,
  
    // Each line will be hidden until it starts drawing
    // to fix a bug in Safari where the line can be
    // partially visible even when progress is at 0
    visibility: "visible",
  });
  return (
    <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
      <Motion.circle
        cx="100"
        cy="100"
        r="80"
        pathLength="1"
        animate={draw(1)}
        transition={{ duration: 0.8, delay: 2 }}
      />
      <Motion.path
        d="M 54 107.5 L 88 138.5 L 144.5 67.5"
        pathLength="1"
        animate={draw(1)}
        transition={{ duration: 0.6, delay: 2.4 }}
      />
    </svg>
  );
};

export default App;