Created
October 25, 2020 09:01
-
-
Save kazuooooo/09be220c12e834d82d049d261e6eba0b to your computer and use it in GitHub Desktop.
Simple carousel implementation Vue3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="container"> | |
<!-- ページをクリッピングするコンテナ --> | |
<div class="clipping-container"> | |
<!-- ページ全体、このleftをtransitionでスライドさせてページを動かす --> | |
<div class="pages" :style="{left: currentLeft}"> | |
<div class="page"> | |
1 | |
</div> | |
<div class="page"> | |
2 | |
</div> | |
<div class="page"> | |
3 | |
</div> | |
</div> | |
</div> | |
<!-- ページを表現するドット --> | |
<div class="dots"> | |
<!-- 現在のページはdot-currentクラスが当たる --> | |
<span | |
v-for="index in totalPage" | |
:class="{ dot: true, 'dot-current': isCurrentPage(index)}" | |
:key="index"> | |
</span> | |
</div> | |
<div> | |
<button @click="backwardPage">←</button> | |
<button @click="forwardPage">→</button> | |
</div> | |
</div> | |
</template> | |
<script lang="ts"> | |
import { defineComponent } from 'vue'; | |
export default defineComponent({ | |
name: 'HelloWorld', | |
data() { | |
return { | |
currentPage: 1, // 現在のページ | |
totalPage: 3, // ページの全数 | |
pageWidth: 200 // 1ページの幅 | |
} | |
}, | |
methods: { | |
// ページを1つ進める | |
forwardPage() { | |
// 最後のページの場合return | |
if(this.currentPage === this.totalPage){ | |
return | |
} | |
this.currentPage += 1 | |
}, | |
// ページを1つ戻す | |
backwardPage() { | |
// 最初のページの場合return | |
if(this.currentPage === 1){ | |
return | |
} | |
this.currentPage -= 1 | |
}, | |
// 現在のページをpositionに変換 | |
pageToPosition(): number { | |
return - this.pageWidth * (this.currentPage - 1) | |
}, | |
isCurrentPage(page: number) { | |
return this.currentPage === page | |
} | |
}, | |
computed: { | |
// 現在のpositionからleftに変換 | |
currentLeft(): string { | |
return String(this.pageToPosition()) + 'px' | |
} | |
} | |
}); | |
</script> | |
<style scoped> | |
.clipping-container { | |
clip-path: inset(0); | |
position: relative; | |
height: 200px; | |
width: 200px; | |
display: inline-block; | |
} | |
.pages { | |
display: flex; | |
/* ここにtransitionをつけることでpagesのleftを変更した場合にアニメーションさせることができる */ | |
transition: left 0.5s ease; | |
position: absolute; | |
left: 0; | |
} | |
.page { | |
width: 200px; | |
height: 200px; | |
background-color: aqua; | |
border: 1px solid white; | |
box-sizing: border-box; | |
} | |
.dots { | |
width: 30px; | |
display: flex; | |
justify-content: space-between; | |
margin: auto; | |
margin-bottom: 16px; | |
} | |
.dot { | |
height: 8px; | |
width: 8px; | |
background-color: #bbb; | |
border-radius: 50%; | |
display: inline-block; | |
} | |
.dot-current { | |
background-color: skyblue; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works like this😎