株式会社グローバルゲート公式ブログ
こんにちは。株式会社グローバルゲートのモーリーです。
紅白の出場歌手が発表されましたが、今年は米津玄師さんは出ない可能性が高そうですね。2020年に嵐に楽曲を提供するそうなので、そちらを楽しみにして、紅白はLiSAさんとおしりたんていに注目したいと思います。
さて、米津玄師さんのキャリアはボカロPからはじまっているのはご存知だと思いますが、ボカロ楽曲の動画は静止画のイラストに歌詞を組み合わせたアニメーションとして作成されていることが多いです。
(最近はMMDやLive2Dを使ったハイクオリティなアニメーションも増えてきてます)
Web制作では音楽をつけることはめったにありませんが、静止画+テキストでアニメーションという表現技法は管理や更新が簡単でありながらもインパクトがあっていいのではと思い、作成してみました。
まずは完成品をご覧ください
今回はCSSとjQueryのほか、anime.jsというJavascriptライブラリを使用しました。
全ソースをGithubに公開していますので、ご興味のある方はご覧ください。
https://github.com/globalgatej/animationLikeVocaloid
会社用のGithubアカウントも開設してしまった…草まみれにするようにがんばります。
HTML
HTMLはできるだけシンプルに、背景画像を設定したdivとテキストだけにします。
<div id="keyvisual">
<div class="keyvisual_main">
<div class="keyvisual_item" style="background-image: url(img1.jpg)">
<p>いつからこんなに大きな</p>
</div>
<div class="keyvisual_item" style="background-image: url(img2.jpg)">
<p>思い出せない記憶があったか</p>
</div>
<div class="keyvisual_item" style="background-image: url(img3.jpg)">
<p>どうにも憶えてないのを</p>
</div>
<div class="keyvisual_item" style="background-image: url(img4.jpg)">
<p>ひとつ確かに憶えてるんだな</p>
</div>
<div class="keyvisual_item" style="background-image: url(img1.jpg)">
<p>もう一回何回やったって</p>
</div>
<div class="keyvisual_item" style="background-image: url(img2.jpg)">
<p>思い出すのはその顔だ</p>
</div>
<div class="keyvisual_item" style="background-image: url(img3.jpg)">
<p>それでもあなたがなんだか</p>
</div>
<div class="keyvisual_item" style="background-image: url(img4.jpg)">
<p>思い出せないままでいるんだな</p>
</div>
</div>
<div class="keyvisual_loading">
<div class="loading_item"></div>
</div>
</div>
各div.keyvisual_itemが順繰りで表示され、その間にテキストが一文字ずつ表示される、という流れです。
前処理としてアニメーション定義やテキストへの編集をJavascriptで行うため、アニメーション開始まで時間がかかります。ローディングを忘れずに。
CSS
#globalheader {
padding: 40px 20px;
}
#globalheader h1 {
font-size: 1.2rem;
font-weight: 700;
}
#keyvisual {
position: relative;
height: 600px;
background: #000;
}
.keyvisual_item {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-position: center center;
background-size: cover;
}
.keyvisual_item p {
font-family: "Noto Serif JP", "BIZ UDPMincho", "ヒラギノ明朝 ProN W6", "HiraMinProN-W6", "HG明朝E", serif;
font-weight: 700;
color: #fff;
font-size: 3rem;
position: absolute;
width: 100%;
left: 0;
top: 50%;
margin-top: -1rem;
text-align: center;
}
main {
padding: 20px;
}
main p:not(:last-child) {
margin-bottom: 1rem;
}
#copy {
text-align: center;
}
/* loading用 */
.keyvisual_loading {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #222;
display: flex;
z-index: 100;
align-items: center;
justify-content: center;
}
.loading_item {
flex: none;
width: 30px;
height: 30px;
background: #fff;
animation: loading 0.5s linear infinite;
}
@keyframes loading {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
body.loaded .loading_item {
animation: loading_end 1s linear;
}
@keyframes loading_end {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
body.loading_end .loading_item {
animation: loading_finish 0.4s linear forwards;
}
@keyframes loading_finish {
0% {
opacity: 1;
height: 30px;
width: 30px;
}
50% {
opacity: 1;
height: 30px;
width: 100%;
}
100% {
opacity: 0;
width: 100%;
height: 100%;
}
}
/* アニメーション用の初期設定 */
.keyvisual_item p span {
display: inline-block;
transform: scale(0);
position: relative;
}
.keyvisual_item p span:not(:last-child) {
margin-right: 1vw;
}
.keyvisual_item p spanはHTML上にはいませんでしたが、以下のJavascriptで一文字ずつspanで囲う処理を入れたあとで生きてきます。
Javascript
まずはHTML内でjQueryとanime.jsをロードしておきます。
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/animejs@3.1.0/lib/anime.min.js"></script>
全文はGithubをご覧いただくとして、ポイントをいくつか解説します。
文字を一文字ずつspanで囲い、アニメーションを適用させる
//文字(p)を1個ずつspanで囲う
$item.find('p').each(function (key, value) {
var text = $(this).get(0).textContent;
var textOut = '';
var textArr = text.split('');
var textNum = textArr.length;
$.each(textArr, function (key, value) {
//ウインドウ内に収まるように文字サイズを調整
textOut += '<span style="font-size: ' + 70 / textNum + 'vw">' + value + '</span>';
});
$(this).empty();
$(this).html(textOut);
});
テキストを一文字ずつspanで囲うことで、一文字ずつアニメーションを伴って出現する・消える、という表現が可能になります。
anime.jsによるアニメーション構築
//アニメーション
//空タイムラインを定義し、addしていく方法が分かりやすくておすすめ
const timeLine = anime.timeline({
loop: true,
autoplay: false // 停止状態でアニメなどを構築しておく
});
$item.each(function(key, value) {
timeLine.add({
//文字のアニメーション
targets: $(value).find('p span').get(),
//1個おきに大きかったり小さかったり角度を付けたり
scale: function(el, index) {
return index % 2 ? [0, 1] : [0, 1.5]
},
rotate: function(el, index) {
return index % 2 ? [15, 15] : [-15, -15]
},
easing: 'easeOutCubic',
duration: 400,
//1文字ずつ200ミリ秒遅延させる
delay: anime.stagger(150)
}).add({
//文字が全部表示されたら文字を消す
targets: $(value).find('p span').get(),
opacity: 0,
//1文字ずつ交互に上下に動く
top: function(el, index) {
return index % 2 ? '1em' : '-1em';
},
scale: '+=1.2',
easing: 'easeOutCubic',
duration: 600
}, '-=100').add({
//ステージのフェードアウト
targets: $(value).get(0),
opacity: {
value: 0,
easing: 'linear'
},
duration: 400,
//順番を入れ替えて裏にもっていく
complate: function() {
$(this).append($(this).parent()).css('opacity', 1);
}
});
});
anime.jsにはtimelineという機能があり、timelineオブジェクトを定義し、そこにadd関数でつなげていくことで順繰りのアニメーションを作成することができます。JavascriptのPromiseと同等のものと考えると分かりやすいでしょう。
jQueryでこのような順番に実行されるアニメーションを作成するときは
・animate関数のコールバックでがんばる
・Deferredでがんばる
のどちらかになりますが、コールバックは地獄が待っていますしDeferredもコード量が増えてしまいます。
anime.jsはコード管理のしやすさという点でも扱いやすいライブラリです。
非公式ですが日本語翻訳されたドキュメントも分かりやすい。
まとめ
動画の場合は一部だけ差し替えたり文章を書き換えたりするのは難しいですが、画像と文字だけなら差し替えるのも簡単です。
ほかにはないオリジナルな表現をやってみたい方はぜひ参考にしてみてください!(もちろん当社へご依頼いただくのも大歓迎ですw)
【関連記事】
カテゴリー
月別アーカイブ
ブログ内検索
執筆メンバーについて
モーリー
Webデザイナー。
当サイトのデザインと管理も担当しています。
ナミー
Webディレクター。
本社制作部の紅一点。お客様に寄り添った提案を心かげています。
タカ
サーバーエンジニア。
Webサイトにとってサーバーは命、ネットワークは血液です。Webサイトの安定稼働のために日夜注力しています。
たっくん
ITアドバイザー
Webサイトの活用方法からオフィスのネットワーク整備まで、多角的にITの活用方法をご案内させていただきます。
ノーさん
制作部ディレクター。
業種を問わず多くのお客様を担当させていただきました。Webサイトのお悩み、活用方法などぜひご相談ください。
カン
制作部デザイナー。
制作部最年少の若手ですが、だからこそ生まれるアイデア・発想にご期待ください。
当社サービスについてのお問い合わせは下記までご連絡下さい。
06-6121-7581 / 03-6415-8161