67 lines
1.6 KiB
Vue
67 lines
1.6 KiB
Vue
<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>
|