Created
March 15, 2023 15:56
-
-
Save AnoRebel/ba52a077b7b3bb0efe7748ab6e40c169 to your computer and use it in GitHub Desktop.
Vue 3 Drawers
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> | |
<section v-if="enabled"> | |
<aside class="sidebar" :style="style" ref="element"> | |
<slot></slot> | |
</aside> | |
<div class="overlay" ref="overlay"></div> | |
</section> | |
</template> | |
<script setup> | |
import { ref, computed, onMounted, onBeforeUnmount } from "vue"; | |
const props = defineProps({ | |
direction: { | |
type: String, | |
required: true, | |
}, | |
exist: { | |
type: Boolean, | |
required: true, | |
}, | |
}); | |
const element = ref(null); | |
const overlay = ref(null); | |
const config = reactive({ | |
"auto_speed" : '0.3s', | |
"manual_speed" : '0.03s', | |
"threshold" : 20, | |
"startTime" : null, | |
"startPos" : null, | |
"translate" : null, | |
"active" : false, | |
"visible" : true, | |
}); | |
const enabled = computed(() => { | |
if(props.exist == true){ | |
return true; | |
} | |
return false; | |
}); | |
const style = computed(() => { | |
if(props.direction == 'right'){ | |
return 'transform:translate3d(100%,0,0);right:0;'; | |
} | |
return 'transform:translate3d(-100%,0,0);left:0;'; | |
}); | |
onMounted(() =>{ | |
document.addEventListener('touchstart', e => handleStart(e)); | |
document.addEventListener('touchmove', e => handleMove(e)); | |
document.addEventListener('touchend', e => handleEnd(e)); | |
document.addEventListener('touchcancel', e => handleEnd(e)); | |
window.addEventListener('resize', e => setVisibality(e), true); | |
overlay.value.addEventListener('transitionend', e => handleZindex(e),false); | |
overlay.value.addEventListener('click', () => close(),false); | |
setVisibality(); | |
}); | |
const setVisibality = () => { | |
if(element.value.offsetWidth == 0){ | |
config.visible = false; | |
} else { | |
config.visible = true; | |
} | |
}; | |
const handleStart = e => { | |
config.startTime = new Date().getTime(); | |
config.startPos = e.targetTouches[0].pageX; | |
element.value.style.transitionDuration = config.manual_speed; | |
}; | |
const handleMove = e => { | |
let gesture = gesture(e); | |
let valid = validate(props.direction, gesture); | |
if (valid) { | |
let percent = percentage(props.direction, gesture); | |
if (props.direction == 'left'){ | |
config.translate = (e.touches[0].pageX - element.value.offsetWidth); | |
if (config.translate < 0) { | |
element.value.style.transform = 'translate3d('+ config.translate +'px,0,0)'; | |
} else { | |
open(); | |
} | |
} else { | |
config.translate = -(screen.width - element.value.offsetWidth - e.touches[0].pageX); | |
if (config.translate > 0) { | |
element.value.style.transform = 'translate3d('+ config.translate +'px,0,0)'; | |
} else { | |
open(); | |
} | |
} | |
overlayOpacity(percent/100); | |
} | |
}; | |
const handleEnd = e => { | |
let speed = speed(e); | |
let gesture = gesture(e); | |
let valid = validate(props.direction, gesture); | |
if (valid) { | |
if (speed > 0.6) { | |
if(!config.active){ | |
open(); | |
} else { | |
close(); | |
} | |
} else { | |
if (element.value.offsetWidth/2 > Math.abs(config.translate)) { | |
open(); | |
} else { | |
close(); | |
} | |
} | |
} | |
}; | |
const handleZindex = () => { | |
let opacity = window.getComputedStyle(overlay.value).getPropertyValue('opacity'); | |
if (opacity <= 0) { | |
overlay.value.style.zIndex = -999; | |
} | |
}; | |
const validate = (direction, gesture) => { | |
if (direction == 'left') { | |
if((config.active && gesture == 'swiperight') || (!config.active && (gesture == 'swipeleft' || config.startPos > config.threshold))){ | |
return false; | |
} | |
} else { | |
if ((config.active && gesture == 'swipeleft') || (!config.active && (gesture == 'swiperight' || config.startPos < (screen.width - config.threshold)))){ | |
return false; | |
} | |
} | |
if ((document.querySelector('.sidebar.active') && !config.active) || !config.visible) { | |
return false; | |
} | |
return true; | |
}; | |
const overlayOpacity = (opacity) => { | |
overlay.value.style.opacity = opacity; | |
if (opacity > 0) { | |
overlay.value.style.zIndex = 999; | |
} | |
}; | |
const gesture = e => { | |
let directions = [ | |
'swipeleft', | |
'swiperight', | |
]; | |
let currentPos = e.changedTouches[0].pageX; | |
if ((config.startPos - currentPos) < 0) { | |
return directions[1]; | |
} else { | |
return directions[0]; | |
} | |
}; | |
const open = () => { | |
config.translate = 0; | |
element.value.style.transform = 'translate3d(' + config.translate + ', 0, 0)'; | |
element.value.style.transitionDuration = config.auto_speed; | |
overlayOpacity(1); | |
lock(document.querySelector('html')); | |
lock(document.querySelector('body')); | |
element.value.classList.add('active'); | |
config.active = true; | |
}; | |
const close = () => { | |
if(props.direction=='left'){ | |
config.translate = '-' + element.value.offsetWidth + 'px'; | |
}else{ | |
config.translate = element.value.offsetWidth + 'px'; | |
} | |
element.value.style.transform = 'translate3d('+config.translate+',0,0)'; | |
element.value.style.transitionDuration = config.auto_speed; | |
overlayOpacity(0); | |
unlock(document.querySelector('html')); | |
unlock(document.querySelector('body')); | |
element.value.classList.remove('active'); | |
config.active = false; | |
}; | |
const speed = e => { | |
let time = new Date().getTime() - config.startTime; | |
let startP = Math.abs(config.startPos); | |
let endP = Math.abs(e.changedTouches[0].pageX); | |
let distance = startP > endP ? (startP-endP) : (endP-startP); | |
return distance/time; | |
}; | |
const percentage = (direction, gesture) => { | |
let percentage = 0; | |
let test = []; | |
if(direction == 'left'){ | |
test = ['swipeleft','swiperight'] | |
}else{ | |
test = ['swiperight','swipeleft'] | |
} | |
if(config.active && gesture == test[0]){ | |
percentage = 100-Math.round(Math.abs(config.translate)/element.value.offsetWidth*100); | |
} | |
if(!config.active && gesture == test[1]){ | |
percentage = Math.round(100-Math.abs(config.translate)/element.value.offsetWidth*100); | |
} | |
if(percentage>100){ | |
percentage = 100; | |
} | |
if(percentage<0){ | |
percentage = 0; | |
} | |
return percentage; | |
}; | |
const lock = (element) => { | |
element.value.style.overflow = 'hidden'; | |
element.value.style.touchAction = 'none'; | |
}; | |
const unlock = (element) => { | |
element.value.style.removeProperty('overflow'); | |
element.value.style.removeProperty('touch-action'); | |
}; | |
onBeforeUnmount(() => { | |
document.removeEventListener('touchstart', e => handleStart(e)); | |
document.removeEventListener('touchmove', e => handleMove(e)); | |
document.removeEventListener('touchend', e => handleEnd(e)); | |
document.removeEventListener('touchcancel', e => handleEnd(e)); | |
window.removeEventListener('resize', e => setVisibality(e), true); | |
overlay.value.removeEventListener('transitionend', e => handleZindex(e),false); | |
overlay.value.removeEventListener('click', () => close(),false); | |
}); | |
</script> | |
<style lang="scss" scoped> | |
div.overlay{ | |
position:fixed; | |
z-index: -999; | |
left: 0px; | |
top:0px; | |
background:rgba(11, 10, 12, 0.35); | |
opacity: 0; | |
width: 100%; | |
height: 100%; | |
transition: opacity 0.3s ease; | |
} | |
aside.sidebar{ | |
z-index: 9999; | |
position: fixed; | |
will-change: transform; | |
height: 100%; | |
top: 0px; | |
transition:transform 0.3s ease; | |
background:#fff; | |
width: 300px; | |
overflow-y: auto; | |
overflow-x: hidden; | |
word-wrap: break-word; | |
} | |
</style> |
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> | |
<transition name="fade" mode="out-in"> | |
<div | |
:style="indexCls()" | |
@click="onMask" | |
v-if="$slots.default" | |
:class="{ mask }" | |
></div> | |
</transition> | |
<transition | |
:enter-active-class="alignInCls" | |
:leave-active-class="alignOutCls" | |
> | |
<div | |
key="content" | |
:class="{ closeable, [align.toLowerCase()]: true }" | |
v-if="$slots.default" | |
class="vue-simple-drawer cover" | |
:style="indexCls()" | |
> | |
<div @click.stop="close" v-if="closeable" class="close-btn"> | |
<div class="leftright"></div> | |
<div class="rightleft"></div> | |
</div> | |
<slot></slot> | |
</div> | |
</transition> | |
</div> | |
</template> | |
<script setup> | |
import { computed, provide, inject } from "vue"; | |
const props = defineProps({ | |
align: { | |
type: String, | |
default: "right", | |
validator: function(value) { | |
// The value must match one of these strings | |
return ["left", "up", "right", "down"].indexOf(value) !== -1; | |
} | |
}, | |
closeable: { | |
type: Boolean, | |
default: true | |
}, | |
mask: { | |
type: Boolean, | |
default: true | |
}, | |
maskClosable: { | |
type: Boolean, | |
default: false | |
}, | |
zIndex: { | |
type: Number, | |
default() { | |
return simpleDrawerIndex; | |
} | |
} | |
}); | |
const emit = defineEmits(["close"]); | |
provide("simpleDrawerIndex", computedIndex.value + 1); | |
const simpleDrawerIndex = inject("simpleDrawerIndex", 1000); | |
const close = () => emit("close"); | |
const onMask = () => { | |
if (props.maskClosable) close(); | |
}; | |
const indexCls = (offset = 0) => { | |
return { | |
zIndex: computedIndex.value + offset | |
}; | |
}; | |
const alignInCls = computed(() => { | |
return `animated bounceIn${props.align.toLowerCase()}`; | |
}); | |
const alignOutCls = computed(() => { | |
return `animated bounceOut${props.align.toLowerCase()}`; | |
}); | |
const alighCloseCls = computed(() => { | |
return `close-${props.align.toLowerCase()}`; | |
}); | |
const computedIndex = computed(() => { | |
return props.zIndex || simpleDrawerIndex; | |
}); | |
</script> | |
<style lang="scss"> | |
$--simple-drawer-softorange: #f4a259 !default; | |
$--simple-drawer-tomatored: #f25c66 !default; | |
$--simple-drawer-mediumblu: #1e272d !default; | |
$--simple-drawer-close-width: 28px !default; | |
$--simple-drawer-bg-color: #333333 !default; | |
$--simple-drawer-fg-color: white !default; | |
.vue-simple-drawer { | |
// default style | |
padding: 20px; | |
color: $--simple-drawer-fg-color; | |
background: $--simple-drawer-bg-color; | |
// common | |
position: fixed; | |
overflow: auto; | |
// top: 0; | |
// z-index: 99; | |
// bottom: 0; | |
&.closeable { | |
padding-top: 40px; | |
} | |
&.left { | |
left: 0; | |
top: 0; | |
bottom: 0; | |
} | |
&.right { | |
right: 0; | |
top: 0; | |
bottom: 0; | |
} | |
&.up { | |
top: 0; | |
left: 0; | |
right: 0; | |
} | |
&.down { | |
bottom: 0; | |
left: 0; | |
right: 0; | |
} | |
.close-btn { | |
// position: relative; | |
// margin: auto; | |
width: $--simple-drawer-close-width; | |
height: $--simple-drawer-close-width; | |
// margin-top: 100px; | |
// cursor: pointer; | |
position: absolute; | |
right: 0; | |
top: 20px; | |
// z-index: 100; | |
transform: translate(-50%, -50%); | |
color: currentColor; | |
font-size: 20px; | |
cursor: pointer; | |
user-select: none; | |
.leftright { | |
height: 4px; | |
width: $--simple-drawer-close-width; | |
position: absolute; | |
margin-top: calc($--simple-drawer-close-width/2); | |
background-color: $--simple-drawer-softorange; | |
border-radius: 2px; | |
transform: rotate(45deg); | |
transition: all 0.3s ease-in; | |
} | |
.rightleft { | |
height: 4px; | |
width: $--simple-drawer-close-width; | |
position: absolute; | |
margin-top: calc($--simple-drawer-close-width/2); | |
background-color: $--simple-drawer-softorange; | |
border-radius: 2px; | |
transform: rotate(-45deg); | |
transition: all 0.3s ease-in; | |
} | |
.close { | |
margin: 60px 0 0 5px; | |
position: absolute; | |
} | |
&:hover .leftright { | |
transform: rotate(-45deg); | |
background-color: $--simple-drawer-tomatored; | |
} | |
&:hover .rightleft { | |
transform: rotate(45deg); | |
background-color: $--simple-drawer-tomatored; | |
} | |
} | |
} | |
.mask { | |
position: fixed; | |
background: grey; | |
opacity: 0.5; | |
width: 100%; | |
left: 0; | |
top: 0; | |
height: 100%; | |
// &::before { | |
// content: ""; | |
// position: absolute; | |
// background: grey; | |
// opacity: 0.5; | |
// width: 100%; | |
// left: 0; | |
// top: 0; | |
// height: 100%; | |
// // z-index: 98; | |
// } | |
} | |
.animated { | |
-webkit-animation-duration: 1s; | |
animation-duration: 1s; | |
-webkit-animation-fill-mode: both; | |
animation-fill-mode: both; | |
} | |
// bounceInRight | |
@-webkit-keyframes bounceInRight { | |
from, | |
60%, | |
75%, | |
90%, | |
to { | |
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
} | |
from { | |
opacity: 0; | |
-webkit-transform: translate3d(3000px, 0, 0); | |
transform: translate3d(3000px, 0, 0); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translate3d(-25px, 0, 0); | |
transform: translate3d(-25px, 0, 0); | |
} | |
75% { | |
-webkit-transform: translate3d(10px, 0, 0); | |
transform: translate3d(10px, 0, 0); | |
} | |
90% { | |
-webkit-transform: translate3d(-5px, 0, 0); | |
transform: translate3d(-5px, 0, 0); | |
} | |
to { | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
@keyframes bounceInRight { | |
from, | |
60%, | |
75%, | |
90%, | |
to { | |
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
} | |
from { | |
opacity: 0; | |
-webkit-transform: translate3d(3000px, 0, 0); | |
transform: translate3d(3000px, 0, 0); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translate3d(-25px, 0, 0); | |
transform: translate3d(-25px, 0, 0); | |
} | |
75% { | |
-webkit-transform: translate3d(10px, 0, 0); | |
transform: translate3d(10px, 0, 0); | |
} | |
90% { | |
-webkit-transform: translate3d(-5px, 0, 0); | |
transform: translate3d(-5px, 0, 0); | |
} | |
to { | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
.bounceInright { | |
-webkit-animation-name: bounceInRight; | |
animation-name: bounceInRight; | |
} | |
// bounceOutLeft | |
@-webkit-keyframes bounceOutLeft { | |
20% { | |
opacity: 1; | |
-webkit-transform: translate3d(20px, 0, 0); | |
transform: translate3d(20px, 0, 0); | |
} | |
to { | |
opacity: 0; | |
-webkit-transform: translate3d(-2000px, 0, 0); | |
transform: translate3d(-2000px, 0, 0); | |
} | |
} | |
@keyframes bounceOutLeft { | |
20% { | |
opacity: 1; | |
-webkit-transform: translate3d(20px, 0, 0); | |
transform: translate3d(20px, 0, 0); | |
} | |
to { | |
opacity: 0; | |
-webkit-transform: translate3d(-2000px, 0, 0); | |
transform: translate3d(-2000px, 0, 0); | |
} | |
} | |
.bounceOutleft { | |
-webkit-animation-name: bounceOutLeft; | |
animation-name: bounceOutLeft; | |
} | |
// bounceInLeft | |
@-webkit-keyframes bounceInLeft { | |
from, | |
60%, | |
75%, | |
90%, | |
to { | |
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
} | |
0% { | |
opacity: 0; | |
-webkit-transform: translate3d(-3000px, 0, 0); | |
transform: translate3d(-3000px, 0, 0); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translate3d(25px, 0, 0); | |
transform: translate3d(25px, 0, 0); | |
} | |
75% { | |
-webkit-transform: translate3d(-10px, 0, 0); | |
transform: translate3d(-10px, 0, 0); | |
} | |
90% { | |
-webkit-transform: translate3d(5px, 0, 0); | |
transform: translate3d(5px, 0, 0); | |
} | |
to { | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
@keyframes bounceInLeft { | |
from, | |
60%, | |
75%, | |
90%, | |
to { | |
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
} | |
0% { | |
opacity: 0; | |
-webkit-transform: translate3d(-3000px, 0, 0); | |
transform: translate3d(-3000px, 0, 0); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translate3d(25px, 0, 0); | |
transform: translate3d(25px, 0, 0); | |
} | |
75% { | |
-webkit-transform: translate3d(-10px, 0, 0); | |
transform: translate3d(-10px, 0, 0); | |
} | |
90% { | |
-webkit-transform: translate3d(5px, 0, 0); | |
transform: translate3d(5px, 0, 0); | |
} | |
to { | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
.bounceInleft { | |
-webkit-animation-name: bounceInLeft; | |
animation-name: bounceInLeft; | |
} | |
// bounceOutRight | |
@-webkit-keyframes bounceOutRight { | |
20% { | |
opacity: 1; | |
-webkit-transform: translate3d(-20px, 0, 0); | |
transform: translate3d(-20px, 0, 0); | |
} | |
to { | |
opacity: 0; | |
-webkit-transform: translate3d(2000px, 0, 0); | |
transform: translate3d(2000px, 0, 0); | |
} | |
} | |
@keyframes bounceOutRight { | |
20% { | |
opacity: 1; | |
-webkit-transform: translate3d(-20px, 0, 0); | |
transform: translate3d(-20px, 0, 0); | |
} | |
to { | |
opacity: 0; | |
-webkit-transform: translate3d(2000px, 0, 0); | |
transform: translate3d(2000px, 0, 0); | |
} | |
} | |
.bounceOutright { | |
-webkit-animation-name: bounceOutRight; | |
animation-name: bounceOutRight; | |
} | |
@-webkit-keyframes bounceInDown { | |
from, | |
60%, | |
75%, | |
90%, | |
to { | |
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
} | |
0% { | |
opacity: 0; | |
-webkit-transform: translate3d(0, -3000px, 0); | |
transform: translate3d(0, -3000px, 0); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translate3d(0, 25px, 0); | |
transform: translate3d(0, 25px, 0); | |
} | |
75% { | |
-webkit-transform: translate3d(0, -10px, 0); | |
transform: translate3d(0, -10px, 0); | |
} | |
90% { | |
-webkit-transform: translate3d(0, 5px, 0); | |
transform: translate3d(0, 5px, 0); | |
} | |
to { | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
@keyframes bounceInDown { | |
from, | |
60%, | |
75%, | |
90%, | |
to { | |
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
} | |
0% { | |
opacity: 0; | |
-webkit-transform: translate3d(0, -3000px, 0); | |
transform: translate3d(0, -3000px, 0); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translate3d(0, 25px, 0); | |
transform: translate3d(0, 25px, 0); | |
} | |
75% { | |
-webkit-transform: translate3d(0, -10px, 0); | |
transform: translate3d(0, -10px, 0); | |
} | |
90% { | |
-webkit-transform: translate3d(0, 5px, 0); | |
transform: translate3d(0, 5px, 0); | |
} | |
to { | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
.bounceInup { | |
-webkit-animation-name: bounceInDown; | |
animation-name: bounceInDown; | |
} | |
@-webkit-keyframes bounceInUp { | |
from, | |
60%, | |
75%, | |
90%, | |
to { | |
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
} | |
from { | |
opacity: 0; | |
-webkit-transform: translate3d(0, 3000px, 0); | |
transform: translate3d(0, 3000px, 0); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translate3d(0, -20px, 0); | |
transform: translate3d(0, -20px, 0); | |
} | |
75% { | |
-webkit-transform: translate3d(0, 10px, 0); | |
transform: translate3d(0, 10px, 0); | |
} | |
90% { | |
-webkit-transform: translate3d(0, -5px, 0); | |
transform: translate3d(0, -5px, 0); | |
} | |
to { | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
@keyframes bounceInUp { | |
from, | |
60%, | |
75%, | |
90%, | |
to { | |
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); | |
} | |
from { | |
opacity: 0; | |
-webkit-transform: translate3d(0, 3000px, 0); | |
transform: translate3d(0, 3000px, 0); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translate3d(0, -20px, 0); | |
transform: translate3d(0, -20px, 0); | |
} | |
75% { | |
-webkit-transform: translate3d(0, 10px, 0); | |
transform: translate3d(0, 10px, 0); | |
} | |
90% { | |
-webkit-transform: translate3d(0, -5px, 0); | |
transform: translate3d(0, -5px, 0); | |
} | |
to { | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
.bounceIndown { | |
-webkit-animation-name: bounceInUp; | |
animation-name: bounceInUp; | |
} | |
@-webkit-keyframes bounceOutDown { | |
20% { | |
-webkit-transform: translate3d(0, 10px, 0); | |
transform: translate3d(0, 10px, 0); | |
} | |
40%, | |
45% { | |
opacity: 1; | |
-webkit-transform: translate3d(0, -20px, 0); | |
transform: translate3d(0, -20px, 0); | |
} | |
to { | |
opacity: 0; | |
-webkit-transform: translate3d(0, 2000px, 0); | |
transform: translate3d(0, 2000px, 0); | |
} | |
} | |
@keyframes bounceOutDown { | |
20% { | |
-webkit-transform: translate3d(0, 10px, 0); | |
transform: translate3d(0, 10px, 0); | |
} | |
40%, | |
45% { | |
opacity: 1; | |
-webkit-transform: translate3d(0, -20px, 0); | |
transform: translate3d(0, -20px, 0); | |
} | |
to { | |
opacity: 0; | |
-webkit-transform: translate3d(0, 2000px, 0); | |
transform: translate3d(0, 2000px, 0); | |
} | |
} | |
.bounceOutdown { | |
-webkit-animation-name: bounceOutDown; | |
animation-name: bounceOutDown; | |
} | |
@-webkit-keyframes bounceOutUp { | |
20% { | |
-webkit-transform: translate3d(0, -10px, 0); | |
transform: translate3d(0, -10px, 0); | |
} | |
40%, | |
45% { | |
opacity: 1; | |
-webkit-transform: translate3d(0, 20px, 0); | |
transform: translate3d(0, 20px, 0); | |
} | |
to { | |
opacity: 0; | |
-webkit-transform: translate3d(0, -2000px, 0); | |
transform: translate3d(0, -2000px, 0); | |
} | |
} | |
@keyframes bounceOutUp { | |
20% { | |
-webkit-transform: translate3d(0, -10px, 0); | |
transform: translate3d(0, -10px, 0); | |
} | |
40%, | |
45% { | |
opacity: 1; | |
-webkit-transform: translate3d(0, 20px, 0); | |
transform: translate3d(0, 20px, 0); | |
} | |
to { | |
opacity: 0; | |
-webkit-transform: translate3d(0, -2000px, 0); | |
transform: translate3d(0, -2000px, 0); | |
} | |
} | |
.bounceOutup { | |
-webkit-animation-name: bounceOutUp; | |
animation-name: bounceOutUp; | |
} | |
// mask | |
.fade-enter-active, | |
.fade-leave-active { | |
transition: opacity 0.5s; | |
} | |
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { | |
opacity: 0; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment