セブではたらく(インターン)
セブではたらく(インターン)
2019.04.15
#185
それいけ!フロントエンド

マウスクリックで顔が増殖!?ワクワクする「TweenMaxアニメーション」を作ろう!

しんどうドリル

こんにちは! フロントエンドエンジニアのドリルです。

さて今回は、マウスクリックで顔が増殖するアニメーションをご紹介します。

概要

4人のLIG社員の顔を増殖
し・ま・す・よ♡

づや
はっちゃん
ありさん
しんどうドリル

登場人物

今回こちらの方々のを使わせていただきました。

撮影と、写真切り抜き、素材制作はデザイナーのありさんに協力してもらいました! 感謝感謝!

づや 人物紹介:づや最高技術責任者。偉い人。
はっちゃん 人物紹介:はっちゃんフロントエンドエンジニア。とにかくヒゲが濃い。
ありさん 人物紹介:ありさんデザイナー。かわいいモノが好き。
しんどうドリル 人物紹介:しんどうドリルフロントエンドエンジニア。日々ドリルしている。

増殖の下準備

  • 増殖用の画像
  • 増殖する場所
  • 増殖ボタン

HTML

<!-- 増殖用の画像 -->
<div class="original">
  <div class="original__item">
    <img src="https://liginc.co.jp/wp-content/uploads/2019/03/001.png">
  </div>
  <div class="original__item">
    <img src="https://liginc.co.jp/wp-content/uploads/2019/03/002.png">
  </div>
  <div class="original__item">
    <img src="https://liginc.co.jp/wp-content/uploads/2019/03/003.png">
  </div>
  <div class="original__item">
    <img src="https://liginc.co.jp/wp-content/uploads/2019/03/004.png">
  </div>
</div>

<!-- 増殖する場所 -->
<div class="wrapper" id="js-wrapper">
</div>

<!-- 増殖するボタン -->
<div class="btn" id="js-btn">ボタン</div>

CSS

/*コピー元として使うだけなので、display:noneして、非表示にしている*/
.original {
  display: none;
}

/*増殖用の画像*/
.original__item {
  // 座標を中心にしている
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: -75px;
  margin-top: -75px;
  width: 150px;
  height: 150px;
  
  img {
    width: 100%;
    height: 100%;
  }
}

