Web
animejs
motiongraphics
webmotion

長方形が変形して文字が出てくるwebのあの動きの実装と応用

どんなものが出来るのか

このgif画像を参考にしてください。
2018-04-03_16-55-23.gif

「あの動き」では困るので「カバーアニメーション」と命名します。正式名称があったら誰か教えてください。

基本の形の作り方

アニメーションは広く普及しているanime.jsで記述します。

環境

CSSリセットとしてress、アニメーションはanime.jsで記述していきます。

お使いの環境に合わせて適宜変更していってください。

コーディング

HTML

<div class="wrap">
    <div class="cover"></div>
    <p>ANIMATION</p>
</div>

CSS

.wrap {
    position: relative;
    padding: 8px;
}

.wrap > .cover {
    position: absolute;
    z-index: 1;

    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background: #03a9f4;
}

.wrap > p {
    position: relative;
    z-index: 0;

    font-size: 24px;
    font-family: "Montserrat";
    letter-spacing: 2px;
    color: #1f1f1f;
}

JS

// 要素の取得
var wrap = document.getElementsByClassName("wrap")[0];
var cover = wrap.getElementsByClassName("cover")[0];
var text = wrap.getElementsByTagName("p")[0];

// アニメーション
var timeline = anime.timeline();
timeline
    .add({
        targets: cover,
        duration: 500,
        easing: "easeInExpo",
        begin: () => {
            cover.style.transformOrigin = "left";
            text.style.visibility = "hidden";
        },
        scaleX: [0, 1]
    })
    .add({
        targets: cover,
        duration: 500,
        easing: "easeOutExpo",
        begin: () => {
            cover.style.transformOrigin = "right";
            text.style.visibility = "visible";
        },
        scaleX: [1, 0]
    });

何をやっているか

アニメーション開始時点 (1回目のbegin関数)

文字側のvisibilityhiddenに設定する。
CSSプロパティのtransform-originleftに設定する。

カバーを拡大する (scaleX: [0, 1])

scaleXを0から1へアニメーションさせる。

カバーの拡大が完了 (2回目のbegin関数)

文字側のvisibilityvisibleに設定する。
CSSプロパティのtransform-originrightに設定する。

カバーを縮小する (scaleX: [1, 0])

scaleXを1から0へアニメーションさせる。

基本的にはやっている事はこれだけです。

コツ

イージングは拡大するときにはeaseIn*系、縮小するときにはeaseOut*系を使うと動きがスムーズに見えて見栄えが良くなります。

応用

その1

カバーを2個にします。

2018-04-03_17-34-33.gif

HTML

cover要素はp要素より前に置かないとCSS側のnth-type-of(n)で上手くいかないので注意してください。

<div class="wrap">
    <div class="cover"></div>
    <div class="cover"></div>
    <p>ANIMATION</p>
</div>

CSS

基本のCSSを少し改変します。

.wrap > .cover:nth-of-type(1) {
    background-color: #03a9f4;
    z-index: 2;
}

.wrap > .cover:nth-of-type(2) {
    background-color: #0277bd;
    z-index: 1;
}

JS

カバー毎にdurationdelayを少しだけずらします。

// 要素の取得
var wrap = adv_1.getElementsByClassName("wrap")[0];
var cover1 = wrap.getElementsByClassName("cover")[0];
var cover2 = wrap.getElementsByClassName("cover")[1];
var text = wrap.getElementsByTagName("p")[0];

// アニメーション
var timeline = anime.timeline();
timeline
    .add({
        targets: [cover1, cover2],
        duration: (target, index) => 500 - index * 100,
        easing: "easeInExpo",
        begin: () => {
            cover1.style.transformOrigin = "left";
            cover2.style.transformOrigin = "left";
            text.style.visibility = "hidden";
        },
        scaleX: [0, 1]
    })
    .add({
        targets: [cover1, cover2],
        duration: 500,
        delay: (target, index) => index * 100,
        easing: "easeOutExpo",
        begin: () => {
            cover1.style.transformOrigin = "right";
            cover2.style.transformOrigin = "right";
            text.style.visibility = "visible";
        },
        scaleX: [1, 0]
    });

その2

応用 その1を簡略化したものです。イージングを各要素ごとに違うものを適用しています。
2018-04-03_17-49-49.gif

HTML、CSSは応用1のものと同じです。

JS

timeline
    .add({
        targets: [cover1, cover2],
        duration: 500,
        easing: (target, index) => `easeIn${["Expo", "Cubic"][index]}`,
        scaleX: [0, 1],
        begin: () => {
            cover1.style.transformOrigin = "left";
            cover2.style.transformOrigin = "left";
            text.style.visibility = "hidden";
        }
    })
    .add({
        targets: [cover1, cover2],
        duration: 500,
        easing: (target, index) => `easeOut${["Expo", "Cubic"][index]}`,
        scaleX: [1, 0],
        begin: () => {
            cover1.style.transformOrigin = "right";
            cover2.style.transformOrigin = "right";
            text.style.visibility = "visible";
        }
    });

最後

間違ってたらコメント欄でご指摘ください。

ブラウザ上で動かす
ソースコード