JSFiddle - React, Tailwind, and code Playground
by Joulence
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<div id="app">
<v-slider :slides-data="slidesData"></v-slider>
</div>
CSS
body {
margin: 0;
}
.slider {
height: 100vh;
overflow: hidden;
position: relative;
}
.slide {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
transition: transform 0.2s ease-in;
position: absolute;
color: white;
font: bold 48px monospace;
}
.slider > button {
position: absolute;
}
button.up,
button.down {
left: 50%;
transform: translateX(-50%);
}
button.up { top: 25px; }
button.down { bottom: 25px; }
button.left,
button.right {
top: 50%;
transform: translateY(-50%);
}
button.left { left: 25px; }
button.right { right: 25px; }
.down-enter {
transform: translateY(100%);
}
.down-enter-to,
.down-leave {
transform: translateY(0);
}
.down-leave-to {
transform: translateY(-100%);
}
.up-enter {
transform: translateY(-100%);
}
.up-enter-to,
.up-leave {
transform: translateY(0);
}
.up-leave-to {
transform: translateY(100%);
}
.left-enter {
transform: translateX(-100%);
}
.left-enter-to,
.left-leave {
transform: translateX(0);
}
.left-leave-to {
transform: translateX(100%);
}
.right-enter {
transform: translateX(100%);
}
.right-enter-to,
.right-leave {
transform: translateX(0);
}
.right-leave-to {
transform: translateX(-100%);
}
JavaScript
Vue.component('v-slider', {
template: `
<div class="slider">
<transition :name="animation">
<div
:key="\`\${iRow}.\${iCol}\`"
:style="{ background: slide.color }"
class="slide"
>{{ slide.text }}</div>
</transition>
<button
v-for="{ name, rowChange = 0, colChange = 0 } in buttons"
v-show="slidesData[iRow + rowChange]?.[iCol + colChange]"
:class="name"
@click="onClick(name, rowChange, colChange)"
>{{ name }}</button>
</div>`,
props: [ 'slidesData' ],
data: () => ({
animation: null,
iRow: 0,
iCol: 0,
buttons: [
{ name: 'up', rowChange: -1, },
{ name: 'right', colChange: 1, },
{ name: 'down', rowChange: 1, },
{ name: 'left', colChange: -1, },
],
}),
computed: {
slide() {
return this.slidesData[this.iRow][this.iCol];
},
},
methods: {
onClick(animation, rowChange, colChange) {
this.animation = animation;
this.iRow += rowChange;
this.iCol += colChange;
},
},
});
new Vue({
el: '#app',
data: {
slidesData: [
[
{ text: 'hello, world!!', color: 'black' },
{ text: 69, color: 'silver' },
],
[
{ text: 'fuck the world', color: 'red' },
{ text: 187, color: 'blue' },
{ text: '!!!', color: 'brown' },
{ text: '???', color: 'magenta' },
],
[
{ text: 'fuck everything', color: 'green' },
{ text: 666, color: 'aqua' },
{ text: '@@@', color: 'orange' },
],
],
},
});