/*増殖する場所*/
.wrapper {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

/*増殖するボタン*/
.btn {
  z-index: 10;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 100px;
  height: 100px;
  background: #333;
  border-radius: 100%;
  
  font-family: "Arial";
  color: #fff;
  text-align: center;
  line-height: 100px;
  cursor: pointer;
}

結果

真ん中にボタンだけが配置されます。
TweenMax アニメーション

増殖のJavaScript ~拡散編~

プラグインを読み込む

今回はTweenMax.jsを使用するので、CDNから読み込みましょう。

<!-- https://greensock.com/gsap -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js"></script>

Webpackなどを使っている方は、以下のようにnpm installした後、import文を記述してください。

$ npm install gsap
import 'gsap/TweenMax';

本コード

// 増殖させるボタン
var $btn = document.querySelector('#js-btn');

// 増殖する場所
var $wrapper = document.querySelector('#js-wrapper');

// 増殖用の画像
var $originalItem = document.querySelectorAll('.original__item');

// 増殖アニメーション用のイージング
// https://greensock.com/ease-visualizer
var easingName = [ 
  'Back.easeInOut.config(1.7)',
  'Elastic.easeInOut.config(1, 0.3)',
  'Bounce.easeInOut',
  'ease: Circ.easeInOut'
 ];

増殖アニメーション用のイージングですが、配列で4つ定義しています。アニメーションのバリエーションを増やすためです。イージングについては、greensockのease-visualizerを参照しています。

$btn.addEventListener('click', function() {
  
  // ランダムで全ての要素の中から1つ、要素を選んで、複製する
  var randNum = Math.floor(Math.random() * $originalItem.length);
  var $clone = $originalItem[ randNum ].cloneNode(true);
  
  // 要素を挿入する
  $wrapper.appendChild($clone);
  
  // 要素を拡散する
  // ---------------------------------------------------------------
  var expandAnime = {
    x: Math.floor(Math.random() * window.innerWidth - window.innerWidth / 2),
    y: Math.floor(Math.random() * window.innerHeight - window.innerHeight / 2),
    rotation: Math.floor(Math.random() * 720 - 360),
    scale: 0.2 + Math.random(),
    duration: 0.5 + Math.random() * 2.0,
    ease : easingName[ Math.floor(Math.random() * easingName.length) ]
  };
  
  TweenMax.to($clone, expandAnime.duration, {
    x: expandAnime.x,
    y: expandAnime.y,
    rotation: expandAnime.rotation,
    scale: expandAnime.scale,
    ease: expandAnime.ease
  });
});

処理の流れとしては以下の通りです。

  • 要素を複製する
  • 要素を挿入する
  • 要素を拡散する

要素を拡散するところがミソで、x軸、y軸、回転角度、スケール、秒数に対して、ランダムなパラメータを与えています。
イージングに関しては4種類から、ランダムで選ばれます。

結果

See the Pen
Clone btn – TweenMax – cloneNode – appendChild – test
by Sho Shindo (@kabukimono)
on CodePen.

きゃあ〜〜〜〜かわいいい♡

だがこれではずっと増え続けてしまう。。。

増殖のJavaScript ~消失編~

次に増殖させたものを、マウスオーバーで削除する機能を作ります。

本コード

$clone.addEventListener('mouseover', function() {
// 拡大
TweenMax.to($clone, 0.3, {
  scale: 2.0,
  opacity: 0,
  ease: 'Power2.easeIn'
});

// 0.3秒後に要素を削除
setTimeout(function() {
  $clone.remove();
}, 300);
});

これをclick functionの中に入れてください。複製したものにマウスオーバーイベントを付与しています。中の処理は、その要素が拡大して0.3秒後に要素を削除しています。

結果

See the Pen
step2 – Clone btn – TweenMax – cloneNode – appendChild
by Sho Shindo (@kabukimono)
on CodePen.

マウスオーバーすると顔が消える機能が追加されました♡

増殖のJavaScript ~躍動編~

次に拡散した顔が、動き続けるアニメーションを作ります。

本コード

var $img = $clone.querySelector('img');
  
var loopAnime = {
  x: Math.floor(Math.random() * 100),
  y: Math.floor(Math.random() * 100),
  rotation: Math.floor(Math.random() * 360 - 180),
  scale: 0.2 + Math.random(),
  duration: 0.5 + Math.random() * 2.0,
  ease: easingName[ Math.floor(Math.random() * easingName.length) ]
};

TweenMax.to($img, loopAnime.duration, {
  x: loopAnime.x,
  y: loopAnime.y,
  rotation: loopAnime.rotation,
  scale: loopAnime.scale,
  ease: loopAnime.ease,
  repeat: -1, // 無限ループ
  yoyo: true, // 往復リピート
  delay: expandAnime.duration // 飛び散るアニメーションが終わったら開始
});

~消失編~のように、これをclick functionの中に入れてください。

それぞれランダムなパラメータを設定して、アニメーションさせます。これはoriginal__itemクラスの子要素であるimgに設定します。original__itemクラスは拡散用、子要素のimgは躍動用としています。

結果

See the Pen
step3 – Clone btn – TweenMax – cloneNode – appendChild
by Sho Shindo (@kabukimono)
on CodePen.

顔が拡散したあと、ループアニメーションを発生させています。

まとめ

いかがでしたか? 今回はちょっとしたアイデアで、アニメーションを面白く、楽しくする方法を記事にしました。何かに応用していただけたら幸いです。ドリルでした!

LIGに楽しいアニメーションの実装を依頼する!