Vuejs 2.5 example Eva con skewx
by jpeter06
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.0/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="main">
<div id="cabecera">TITULO</div>
<p-menu></p-menu>
<div id="pageCont">
<transition :name="transitionName" >
<keep-alive :max="2">
<component v-bind:is="page"></component>
</keep-alive>
</transition>
</div>
</div>
<template id="pMenu">
<div class="menu">
<ul>
<li v-bind:class="[page==item ?'focused':'']" v-for="item in items" v-on:click="click(item)">
{{item}}
</li>
</ul>
</div>
</template>
<!-- PAGES -->
<template id="page1">
<div class="page page1" style="background:#eeeeee">
<div id="list-demo">
<button v-on:click="add">Add</button>
<button v-on:click="remove">Remove</button>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">autoPage</label>
<transition-group name="list-complete" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-complete-item" @click="clicked(item)"
v-bind:class="{ first: item === items[0] }">
{{ item }}
<transition name="pageST">
<div v-if="item === items[0]"style="color:#ddd">
texto la page: {{ item }}
</div>
</transition>
</span>
</transition-group>
<div id="subpageCont">
<transition :name="transitionName" >
<keep-alive :max="2">
<component v-bind:is="page"></component>
</keep-alive>
</transition>
</div>
</div>
</template>
<template id="page2">
<div class="page page2" style="background:#eeeeee">
Page2
...
CSS
html, body ,#main
{
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
background:#eee;
font-family:Arial;
}
#main{
display:flex; flex-direction:column;
}
#cabecera{ flex-grow:0;height:40px;text-align:center;
color:white; font-size:30px; background:#333334;
box-shadow: 1px 6px 10px 0px rgba(0,0,0,0.44); }
.menu{ flex-grow:0}
#pageCont{flex-grow:1;position:relative;border: 10px solid transparent;}
.page{
width:100%;height:100%;
position: absolute;top:0px;left:0px;
box-shadow: 1px 6px 13px 0px rgba(0,0,0,0.44);
box-sizing: border-box;
display: block;
padding:12px;
text-align:center;
transition: 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
background-clip: border-box;
transform-origin: top left;
}
@keyframes bounce-li{
0% {transform: skewX(7deg) translate(100%,0%);animation-timing-function: ease-out; }
33% {transform: skewX(6deg) translate(0%,0%); animation-timing-function: ease-in; }
55% {transform: skewX(-5deg); animation-timing-function: ease-out; }
68% {transform: skewX(4deg); animation-timing-function: ease-in; }
78% {transform: skewX(-3deg); animation-timing-function: ease-out; }
86% {transform: skewX(2deg); animation-timing-function: ease-in; }
94%{transform: skewX(1deg); animation-timing-function: ease-out; }
100%{transform: skewX(0deg); animation-timing-function: ease-in; }
}
@keyframes bounce-lo{
0% {transform: skewX(7deg) translate(0%,0%);animation-timing-function: ease-out; }
33% {transform: skewX(6deg) translate(calc(-100% - 40px),0%); animation-timing-function: ease-in; }
100%{transform: skewX(0deg) translate(calc(-100% - 40px),0%); animation-timing-function: ease-in; }
}
@keyframes bounce-ri{
0% {transform: skewX(-7deg) translate(-100%,0%);animation-timing-function: ease-out; }
33% {transform: skewX(-6deg) translate(0%,0%); animation-timing-function: ease-in; }
55% {transform: skewX(5deg);...
JavaScript
///////// pMenu //////////
var pMenu = Vue.extend({
template: '#pMenu',
data:function(){
return {
page:'page1',
items:['page1',"page2",'page3']
}
},
methods:{
click:function(item){
var isR=this.items.indexOf(item)>this.items.indexOf(this.page);
this.page=item;
vv.transitionName=isR?'pageL':'pageR';
vv.page=item;
},
isFocused:function(item){
return item==this.page?'focused':''
}
}
})
Vue.component('p-menu', pMenu);
/////////// PAGE 1 ///////////////
Vue.component('page1', { template: '#page1',
data:function(){
return {
transitionName:'pageS',
subpage:'subpage1',
checked:false,
page:"",
items:['page1','page2','page3','page4'],
nextNum: 10
}
},
methods: {
randomIndex: function () {
return Math.floor(Math.random() * this.items.length)
},
add: function () {
this.items.splice(this.randomIndex(), 0, "page"+this.nextNum++)
},
remove: function () {
this.items.splice(this.randomIndex(), 1)
},
clicked(item){
const index=this.items.indexOf(item);
if(index==0){
if(this.page==item)
this.page="pageEmpty";
else
this.page=item;
}else{
this.items.splice(index, 1);
this.items.splice(0, 0, item);
this.page="pageEmpty";
if(this.checked)
this.page=item;
}
},
}});
/////////// PAGE 2 ///////////////
Vue.component('page2', { template: '#page2'});
/////////// PAGE 3 ///////////////
Vue.component('page3', { template: '#page3'});
/////////// PAGE 3 ///////////////
Vue.component('page4', { template: '#page4'});
/////////// PAGE 3 ///////////////
Vue.component('pageEmpty', { template: '#pageEmpty'});
/////////// PAGE 3 ///////////////
Vue.component('innertext', { template: '#innertext'});
///////////// MAIN //////////////
var vv=new Vue({
el: '#main',
data: {
page:'page1',
...