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`, enterActiveClass: `${transitionName}-enter ${transitionName}-enter-prepare`,
enterToClass: `${transitionName}-enter ${transitionName}-enter-active`, enterToClass: `${transitionName}-enter ${transitionName}-enter-active`,
leaveFromClass: ` ${transitionName}-leave`, leaveFromClass: ` ${transitionName}-leave`,
leaveActiveClass: `${transitionName}-leave ${transitionName}-leave-active`, leaveActiveClass: `${transitionName}-leave`,
leaveToClass: `${transitionName}-leave ${transitionName}-leave-active`, leaveToClass: `${transitionName}-leave ${transitionName}-leave-active`,
...opt, ...opt,
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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