I am trying to develop an animation which will sequentially load into the view once the side bar is toggled on
The animation should be similar to this one: https://codepen.io/dizzyluo/pen/yJLwWm
Here is my code:
Parent:
<template>
<div>
<button @click="cartToggle">Toggle</button>
</div>
<div>
<Child :visible="cartVisible" @update:visible="cartToggle" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Comp.vue'
const cartVisible = ref(false)
const cartToggle = () => {
cartVisible.value = !cartVisible.value
}
</script>
<style scoped>
span {
cursor: pointer;
}
</style>
Child:
<script setup lang="ts">
import { toRefs, watchEffect, onBeforeUnmount } from 'vue'
import CartItem from './CartItem.vue'
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false
}
})
const { visible } = toRefs(props)
const emit = defineEmits(['update:visible'])
const hideCartBar = () => {
emit('update:visible', false)
}
watchEffect(() => {
document.body.style.overflow = visible.value ? 'hidden' : 'auto'
document.body.style.paddingRight = visible.value ? '15px' : '0px'
})
onBeforeUnmount(() => {
document.body.style.overflow = 'auto'
document.body.style.paddingRight = '0px'
})
const show = true
</script>
<template>
<transition name="fade">
<div
v-if="props.visible"
class="cartbar-overlay"
@click="hideCartBar"
></div>
</transition>
<transition name="slide">
<div v-show="props.visible" class="cartbar-container">
<div class="cartbar__header">
<h2>Menu</h2>
<span @click="hideCartBar" class="cursor-pointer">X</span>
</div>
<div class="cart-items">
<CartItem v-for="index in 3" :key="index" :delay="index" />
</div>
</div>
</transition>
</template>
<style scoped>
/* transition */
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-to,
.fade-leave-from {
opacity: 1;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 500ms;
}
.slide-enter-from,
.slide-leave-to {
transform: translateX(100%);
}
.slide-enter-to,
.slide-leave-from {
transform: translateX(0);
}
.slide-enter-active,
.slide-leave-active {
transition: transform 500ms;
}
/* cartbar */
.cursor-pointer {
cursor: pointer;
}
.cartbar-overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.7);
cursor: pointer;
}
.cartbar-container {
position: fixed;
top: 0;
right: 0;
bottom: 0;
width: 100%;
max-width: 460px;
height: 100%;
overflow: hidden;
margin-left: auto;
padding: calc(4px * 7);
background-color: #f4f2f1;
color: #706b5f;
}
.cartbar__header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
</style>
Delayed animated component:
<script setup>
import { toRefs } from 'vue'
const props = defineProps({
delay: Number
})
const { delay } = toRefs(props)
</script>
<template>
<transition appear name="slide">
<div class="item">
{{ delay }}
<div class="image">
<img src="https://placehold.co/75x100" />
</div>
<div class="meta">
<h3>Lorem Ipsum</h3>
<div class="meta-info">
<p>Dolor sit amet dorum forum</p>
</div>
</div>
</div>
</transition>
</template>
<style scoped>
.slide-leave-active,
.slide-enter-active {
transition: 1s;
transition-delay: 0.25s;
}
.slide-enter {
transform: translate(100%, 0);
}
.slide-leave-to {
transform: translate(-100%, 0);
}
.meta-info {
display: flex;
flex-direction: row;
justify-content: space-between;
margin: 0;
padding: 0;
}
.item {
display: flex;
flex-direction: row;
margin: 10px 0;
}
.image {
margin-right: 15px;
height: 100%;
}
.image img {
height: 100%;
}
.meta-info {
font-size: 0.8rem;
}
</style>
Any idea what am I missing there?