💓

いいねアニメーションを自作してみた🫶

2023/04/05に公開

はじめに

皆さんこんにちは!
スペースマーケット エンジニアのk___0122です。

こないだリバイバル上映でやってたパルプフィクションを観てきました🔫
やっぱ映画館で映画を観るのって最高ですね〜📽


ということで以下のようないいねアニメーションを実装したので記事にまとめました。
Zennのいいねボタンのように、クリックしたらハートが動き、ハートの周りが弾けるアニメーションになっています。

いいねアニメーションを作ろうと思ったきっかけは、times(個人チャンネル)で何気なく呟いたことでした😇

言い出しっぺの法則ということで、実現方法を調べてみることに。。。

調べてみると、以下のような画像を用意して、アニメーションをつけて実装する方法がありました。

上の記事を読んでいただくと分かるかと思いますが、アニメーション用の画像を用意し、パラパラ漫画のようにスライドさせていけばいいねアニメーションが実現できるんですね!

ただ今回はハートの静止画を用意し、いいねした時のエフェクトはCSSアニメーションで実装してみることにします。

実装方法

まず白抜きのハートと赤色のハートのsvgを用意します。
これはクリックした時に、imageタグのsrcの値を切り替えてあげます。

次にクリックしたらハートを拡大するアニメーションをつけます。

const heartBeat = keyframes({
  '50%': { transform: 'scale(1.2)' },
})

trasnform: scaleで要素を拡大させることができます。
またkeyframesを使うことでアニメーションの中間地点のスタイルを定義できます。
今回は50%の時に1.2倍の大きさにします。

いい感じにハートが動いてくれました。

次にspanタグを使って以下のようにハートの周りに配置していきます。
配置する場所や大きさは、Zennのいいねボタンを参考にしてます。

ではアニメーションをつけていきます。
spanタグを外に向かってフェードアウトさせたいので、transform: translateを使って要素を移動させたいですね。
要素を薄くしていくにはopacityを使えばよさそうです。

ただspanタグによってtranslateやscaleの値が異なるので、以下のような関数を作りました。

const createAnimationKeyframes = (
  translateX: number,
  translateY: number,
  scale: number,
): Keyframes =>
  keyframes({
    '0%': { opacity: 1 },
    '50%': { opacity: 0.8 },
    '80%': { opacity: 0.2 },
    '100%': {
      opacity: 0.1,
      transform: `translate(${translateX}px, ${translateY}px) scale(${scale})`,
    },
  })
  
  {/* 呼び出し側 */}
   <chakra.span
      pos="absolute"
      top="1px"
      left="-6px"
      background="#CC8EF5"
      borderRadius="100"
      w="4px"
      h="4px"
      opacity="0"
      animation={isClicked ? `${createAnimationKeyframes(-10, -10, 1.4)} 0.25s` : ''}
    />

これで完成です!!

感想

いいねアニメーションってどうやって実装するんだろうなと前々から気になっていましたが、思ったより簡単に実装できました!
これを機にプロダクトにアニメーションをどんどん取り入れていけたらなと思ってます!

最後に

スペースマーケットでは、一緒にサービスを成長させていく仲間を探しています。
とりあえずどんなことをしているのか聞いてみたいという方も大歓迎です!
ご興味ありましたら是非ご覧ください!
https://www.wantedly.com/projects/1113570
https://www.wantedly.com/projects/1113544
https://www.wantedly.com/projects/1061116
https://spacemarket.co.jp/recruit/engineer/

スペースマーケット Engineer Blog

Discussion