なぽろぐ

気ままに感じたことを記事にまとめます。

LottieWebでチェックボックスの状態を管理する

Lottieで消えちゃうCheckBox作るぞ!

こういうのを作りたい

https://naporin0624.github.io/napoblog-assets/#/

Image from Gyazo

今回はこちらのチェックボックスアニメーションを使わせていただきました.

lottiefiles.com

コードの全体像

Lottieのマウントにはreact-lottieを使っています.animを直で触りたいのでそこの部分だけ型定義を拡張して使っている感じですね.

github.com

index.tsx

import React, { useRef, useEffect } from "react";
import Lottie from "react-lottie";
import checkbox from "./checkbox.json";
import { AnimationItem } from "lottie-web";

interface LottieType extends Lottie {
  anim: AnimationItem;
}
interface Props {
  checked: boolean;
}
const options = {
  loop: false,
  autoplay: false,
  animationData: checkbox,
  rendererSettings: {
    preserveAspectRatio: "xMidYMid slice",
  },
};
export const CheckBox = (props: Props) => {
  const { checked } = props;
  const ref = useRef<LottieType>(null);
  const prev = useRef<boolean>();

  useEffect(() => {
    // 初回マウントときはレンダリングしない
    // falseでは行ってきたときにgoToAndPlayされるのを防ぐため
    if (prev.current === undefined) {
      prev.current = checked;
      // 初回マウント かつ チェックボックスが選択されているならフレームの最後からアニメーションを実行する
      checked && ref.current?.anim.goToAndPlay(ref.current?.anim.getDuration(true), true);
      return;
    }

    if (checked) {
      ref.current?.anim.goToAndPlay(0, true);
    } else {
      ref.current?.anim.setDirection(-1);
      ref.current?.anim.goToAndPlay(15, true);
    }
  }, [checked]);
  return <Lottie ref={ref} options={options} width={300} />;
};

最後に

lottie-webにはここでフレームを止めるみたいなことができないぽいのでこのような措置を取りました.もっといい方法があれば教えてください🙇‍♂️

初めはこの子

lottiefiles.com

で実装していてチェックされてから消えるまでセットのアニメーションだったために以下のようにしていたのですが

  useEffect(() => {
    ref.current?.anim.playSegments([30, 75], true);
    ref.current?.anim.stop();
  }, []);

なぜかこうなる・・・・・・

Image from Gyazo

消すとうまくいくので明らかにplaySegmentが悪いのはわかっているんですけど,どう直したらいいのかわからなかったので上で紹介したアニメーションを使いました

有識者教えてください!!!!

わかっていること

  • destroyの前に動き始めている
    • useEffectのreturnにconsole.logをしこませて検証
  • playSegmentの上にconsole.logをおいても初期レンダリング以外では反応なし

ぐらいです・・・・・・