Vueのアニメーションで実装方法を検索すると、「transition」がよく出てくるかと思います。
この「transition」もとても便利なのですが、
コンポーネントが表示・非表示になる時以外でも要素にアニメーションをつけたかったので、
CSSとVueを使って実装してみました。
今回はよく見かけるカルーセルの一種で、
次の画像がちら見えしてるパターンを作成した方法を紹介したいと思います。
↓こんな感じの!
transform、transition-durationを使ってこんなに簡単に!
動かしたい要素に対して
translateとtransition-durationを指定することで簡単にアニメーションを実装することが出来ます。
App.vue
<template>
<div id="app">
<div class="sample">
<div class="sample__wrap">
//スライドさせたい要素のstyleにtransformを指定し、位置が動的に変わるように設定する(${position}pxの部分)
<ul
class="sample__list"
:style="{ transform: `translate(${position}px, 0)` }"
>
<li class="sample__item sample__item--pink">1</li>
<li class="sample__item sample__item--green">2</li>
<li class="sample__item sample__item--orange">3</li>
<li class="sample__item sample__item--blue">4</li>
<li class="sample__item sample__item--yellow">5</li>
<li class="sample__item sample__item--red">6</li>
</ul>
</div>
<div
class="sample__btn sample__btn--prev"
@click="moveContainer('left');"
:class="{ isDisabled: this.rightEnd }"
></div>
<div
class="sample__btn sample__btn--next"
@click="moveContainer('right');"
:class="{ isDisabled: this.leftEnd }"
></div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
itemWidth: 200,
position: 0,
leftEnd: true,
rightEnd: false
};
},
methods: {
moveContainer(turn) {
if (turn === "left") {
if (this.position < -(this.itemWidth * 4)) {
return;
}
this.position = this.position - this.itemWidth;
} else {
if (this.position === 0) {
return;
}
this.position = this.position + this.itemWidth;
}
this.leftEnd = this.position === 0 ? true : false;
this.rightEnd = this.position < -(this.itemWidth * 4) ? true : false;
}
}
};
</script>
<style lang="scss">
.sample {
position: relative;
margin: 100px auto;
width: 300px;
&__wrap {
overflow: hidden;
border: 5px solid #848484;
}
&__list {
//translateの値が変化した時に、
//ここのtransition-durationの指定でアニメーションしながら要素が動く
transition-duration: 0.8s;
margin: 0;
padding: 0;
display: flex;
width: 1200px;
}
&__item {
list-style: none;
width: 200px;
height: 200px;
line-height: 200px;
color: #fff;
font-size: 50px;
font-weight: bold;
text-align: center;
&--pink {
background: #ff69b4;
}
&--green {
background: #3cb371;
}
&--orange {
background: #ffa500;
}
&--blue {
background: #6495ed;
}
&--yellow {
background: #ffd700;
}
&--red {
background: #ff6347;
}
}
&__btn {
position: absolute;
width: 40px;
height: 40px;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
&:hover {
opacity: 0.8;
}
&:before {
position: absolute;
top: 0;
bottom: 0;
left: 0;
margin: auto;
content: "";
vertical-align: middle;
}
&--prev {
bottom: 80px;
left: -60px;
&:before {
left: 13px;
width: 14px;
height: 14px;
border-bottom: 4px solid #fff;
border-left: 4px solid #fff;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
}
&--next {
bottom: 80px;
right: -60px;
&:before {
left: 9px;
width: 14px;
height: 14px;
border-top: 4px solid #fff;
border-right: 4px solid #fff;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
}
}
}
.isDisabled {
opacity: 0.2;
&:hover {
opacity: 0.2;
}
}
</style>
translateの値を動的にする事でユーザーがクリックしたら、何か表示が変わったら、などなど色んな応用ができます。
まとめ
Vueのアニメーションで検索すると、「transition」の記事ばかりがでて、やりたいことが出来なかったりしましたが、
CSSを使う事でJQueryで実装していたようなUIも実装できるようになります。
(「transition」で実装できる箇所は「transition」を使うべきですが)
CSSのアニメーションも大分充実してきたので、うまくVue.jsと合わせて使っていきたいですね。