Vue.config.devtools = false;
Vue.config.productionTip = false;
Vue.component('rotatingButton', {
template: `
<div>
<div class="flipper">
<div
class="items"
:style="{ transform: \`rotateX(\${rotation}deg)\` }">
<div v-for="item in items"
:key="item.ID"
:class="[item.value, 'item']"
v-text="item.value" />
</div>
</div>
<input type="range" v-model="range" min="0" max="1500">
<div class="color-range">
<div v-for="item in items"
:style="{width: \`\${(item.max - item.min)/15}%\`,
left: \`\${item.min/15}%\`,
backgroundColor: item.barColor }"
/>
</div>
</div>`,
data: () => ({
range: 100,
items: [{
ID: 0,
min: 0,
max: 500,
value: "first",
barColor: '#369'
}, {
ID: 1,
min: 500,
max: 700,
value: "second",
barColor: "#900"
}, {
ID: 2,
min: 700,
max: 1500,
value: "third",
barColor: "#393"
}
],
}),
computed: {
rotation() {
return this.range < this.items[0].max ? 0 : (this.range < this.items[1].max ? 90 : 180);
}
}
})
new Vue({
el: '#app'
});
#app {
text-align: center;
margin-top: 60px;
}
.flipper {
perspective: 210px;
height: 30px;
width: 150px;
line-height: 30px;
margin: 15px auto;
}
.items {
height: 100%;
perspective-origin: 150% 150%;
transform-style: preserve-3d;
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.item {
display: block;
position: absolute;
width: 100%;
height: 100%;
border: 1px solid rgba(33,66,99,.33);
font: 25px monospace;
color: rgba(33,66,99,.33);
background-color: white;
}
.first { transform: translateZ(15px); }
.second { transform: rotateX(-90deg) translateZ(15px); }
.third { transform: rotateX(180deg) translateZ(15px); }
.fourth { transform: rotateX(90deg) translateZ(15px); }
.color-range {
padding: 0 1rem;
position: relative;
height: 4px;
}
input[type="range"] {width: 100%; margin: 0;}
.color-range > div {
position: absolute;
top: 0;
height: 100%;
opacity: .65;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<rotating-button />
</div>