CSS3アニメーションでつくるインターフェイス表現

第14回周囲が勢いよく回転するボタン

今回のお題は、ボタンのアニメーションだ。マウスポインタを重ねると、周囲が勢いよく回るサンプル1⁠。Button Spinner Testのデザインとアニメーションをもとに、コードは絞り込んでわかりやすく組み立て直した。animationプロパティで細かい動きをつくり込んでいる。

サンプル1 CSS3CSS3: Button Spinner

ボタンをつくる要素と静的なスタイル

HTMLドキュメントの<body>要素に加えるボタンをつくる要素の記述と、アニメーションを与える前の静的なスタイルはコード1のとおりだ図1⁠。Google FontsのRalewayを使っている。また、<script>要素に-prefix-freeを読み込んで、ベンダープレフィックスは省いた(第1回のベンダープレフィックスと-prefix-freeの項参照⁠⁠。

図1 ボタンの静的なスタイル
図1 ボタンの静的なスタイル
コード1 ボタンをつくる<body>と<head>要素のCSSの定め

<body>要素

<div class="container">
    <div class="circle">
        <div class="spinner">
        </div>
        <div class="label">
            <p>Button</p>
        </div>
    </div>
</div>
<head>要素
<link href="https://fonts.googleapis.com/css?family=Raleway:400,900" rel="stylesheet">
<style>
html {
    background-color: steelblue;
}
.container {
    margin: 150px auto;
    text-align: center;
    background-color: steelblue;
}
.circle {
    background-color: black;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    display: inline-block;
    overflow: hidden;
    cursor: pointer;
}
.spinner {
    background-color: #efefef;
    height: 50px;
    margin-top: 75px;
}
.label {
    background-color: cornflowerblue;
    height: 190px;
    width: 190px;
    position: relative;
    margin: -120px auto;
    border-radius: 50%;
}
.label p {
    text-align: center;
    margin: 40% auto;
    display: inline-block;
    font-family: 'Raleway', sans-serif;
    font-weight: 900;
    font-size: 24pt;
}
</style>
<script src="lib/prefixfree.min.js"></script>

ボタンにマウスポインタが重なったときのアニメーション

ボタンにマウスポインタが重なったときの基本的なアニメーションを加えよう。ボタンの縁として見える大もとの要素class属性"circle")は、以下のようにはじめ背景と同じ色(steelblue)にしておき、:hover擬似クラスで白に変える。内側class属性"label")は背景色を明るい青(lightsteelblue)に、テキストは白にした。アニメーションはtransitionプロパティで定めている。ボタンの縁には待ち時間を加えたので、少しためてから動き始める。

transition: アニメーション時間 タイミング関数 待ち時間
.circle {
    background-color: steelblue /* black */;

    transition: 1s ease-in-out;
}

.circle:hover .label {
    background-color: ;
    transition: 0.3s ease-in-out;
}
.circle:hover .label p {
    color: white;
    transition: 0.3s ease-in-out;
}
.circle:hover {
    background-color: white;
    transition: 1s ease-in-out 0.8s;
}
.label {

    transition: 0.3s ease-in-out;
}
.label p {

    transition: 0.3s ease-in-out;
}

これで、ボタンにマウスポインタを重ねると、内側の色が明るく変わりテキストは白くなる。そして、白い縁が広がるように表れる図2⁠。スタイルの定めは以下にコード2としてまとめた。

図2 マウスポインタを重ねるとアニメーションするボタン
図2 マウスポインタを重ねるとアニメーションするボタン
コード2 ボタンにマウスポインタを重ねたときのアニメーションの定め
html {
    background-color: steelblue;
}
.container {
    margin: 150px auto;
    text-align: center;
    background-color: steelblue;
}
.circle {
    background-color: steelblue;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    display: inline-block;
    overflow: hidden;
    cursor: pointer;
    transition: 1s ease-in-out;
}
.spinner {
    background-color: #efefef;
    height: 50px;
    margin-top: 75px;
}
.circle:hover .label {
    background-color: lightsteelblue;
    transition: 0.3s ease-in-out;
}
.circle:hover .label p {
    color: white;
    transition: 0.3s ease-in-out;
}
.circle:hover {
    background-color: white;
    transition: 1s ease-in-out 0.8s;
}
.label {
    background-color: cornflowerblue;
    height: 190px;
    width: 190px;
    position: relative;
    margin: -120px auto;
    border-radius: 50%;
    transition: 0.3s ease-in-out;
}
.label p {
    text-align: center;
    margin: 40% auto;
    display: inline-block;
    font-family: 'Raleway', sans-serif;
    font-weight: 900;
    font-size: 24pt;
    transition: 0.3s ease-in-out;
}

ボタンの周囲を回るアニメーション

残るは、ボタンの左右両側に見える要素class属性"spinner")を、以下のようにマウスポインタが重なったとき回す@keyframes規則clockwise⁠⁠。マウスポインタが外れたときの逆回しも、併せてanimationプロパティに定めた@keyframes規則anti-clockwise⁠⁠。:hover擬似クラスには、少し遅れた拡大のアニメーションも加えてある@keyframes規則scale⁠⁠。それぞれの@keyframes規則は後で示そう。

