parsley/app/javascript/components/AppExpandTransition.vue

109 lines
3.0 KiB
Vue
Raw Permalink Normal View History

2018-09-05 17:49:21 -05:00
<template>
<transition
name="expand"
@enter="enter"
2018-09-13 14:51:41 -05:00
@leave="leave"
@enter-cancel="cancel"
@leave-cancel="cancel">
2018-09-05 17:49:21 -05:00
<slot></slot>
</transition>
</template>
<script>
2018-09-13 14:51:41 -05:00
import TWEEN from '@tweenjs/tween.js';
2018-09-05 17:49:21 -05:00
export default {
2018-09-13 14:51:41 -05:00
props: {
expandTime: {
type: Number,
default: 250
}
},
data() {
return {
animation: null
}
},
2018-09-05 17:49:21 -05:00
methods: {
2018-09-13 14:51:41 -05:00
cancel () {
if (this.animation) {
this.animation.stop();
this.animation = null;
}
},
2018-09-05 17:49:21 -05:00
enter(element, done) {
2018-09-13 14:51:41 -05:00
const width = parseInt(getComputedStyle(element).width);
const paddingTop = parseInt(getComputedStyle(element).paddingTop);
const paddingBottom = parseInt(getComputedStyle(element).paddingBottom);
2018-09-05 17:49:21 -05:00
element.style.width = width;
element.style.position = 'absolute';
element.style.visibility = 'hidden';
element.style.height = 'auto';
2018-09-13 14:51:41 -05:00
const height = parseInt(getComputedStyle(element).height);
2018-09-05 17:49:21 -05:00
element.style.width = null;
element.style.position = null;
element.style.visibility = null;
2018-09-13 14:51:41 -05:00
element.style.overflow = 'hidden';
2018-09-05 17:49:21 -05:00
element.style.height = 0;
2018-09-13 14:51:41 -05:00
this.animation = new TWEEN.Tween({height: 0, paddingTop: 0, paddingBottom: 0})
.to({height: height, paddingTop: paddingTop, paddingBottom: paddingBottom}, this.expandTime)
.onUpdate(obj => {
element.style.height = obj.height + "px";
element.style.paddingBottom = obj.paddingBottom + "px";
element.style.paddingTop = obj.paddingTop + "px";
})
.onComplete(() => {
this.animation = null;
element.removeAttribute('style');
element.style.opacity = 0.99;
setTimeout(() => {
// Fixes odd drawing bug in Chrome
element.style.opacity = 1.0;
}, 1000);
done();
})
.start();
2018-09-05 17:49:21 -05:00
},
leave(element, done) {
2018-09-13 14:51:41 -05:00
const height = parseInt(getComputedStyle(element).height);
const paddingTop = parseInt(getComputedStyle(element).paddingTop);
const paddingBottom = parseInt(getComputedStyle(element).paddingBottom);
2018-09-05 17:49:21 -05:00
2018-09-13 14:51:41 -05:00
element.style.overflow = 'hidden';
2018-09-05 17:49:21 -05:00
2018-09-13 14:51:41 -05:00
this.animation = new TWEEN.Tween({height: height, paddingTop: paddingTop, paddingBottom: paddingBottom})
.to({height: 0, paddingTop: 0, paddingBottom: 0}, this.expandTime)
.onUpdate(obj => {
element.style.height = obj.height + "px";
element.style.paddingBottom = obj.paddingBottom + "px";
element.style.paddingTop = obj.paddingTop + "px";
})
.onComplete(() => {
this.animation = null;
element.removeAttribute('style');
done();
})
.start();
2018-09-05 17:49:21 -05:00
}
}
}
</script>
<style scoped>
* {
will-change: height;
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000px;
}
</style>