Vuejs 2.5 sink animation mult

by jpeter06

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="main">
  <p-menu></p-menu>
  <div style="display:flex;flex-grow:1;position:relative; width:100%; height:100%">
    <div class="pageContExt">
      <div class="pageCont"  v-bind:class="{ active: isActive }">
        <transition :name="transitionName" >
          <component v-bind:is="page_1"></component>
        </transition>
      </div>  
    </div>
      <div class="pageContExt">
      <div class="pageCont"  v-bind:class="{ active: isActive }">
        <transition :name="transitionName" >
          <component v-bind:is="page_2"></component>
        </transition>
      </div>  
    </div>
  </div>
    <div style="display:flex;flex-grow:1;position:relative; width:100%; height:100%">
    <div class="pageContExt">
      <div class="pageCont"  v-bind:class="{ active: isActive }">
        <transition :name="transitionName" >
          <component v-bind:is="page_3"></component>
        </transition>
      </div>  
    </div>
      <div class="pageContExt">
      <div class="pageCont"  v-bind:class="{ active: isActive }">
        <transition :name="transitionName" >
          <component v-bind:is="page_4"></component>
        </transition>
      </div>  
    </div>
  </div>
</div>

<template id="pMenu">
  <div class="menu" v-bind:class="{ active: isActive }">
    <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="page2">
  <div class="page page2" >
   Page2
  </div>
</template>
 
<template id="page1">
  <div class="page page1" >
   Page1
   <innertext/>
  </div>
</template>
 
<template id="page3">
  <div class="page page3" style="background:orange;color:white !important">
  Page3
  </div>
</template>

<template id="page4">
  <div class="page page4" style="background:#38d838;color:white !important">
  Page4
 ...

CSS

html, body ,#main
{
    height: 100%;
    width: 100%;
    margin: 0px;
    padding: 0px;
    overflow: hidden;
    background:#fff;
    font-family:Arial;
    color:#888;
}

#main{
  display:flex; flex-direction:column;
  --animation-speed: 1.4s;
  --scale: 0.92;
}

.pageContExt{flex-grow:1;position:relative;overflow: hidden;
          border: 10px solid transparent;display:flex;}
.pageCont{flex-grow:1;position:relative;overflow: hidden;
          }
.pageCont.active{border: 1px inset rgba(250,250,250,0.6); }
.pageCont::after {
  box-shadow: 0 0px 15px rgba(0,0,0,0.3) inset;
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  content:"";
  pointer-events: none;
  background:rgba(0,0,0,0.03);
  /*border: 1px inset rgba(250,250,250,0.6);*/
}

/* Transition to showing the bigger shadow on hover */
.pageCont.active::after {
  animation: show-hole calc(var(--animation-speed) );
}

@keyframes show-hole{
  0%  {opacity:0 ;animation-timing-function: ease-out;  }
  33%  { opacity: 1;animation-timing-function: ease-out;  }
  70%  { opacity: 1;animation-timing-function: ease-in;  }
 100% { opacity: 0.2; animation-timing-function: ease-in; }
}

.page{
   will-change: transform;
   width:100%;height:100%;
   position: absolute;top:0px;left:0px;
   box-sizing: border-box;
   display: block;
   padding:12px;
   text-align:center;
   background-clip: border-box;
   overflow-y:auto;
   transform-origin:center;
   line-height:1.2;
}
.page::first-line{font-weight:bold; font-size:26px;}

@keyframes bounce-li{
  0%  {transform:   translate(0%,calc( 100% + 40px)) scale(var(--scale),var(--scale));animation-timing-function: ease-out;  }
  33%  {transform:   translate(0%,calc( 100% + 40px)) scale(var(--scale),var(--scale));animation-timing-function: ease-out;  }
  70%  {transform:   translate(0%,0%) scale(var(--scale),var(--scale));animation-timing-function: ease-in;  }
 100% {transform:    translate(0%,0%); animation-timing-function: ease-in;...

JavaScript

///////// pMenu //////////
var pMenu = Vue.extend({
  template: '#pMenu',
  data:function(){
  	return {
    		page:'page1',
        isActive:false,
        timeoutId:null,
    		items:['page1','page2','page3','page4']
        }
  },
  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_4=this.getRandom(vv.page_4);
      vv.page_1=this.getRandom(vv.page_1);
      vv.page_2=this.getRandom(vv.page_2);
      vv.page_3=this.getRandom(vv.page_3);
      vv.page=item;
    },
 		isFocused:function(item){
    	return item==this.page?'focused':''
    },getRandom:function(item){
      var pos=Math.floor(Math.random()*this.items.length)%this.items.length;
    	var next= this.items[pos];
      if(next==item)
      	next= this.items[(pos+1)%(this.items.length)];
       return next;
    }   
  },
  watch: {
    page: function(newValue) {
    /*
      clearTimeout(this.timeoutId);
      this.isActive=true;
      var self=this;
      this.timeoutId = setTimeout(function(){ self.isActive=false; }, 1000);
      */
    }
  }
})
Vue.component('p-menu', pMenu);

/////////// PAGE 1 ///////////////
Vue.component('page1', {  template: '#page1',
  data:function(){
  	return {
    		transitionName:'pageS',
    		subpage:'subpage1',
        checked:false,
        page:"",
        page_1:"page1",
        page_2:"page2",
        page_3:"page3",
        page_4:"page4",
    		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)
       ...