さらに、マウスポインタを重ねたときには、ボタンの左右両側の要素class属性"spinner")filterプロパティblur()関数でぼかした。引数にはぼけ幅を渡す。また、cubic-bezier()はタイミング関数を4つの引数で定める。引数の与え方と値がどう変わるかについては、次項で補おう。

.circle {

    opacity: 0.99;

}
.spinner {

    animation: anti-clockwise 1s ease-in-out;
    transform: scaleY(2);
}

.circle:hover .spinner {
    filter: blur(5px);
    animation: clockwise 1s cubic-bezier(1, 0.22, 1, 0.92),
        scale 2s 1s ease-in-out;
}

回転の時計回り(clockwise)と反時計回り(anti-clockwise)および拡大(scale)@keyframesは、それぞれつぎのとおりだ(第10回の五角柱を水平に回す参照⁠⁠。回転角に360度より大きい値を与えれば1周以上くるくると回ることになる。これで、お題のアニメーションはでき上がった。ボタンにマウスポインタを重ねると、周囲が広がりながら、左右の要素はくるくると回る図3⁠。スタイルの定めは以下のコード3にまとめた。

@keyframes clockwise {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(1080deg);
    }
}
@keyframes anti-clockwise {
    from {
        transform: rotate(1080deg);
    }
    to {
        transform: rotate(0deg);
    }
}
@keyframes scale {
    from {
        transform: scaleY(2);
    }
    to {
        transform: scaleY(4);
    }
}
図3 ボタンにマウスポインタを重ねると左右の要素がくるくる回る
図3 ボタンにマウスポインタを重ねると左右の要素がくるくる回る
コード3 ボタンにマウスポインタが重なったとき周囲を回す
html {
    background-color: steelblue;
}
.container {
    margin: 150px auto;
    text-align: center;
    background-color: steelblue;
}
.circle {
    background-color: steelblue;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    display: inline-block;
    overflow: hidden;
    cursor: pointer;
    opacity: 0.99;
    transition: 1s ease-in-out;
}
.spinner {
    background-color: #efefef;
    height: 50px;
    margin-top: 75px;
    animation: anti-clockwise 1s ease-in-out;
    transform: scaleY(2);
}
.circle:hover .label {
    background-color: lightsteelblue;
    transition: 0.3s ease-in-out;
}
.circle:hover .label p {
    color: white;
    transition: 0.3s ease-in-out;
}
.circle:hover .spinner {
    filter: blur(5px);
    animation: clockwise 1s cubic-bezier(1, 0.22, 1, 0.92),
        scale 2s 1s ease-in-out;
}
@keyframes clockwise {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(1080deg);
    }
}
@keyframes anti-clockwise {
    from {
        transform: rotate(1080deg);
    }
    to {
        transform: rotate(0deg);
    }
}
@keyframes scale {
    from {
        transform: scaleY(2);
    }
    to {
        transform: scaleY(4);
    }
}
.circle:hover {
    background-color: white;
    transition: 1s ease-in-out 0.8s;
}
.label {
    background-color: cornflowerblue;
    height: 190px;
    width: 190px;
    position: relative;
    margin: -120px auto;
    border-radius: 50%;
    transition: 0.3s ease-in-out;
}
.label p {
    text-align: center;
    margin: 40% auto;
    display: inline-block;
    font-family: 'Raleway', sans-serif;
    font-weight: 900;
    font-size: 24pt;
    transition: 0.3s ease-in-out;
}

cubic-bezier()関数とopacityプロパティの役割

cubic-bezier()関数について、補っておく。この関数は4つの引数でタイミング関数を定める。xy座標平面で始点が(0, 0)、終点は(1, 1)として、ベジエ曲線の各コントロールポイントのxy座標値を、つぎのようにcubic-bezier()関数に渡す。たとえば、デフォルトの関数キーワードeaseは、cubic-bezier(0.25, 0.1, 0.25, 1.0)を表す。

cubic-bezier(x1, y1, x2, y2)

Cubic Bezier Generatorcubic-bezier()関数の4つの引数値を入力すると、値の変わり方がグラフで示される。前掲コード3で用いたcubic-bezier(1, 0.22, 1, 0.92)を試すと、つぎの図4のようにease-inにもっとめりはりを利かせた曲線になる。

図4 ⁠Cubic Bezier Generator」で描いたcubic-bezier(1, 0.22, 1, 0.92)のグラフ
図4 「Cubic Bezier Generator」で描いたcubic-bezier(1, 0.22, 1, 0.92)のグラフ

もうひとつ、ボタンの大もとの要素(class属性"circle")opacityプロパティをなぜ加えたのか、疑問に思われたかもしれない。つぎのように、このプロパティを与えないと、実はボタンの左右の要素のアニメーションが、マウスポインタを重ねたとき円形の外側にはみ出してしまう図5。そこで、opacityプロパティを不透明(1)に近い数値(0.99)とした。

.circle {

    /* opacity: 0.99; */

}
図5 左右の要素が円形の外にはみ出す
図5 左右の要素が円形の外にはみ出す

おすすめ記事

記事・ニュース一覧