最近マイブームの「アレ、どうやって作るんだろう?」的なメモです。
たまに見かける「メニューを開くと文字がフワフワっと出てくる」アレ。
実は以前から「どうやって作るんだろう??」と思ってたんです。
transition-delay
を付けても出来そうなんですけど、
何か1文字ずつズレて表示されてるし、
人力で手作業でやってるワケないしな〜と思ったので、調べました。
調べた結果、おそらくSplitText
っていうエフェクトの
カスタムの一種だろうと思いました。
gsap
っていうJavascriptアニメーションフレームワーク
があるんですけど、
それの高機能なバージョンに付属している機能です。
Vue.jsで試してみる。
今回もVue.js
です。前回の投稿で「≡」を作った時のソースの流用をします。
https://qiita.com/DaisukeNishi/items/999709a4636f600ffcfa
<template>
<div id="app">
<header class="header">
<h1 class="title">
Website
</h1>
<div
class="menu"
data-state="hoge"
data-mouse="fuga"
@click="click"
@mouseenter="enter"
@mouseleave="leave"
>
<div class="line line-1"></div>
<div class="line line-2"></div>
<div class="line line-3"></div>
<div class="line-close line-close-1"></div>
<div class="line-close line-close-2"></div>
</div>
</header>
<div class="cnt-cover">
<div class="cover"></div> <!--白背景-->
</div>
<nav class="split-text">
<div id="quote" style="text-align:left;">
メニュー表示<br/>
会社概要<br/>
プライバシーポリシー<br/>
あいうえお<br/>
かきくけこ
</div>
</nav>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
.cnt-cover {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 10;
pointer-events: none
}
.cnt-cover .cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #fff;
z-index: 1;
will-change: opacity;
opacity: 0;
}
.split-text {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 20;
color: #000;
opacity: 0;
}
(あれっ!?しまった、書いてる途中に気がついたんですが、
これopacity
だけだとメニューの後ろにあるリンクが押せなくなりますね。
z-index
も一緒に変えれば動くとおもう・・・)→(未検証)
<script>
import gsap from 'gsap';
import SplitText from './js/SplitText.js'
import $ from 'jquery';
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
methods:{
//ハンバーガーメニューのイベント
click(e){
if(e.target.dataset.state !== 'batsu'){
e.target.dataset.state = 'batsu';
this.show();
}else{
e.target.dataset.state = 'hamburger';
this.hide();
}
},
enter(e){
e.target.dataset.mouse = 'enter';
},
leave(e){
e.target.dataset.mouse = 'leave';
},
show(){
//gsapで表示
const wt = $(".cnt-cover .cover");
const tl = new gsap.timeline({});
tl.to(wt, .15, { autoAlpha:1 });
//jQueryで表示
$(".split-text").css("opacity","1")
//テキストアニメーション
const tl2 = gsap.timeline(),
mySplitText = new SplitText("#quote", {type:"words,chars"}),
chars = mySplitText.chars;
gsap.set("#quote", {perspective: 400});
tl2.from(chars, {duration: 0.8, opacity:0, scale:0, y:80, rotationX:180, transformOrigin:"50% 50% -20", ease:"back", stagger: 0.01}, "+=0");
},
hide(){
//gsapで非表示
const wt = $(".cnt-cover .cover ");
const tl = new gsap.timeline({});
tl.to(wt, 0.15, { autoAlpha:0 });
//jQueryで非表示
$(".split-text").css("opacity","0")
},
},
}
</script>
使用方法の説明にはこう書いてあります。
an array of all the divs that wrap each character
div
の中にある全ての文字をアニメーションさせる、的な意味かと。
多分、親要素に書いてあげれば子要素に適用できるはず。
変数をconst3連続で定義してます。
こちらのSplitText
はimport
してないとエラーになります。
const tl2 = gsap.timeline(),
mySplitText = new SplitText("#quote", {type:"words,chars"}),
chars = mySplitText.chars;
パースペクティブの意味はちょっと調べてないですが、文字数制限的な感じかと。
ココで要素のid
を指定しておきます。
gsap.set("#quote", {perspective: 400});
tl2.from(
chars, {
duration: 0.8, //スピード
opacity:0, //開始時の透明度
scale:0, //開始時の大きさ
y:80, //開始時のy軸?
rotationX:180, //開始時にx軸の方向に180度倒す
transformOrigin:"50% 50% -20", //元の大きさとか?
ease:"back", //イージングとか
stagger: 0.01 //ぐらつきの度合い
},
"+=0"); //?なんだろう?
動きました。細かいセッティングが可能です。
プラグインが微妙に高い。
import SplitText from './js/SplitText.js'
こちら、本来はgsap
のパッケージに入ってるのだろうと思います。
有料プラグインは、買うしかないんじゃないですかね商用ライセンスだし。
いやはや「試しにコレ使ってみたいな」で1万円は高いッス。。高いッスよ・・・
CodePen
では無料で使えるらしいですが、まず案件に使えるのかを試したい。
JSプラグイン
を有料で買うって文化が、日本にはまだないので稟議を通らないと思うんですよね。。
オシャレなデザイン事務所様だったら稟議通るかもですけど。
お試しでローカルで使ってみたい(案件で使う時は買う)という話だったら、
β版のSplitText
がどこかに転がってないか探してみたら良いかと思います。
動作保証できないですが、案外バージョンが合わなくても動く気がします。
https://github.com/wh1100717/me.emptystack.net/blob/9b54f1aba0e5140bb873df63c1c5ea614e622e4f/asset/gsap/utils/SplitText.js
https://github.com/pslhrd/PORTFOLIO_V2/blob/50a0224456ed4de14d88f8cfb550d80e425183c1/src/js/SplitText.js
■参考資料
https://goworkship.com/magazine/text-effect-typography/
https://greensock.com/SplitText
https://codepen.io/collection/KiEhr?grid_type=list
https://www.webprofessional.jp/fancy-web-animations-made-easy-greensock-plugins/