akb428の技術メモ

cssとかJavaScriptとか。akbは'AK'imotoの'B'logの略です。akb48は全く関係ありません。すみません。

矩形の辺をtransitionでアニメーションさせる

矩形のメニューをhoverすると、周りのラインが伸縮するアニメーションがかっこ良かったので、真似してみました。

複雑なラインのアニメーションだとSVGを使うのが良いかもしれませんが、 単純にこの手もあったかぁと思ったので、 真似してみました。

作るものはこんなの。↓

htmlで矩形のラインを表現するとしたら、borderを使いますが、 ここでは各辺のラインをそれぞれアニメーションさせたいので、 幅1pxのdivを各辺に配置し、色はbackground-colorで表現しています。

<div class="rect">
    <div class="t"></div>
    <div class="r"></div>
    <div class="b"></div>
    <div class="l"></div>
</div>

CSSのpositionでそれぞれ位置に設置します。 横幅や高さなど使い回す部分はsassの変数に入れます。

$w: 200px;
$h: 200px;
$lineW: 1px;
$lineColor: #fff;

.rect {
    width: $w;
    height: $h;
    position: relative;
    margin: 100px auto;
  
    .l{
        position: absolute;
        width: $lineW;
        height: $h;
        background-color: $lineColor;
        left: 0;
        top: 0;
    }
    
    .t{
        position: absolute;
        width: $w;
        height: $lineW;
        background: $lineColor;
        left: 0;
        top: 0;
    }
    
    .r{
        position: absolute;
        width: $lineW;
        height: $h;
        background-color: $lineColor;
        top: 0;
        right: 0;
    }
    
    .b{
        position: absolute;
        width: $w;
        height: $lineW;
        background-color: $lineColor;
        bottom: 0;
        left: 0;
     }

これで、矩形ができました。 次に書く辺をhoverしたら線を伸縮させたいので、 上記のそれぞれの辺にtransitionを記述します。 左と右の辺はheightが伸縮して、上と下の辺はwidthが伸縮します。

.l{
    position: absolute;
    width: $lineW;
    height: $h;
    background-color: $lineColor;
    left: 0;
    top: 0;
    -webkit-transition: height .7s ease-out 0, top .7s ease-out 0;
    -moz-transition: height .7s ease-out 0, top .7s ease-out 0;
    -ms-transition: height .7s ease-out 0, top .7s ease-out 0;
    transition: height .7s ease-out 0, top .7s ease-out 0;
}

.t{
    position: absolute;
    width: $w;
    height: $lineW;
    background: $lineColor;
    left: 0;
    top: 0;
    -webkit-transition: width .7s ease-out 0;
    -moz-transition: width .7s ease-out 0;
    -ms-transition: width .7s ease-out 0;
    transition: width .7s ease-out 0;
}

.r{
    position: absolute;
    width: $lineW;
    height: $h;
    background-color: $lineColor;
    top: 0;
    right: 0;
    -webkit-transition: height .7s ease-out 0;
    -moz-transition: height .7s ease-out 0;
    -ms-transition: height .7s ease-out 0;
    transition: height .7s ease-out 0;
}

.b{
    position: absolute;
    width: $w;
    height: $lineW;
    background-color: $lineColor;
    bottom: 0;
    left: 0;
    -webkit-transition: width .7s ease-out 0, left .7s ease-out 0;
    -moz-transition: width .7s ease-out 0, left .7s ease-out 0;
    -ms-transition: width .7s ease-out 0, left .7s ease-out 0;
    transition: width .7s ease-out 0, left .7s ease-out 0;
}

ここで、少しポイントなのはleftとbottmのdivはtransionのプロパティが2つ設定している点。 基本的に、各辺の始点が左上なので、上記の2つの辺はそのまま伸縮すると、 方向が他の辺と違う微妙なアニメーションになります。

なので、上記の二辺は伸縮と同時にpositionを移動させることで、 他の辺と統一的な伸縮アニメーションにすることができます。

最後にhoverしたときの値を設定します。

&:hover > .t, &:hover >.b{
    width: 0;
}
&:hover >.b{
    left: $w;        
}
&:hover > .r, &:hover > .l{
    height: 0;        
}
&:hover > .l{
    top: $h;
}

先ほど書いたように、leftとbottomだけ、positionの値も変えています。 これで、hoverすると伸縮するアニメーションができました。 UIなどで使えそうですね。