perf: menu animate

feat-css-var
tangjinzhou 2022-03-03 22:27:44 +08:00
parent 0202c441cf
commit 07a7f47de3
7 changed files with 55 additions and 52 deletions

View File

@ -29,7 +29,7 @@ export const getTransitionProps = (transitionName: string, opt: TransitionProps
enterActiveClass: `${transitionName}-enter ${transitionName}-enter-prepare`,
enterToClass: `${transitionName}-enter ${transitionName}-enter-active`,
leaveFromClass: ` ${transitionName}-leave`,
leaveActiveClass: `${transitionName}-leave ${transitionName}-leave-active`,
leaveActiveClass: `${transitionName}-leave`,
leaveToClass: `${transitionName}-leave ${transitionName}-leave-active`,
...opt,
}

View File

@ -102,9 +102,7 @@ export default defineComponent({
forceRender={forceRender || forceSubMenuRender.value}
popupAnimation={mergedMotion.value}
v-slots={{
popup: () => {
return slots.popup?.({ visible: innerVisible.value });
},
popup: slots.popup,
default: slots.default,
}}
></Trigger>

View File

@ -269,7 +269,6 @@ export default defineComponent({
return slots.default?.();
}
const subMenuPrefixClsValue = subMenuPrefixCls.value;
let titleNode = () => null;
if (!overflowDisabled.value && mode.value !== 'inline') {
titleNode = () => (
@ -321,22 +320,24 @@ export default defineComponent({
onMouseenter={onMouseEnter}
onMouseleave={onMouseLeave}
data-submenu-id={key}
v-slots={() => {
return (
<>
{titleNode()}
v-slots={{
default: () => {
return (
<>
{titleNode()}
{/* Inline mode */}
{!overflowDisabled.value && (
<InlineSubMenuList
id={popupId}
open={open.value}
keyPath={keysPath.value}
v-slots={{ default: slots.default }}
></InlineSubMenuList>
)}
</>
);
{/* Inline mode */}
{!overflowDisabled.value && (
<InlineSubMenuList
id={popupId}
open={open.value}
keyPath={keysPath.value}
v-slots={{ default: slots.default }}
></InlineSubMenuList>
)}
</>
);
},
}}
></Overflow.Item>
</MenuContextProvider>

View File

@ -40,6 +40,7 @@
transform-origin: 0% 0%;
opacity: 0;
}
100% {
transform: scaleY(1);
transform-origin: 0% 0%;
@ -53,6 +54,7 @@
transform-origin: 0% 0%;
opacity: 1;
}
100% {
transform: scaleY(0.8);
transform-origin: 0% 0%;
@ -66,6 +68,7 @@
transform-origin: 100% 100%;
opacity: 0;
}
100% {
transform: scaleY(1);
transform-origin: 100% 100%;
@ -79,6 +82,7 @@
transform-origin: 100% 100%;
opacity: 1;
}
100% {
transform: scaleY(0.8);
transform-origin: 100% 100%;
@ -92,6 +96,7 @@
transform-origin: 0% 0%;
opacity: 0;
}
100% {
transform: scaleX(1);
transform-origin: 0% 0%;
@ -105,6 +110,7 @@
transform-origin: 0% 0%;
opacity: 1;
}
100% {
transform: scaleX(0.8);
transform-origin: 0% 0%;
@ -118,6 +124,7 @@
transform-origin: 100% 0%;
opacity: 0;
}
100% {
transform: scaleX(1);
transform-origin: 100% 0%;
@ -131,6 +138,7 @@
transform-origin: 100% 0%;
opacity: 1;
}
100% {
transform: scaleX(0.8);
transform-origin: 100% 0%;

View File

@ -47,6 +47,7 @@
transform: scale(0.2);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
@ -57,6 +58,7 @@
0% {
transform: scale(1);
}
100% {
transform: scale(0.2);
opacity: 0;
@ -64,15 +66,11 @@
}
@keyframes antZoomBigIn {
// 计算popover位置时有可能处于 active 状态,通过这种方式 hack 待改进
0% {
transform: none;
opacity: 0;
}
5% {
transform: scale(0.8);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
@ -83,6 +81,7 @@
0% {
transform: scale(1);
}
100% {
transform: scale(0.8);
opacity: 0;
@ -95,6 +94,7 @@
transform-origin: 50% 0%;
opacity: 0;
}
100% {
transform: scale(1);
transform-origin: 50% 0%;
@ -106,6 +106,7 @@
transform: scale(1);
transform-origin: 50% 0%;
}
100% {
transform: scale(0.8);
transform-origin: 50% 0%;
@ -119,6 +120,7 @@
transform-origin: 0% 50%;
opacity: 0;
}
100% {
transform: scale(1);
transform-origin: 0% 50%;
@ -130,6 +132,7 @@
transform: scale(1);
transform-origin: 0% 50%;
}
100% {
transform: scale(0.8);
transform-origin: 0% 50%;
@ -143,6 +146,7 @@
transform-origin: 100% 50%;
opacity: 0;
}
100% {
transform: scale(1);
transform-origin: 100% 50%;
@ -154,6 +158,7 @@
transform: scale(1);
transform-origin: 100% 50%;
}
100% {
transform: scale(0.8);
transform-origin: 100% 50%;
@ -167,6 +172,7 @@
transform-origin: 50% 100%;
opacity: 0;
}
100% {
transform: scale(1);
transform-origin: 50% 100%;
@ -178,6 +184,7 @@
transform: scale(1);
transform-origin: 50% 100%;
}
100% {
transform: scale(0.8);
transform-origin: 50% 100%;

View File

@ -1,5 +1,3 @@
@import '../themes/index';
.motion-common(@duration: @animation-duration-base) {
animation-duration: @duration;
animation-fill-mode: both;

View File

@ -2,16 +2,7 @@ import type { AlignType } from '../interface';
import useVisibleStatus from './useVisibleStatus';
import useStretchStyle from './useStretchStyle';
import type { CSSProperties } from 'vue';
import {
computed,
defineComponent,
nextTick,
ref,
toRef,
Transition,
watch,
withModifiers,
} from 'vue';
import { computed, defineComponent, ref, toRef, Transition, watch, withModifiers } from 'vue';
import type { RefAlign } from '../../vc-align/Align';
import Align from '../../vc-align/Align';
import { getMotion } from '../utils/motionUtil';
@ -84,7 +75,7 @@ export default defineComponent({
if (status.value === 'align') {
// Repeat until not more align needed
if (preAlignedClassName !== nextAlignedClassName) {
nextTick(() => {
Promise.resolve().then(() => {
forceAlign();
});
} else {
@ -103,8 +94,8 @@ export default defineComponent({
['onAfterEnter', 'onAfterLeave'].forEach(eventName => {
const originFn = m[eventName];
m[eventName] = node => {
originFn?.(node);
goNextStatus();
originFn?.(node);
};
});
return m;
@ -117,9 +108,9 @@ export default defineComponent({
};
watch(
[toRef(motion.value, 'name'), status],
[motion.value, status],
() => {
if (!motion.value.name && status.value === 'motion') {
if (!motion.value && status.value === 'motion') {
goNextStatus();
}
},
@ -132,6 +123,12 @@ export default defineComponent({
return (elementRef.value as any).$el || elementRef.value;
},
});
const alignDisabled = computed(() => {
if ((props.align as any)?.points && (status.value === 'align' || status.value === 'stable')) {
return false;
}
return true;
});
return () => {
const {
zIndex,
@ -148,19 +145,12 @@ export default defineComponent({
const mergedStyle: CSSProperties = {
...stretchStyle.value,
zIndex,
opacity:
statusValue === 'motion' || statusValue === 'stable' || !visible.value ? undefined : 0,
pointerEvents: statusValue === 'stable' ? undefined : 'none',
opacity: statusValue === 'motion' || statusValue === 'stable' || !visible.value ? null : 0,
pointerEvents: statusValue === 'stable' ? null : 'none',
...(attrs.style as object),
};
// Align statusValue
let alignDisabled = true;
if (align?.points && (statusValue === 'align' || statusValue === 'stable')) {
alignDisabled = false;
}
let childNode: any = flattenChildren(slots.default?.());
let childNode: any = flattenChildren(slots.default?.({ visible: props.visible }));
// Wrapper when multiple children
if (childNode.length > 1) {
@ -169,6 +159,7 @@ export default defineComponent({
const mergedClassName = classNames(prefixCls, attrs.class, alignedClassName.value);
const hasAnimate = visible.value || !props.visible;
const transitionProps = hasAnimate ? getTransitionProps(motion.value.name, motion.value) : {};
return (
<Transition
ref={elementRef}
@ -183,7 +174,7 @@ export default defineComponent({
key="popup"
ref={alignRef}
monitorWindowResize
disabled={alignDisabled}
disabled={alignDisabled.value}
align={align}
onAlign={onInternalAlign}
v-slots={{