parsley/app/javascript/components/AppExpandTransition.vue

104 lines
2.9 KiB
Vue
Raw 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>
2024-09-29 13:35:49 -05:00
<script setup>
2018-09-05 17:49:21 -05:00
2018-09-13 14:51:41 -05:00
import TWEEN from '@tweenjs/tween.js';
2024-09-29 09:44:40 -05:00
import { useGlobalTweenGroup } from "../lib/useGlobalTweenGroup";
2018-09-13 14:51:41 -05:00
2024-09-29 13:35:49 -05:00
const props = defineProps({
expandTime: {
type: Number,
default: 250
}
});
2018-09-13 14:51:41 -05:00
2024-09-29 13:35:49 -05:00
let animation = null;
2018-09-13 14:51:41 -05:00
2024-09-29 13:35:49 -05:00
function cancel () {
if (animation) {
animation.stop();
animation = null;
}
}
2018-09-13 14:51:41 -05:00
2024-09-29 13:35:49 -05:00
function enter(element, done) {
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
2024-09-29 13:35:49 -05:00
element.style.width = width;
element.style.position = 'absolute';
element.style.visibility = 'hidden';
element.style.height = 'auto';
2018-09-05 17:49:21 -05:00
2024-09-29 13:35:49 -05:00
const height = parseInt(getComputedStyle(element).height);
2018-09-05 17:49:21 -05:00
2024-09-29 13:35:49 -05:00
element.style.width = null;
element.style.position = null;
element.style.visibility = null;
element.style.overflow = 'hidden';
element.style.height = 0;
2018-09-05 17:49:21 -05:00
2024-09-29 13:35:49 -05:00
animation = new TWEEN.Tween({height: 0, paddingTop: 0, paddingBottom: 0})
.to({height: height, paddingTop: paddingTop, paddingBottom: paddingBottom}, props.expandTime)
.onUpdate(obj => {
element.style.height = obj.height + "px";
element.style.paddingBottom = obj.paddingBottom + "px";
element.style.paddingTop = obj.paddingTop + "px";
})
.onComplete(() => {
animation = null;
element.removeAttribute('style');
element.style.opacity = 0.99;
setTimeout(() => {
// Fixes odd drawing bug in Chrome
element.style.opacity = 1.0;
}, 1000);
done();
})
.group(useGlobalTweenGroup())
.start();
}
2018-09-05 17:49:21 -05:00
2024-09-29 13:35:49 -05:00
function leave(element, done) {
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
2024-09-29 13:35:49 -05:00
element.style.overflow = 'hidden';
2018-09-05 17:49:21 -05:00
2024-09-29 13:35:49 -05:00
animation = new TWEEN.Tween({height: height, paddingTop: paddingTop, paddingBottom: paddingBottom})
.to({height: 0, paddingTop: 0, paddingBottom: 0}, props.expandTime)
.onUpdate(obj => {
element.style.height = obj.height + "px";
element.style.paddingBottom = obj.paddingBottom + "px";
element.style.paddingTop = obj.paddingTop + "px";
})
.onComplete(() => {
animation = null;
element.removeAttribute('style');
done();
})
.group(useGlobalTweenGroup())
.start();
2018-09-05 17:49:21 -05:00
}
</script>
<style scoped>
* {
will-change: height;
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000px;
}
</style>