Files

67 lines
1.6 KiB
Vue
Raw Permalink Normal View History

2026-08-19 08:17:18 +08:00
<template>
<!-- 进入动效外壳:fade / slide / zoom / none -->
<view class="theme-enter" :class="'theme-enter--' + transition" :style="enterStyle">
<slot />
</view>
</template>
<script>
import { getActiveLayout, getActiveVars } from '@/utils/theme'
export default {
name: 'ThemeEnter',
props: {
/** 覆盖 effect.transition */
type: { type: String, default: '' },
delay: { type: [Number, String], default: 0 },
},
computed: {
transition() {
if (this.type) return this.type
const effect = (getActiveLayout().effect) || {}
return effect.transition || 'fade'
},
enterStyle() {
const v = getActiveVars()
const base = v['--motion-base'] || '320ms'
const easing = v['--motion-easing'] || 'ease'
return {
animationDuration: base,
animationTimingFunction: easing,
animationDelay: `${Number(this.delay) || 0}ms`,
}
},
},
}
</script>
<style lang="scss" scoped>
.theme-enter--none {
animation: none;
}
.theme-enter--fade {
animation-name: themeFadeIn;
animation-fill-mode: both;
}
.theme-enter--slide {
animation-name: themeSlideUp;
animation-fill-mode: both;
}
.theme-enter--zoom {
animation-name: themeZoomIn;
animation-fill-mode: both;
}
@keyframes themeFadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes themeSlideUp {
from { opacity: 0; transform: translateY(24rpx); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes themeZoomIn {
from { opacity: 0; transform: scale(0.96); }
to { opacity: 1; transform: scale(1); }
}
</style>