diff --git a/frameworks/core/components_ng/pattern/menu/menu_pattern.cpp b/frameworks/core/components_ng/pattern/menu/menu_pattern.cpp index 06976f715f64c931dc31495681a4f0bf7ece498c..ade8830e0dbdff8c67397b27f8d5169abeb6e79c 100644 --- a/frameworks/core/components_ng/pattern/menu/menu_pattern.cpp +++ b/frameworks/core/components_ng/pattern/menu/menu_pattern.cpp @@ -49,20 +49,14 @@ namespace { constexpr float PAN_MAX_VELOCITY = 2000.0f; constexpr Dimension MIN_SELECT_MENU_WIDTH = 64.0_vp; constexpr int32_t COLUMN_NUM = 2; -constexpr int32_t STACK_EXPAND_DISAPPEAR_DURATION = 300; +constexpr int32_t OTHER_MENUITEM_OPACITY_DELAY = 50; +constexpr int32_t OTHER_MENUITEM_OPACITY_DURATION = 100; +constexpr int32_t MENU_OPACITY_DURATION = 150; +constexpr Dimension BLUR_RADIUS = 20.0_vp; constexpr int32_t HALF_FOLD_HOVER_DURATION = 1000; constexpr double MENU_ORIGINAL_SCALE = 0.6f; -constexpr double MOUNT_MENU_OPACITY = 0.4f; - -constexpr double VELOCITY = 0.0f; -constexpr double MASS = 1.0f; -constexpr double STIFFNESS = 228.0f; -constexpr double DAMPING = 22.0f; -constexpr double STACK_MENU_DAMPING = 26.0f; -const RefPtr MENU_ANIMATION_CURVE = - AceType::MakeRefPtr(VELOCITY, MASS, STIFFNESS, DAMPING); -const RefPtr STACK_MENU_CURVE = - AceType::MakeRefPtr(VELOCITY, MASS, STIFFNESS, STACK_MENU_DAMPING); +constexpr double MAIN_MENU_OPACITY = 0.4f; + const RefPtr CUSTOM_PREVIEW_ANIMATION_CURVE = AceType::MakeRefPtr(0.0f, 1.0f, 380.0f, 34.0f); const RefPtr MAIN_MENU_ANIMATION_CURVE = @@ -731,7 +725,7 @@ void MenuPattern::HideStackMenu() const } auto menuNode = AceType::DynamicCast(wrapper->GetFirstChild()); CHECK_NULL_VOID(menuNode); - ShowStackExpandDisappearAnimation(menuNode, host, option); + ShowStackMenuDisappearAnimation(menuNode, host, option); } void MenuPattern::HideSubMenu() @@ -1261,61 +1255,95 @@ void MenuPattern::ShowMenuAppearAnimation() isMenuShow_ = false; } -void MenuPattern::ShowStackExpandMenu() +void MenuPattern::ShowStackMenuAppearAnimation() { auto host = GetHost(); CHECK_NULL_VOID(host); if (!isSubMenuShow_) { return; } - auto renderContext = host->GetRenderContext(); - CHECK_NULL_VOID(renderContext); auto menuWarpper = GetMenuWrapper(); CHECK_NULL_VOID(menuWarpper); auto menuWrapperPattern = menuWarpper->GetPattern(); CHECK_NULL_VOID(menuWrapperPattern); - auto outterMenu = menuWrapperPattern->GetMenu(); - CHECK_NULL_VOID(outterMenu); - - auto [originOffset, endOffset] = GetMenuOffset(outterMenu); - auto outterMenuContext = outterMenu->GetRenderContext(); - CHECK_NULL_VOID(outterMenuContext); - - renderContext->UpdatePosition( + auto mainMenu = menuWrapperPattern->GetMenu(); + CHECK_NULL_VOID(mainMenu); + + auto [originOffset, endOffset] = GetMenuOffset(mainMenu); + auto mainMenuContext = mainMenu->GetRenderContext(); + ShowStackMenuAppearOpacityAndBlurAnimation(mainMenuContext); + auto subMenuContext = host->GetRenderContext(); + CHECK_NULL_VOID(subMenuContext); + subMenuContext->UpdatePosition( OffsetT(Dimension(originOffset.GetX()), Dimension(originOffset.GetY()))); - AnimationOption opacityOption = AnimationOption(); - opacityOption.SetCurve(Curves::FRICTION); - opacityOption.SetDuration(STACK_EXPAND_DISAPPEAR_DURATION); - AnimationUtils::Animate(opacityOption, [renderContext, outterMenuContext]() { - if (renderContext) { - renderContext->UpdateOpacity(1.0f); - } - if (outterMenuContext) { - outterMenuContext->UpdateOpacity(MOUNT_MENU_OPACITY); - } - }); - AnimationOption translateOption = AnimationOption(); - translateOption.SetCurve(STACK_MENU_CURVE); - AnimationUtils::Animate(translateOption, [renderContext, menuPosition = endOffset, outterMenuContext]() { - if (renderContext) { - renderContext->UpdatePosition( + translateOption.SetCurve(MAIN_MENU_ANIMATION_CURVE); + AnimationUtils::Animate(translateOption, [subMenuContext, menuPosition = endOffset, mainMenuContext]() { + if (subMenuContext) { + subMenuContext->UpdatePosition( OffsetT(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY()))); } - if (outterMenuContext) { - outterMenuContext->UpdateTransformScale(VectorF(MOUNT_MENU_FINAL_SCALE, MOUNT_MENU_FINAL_SCALE)); + if (mainMenuContext) { + mainMenuContext->UpdateTransformScale(VectorF(MOUNT_MENU_FINAL_SCALE, MOUNT_MENU_FINAL_SCALE)); } }); ShowArrowRotateAnimation(); isSubMenuShow_ = false; } -std::pair MenuPattern::GetMenuOffset(const RefPtr& outterMenu, +void MenuPattern::ShowStackMenuAppearOpacityAndBlurAnimation(const RefPtr& mainMenuContext) const +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto otherMenuItemContext = GetOtherMenuItemContext(host); + // separated animation param for first item and other items + auto scroll = host->GetFirstChild(); + CHECK_NULL_VOID(scroll); + auto subInnerMenu = scroll->GetFirstChild(); + CHECK_NULL_VOID(subInnerMenu); + + auto titleNode = DynamicCast(subInnerMenu->GetFirstChild()); + CHECK_NULL_VOID(titleNode); + auto titleContext = titleNode->GetRenderContext(); + CHECK_NULL_VOID(titleContext); + titleContext->UpdateOpacity(1.0f); + + for (auto menuItemContext : otherMenuItemContext) { + menuItemContext->UpdateOpacity(0.0f); + } + + AnimationOption opacityOption = AnimationOption(); + opacityOption.SetCurve(Curves::FRICTION); + opacityOption.SetDelay(OTHER_MENUITEM_OPACITY_DELAY); + opacityOption.SetDuration(OTHER_MENUITEM_OPACITY_DURATION); + AnimationUtils::Animate(opacityOption, [otherMenuItemContext]() { + for (auto menuItemContext : otherMenuItemContext) { + menuItemContext->UpdateOpacity(1.0f); + } + }); + + auto scrollContext = AceType::DynamicCast(scroll)->GetRenderContext(); + CHECK_NULL_VOID(scrollContext); + scrollContext->UpdateBackBlur(Dimension(BLUR_RADIUS), {{0, 0}}); + auto subMenuContext = host->GetRenderContext(); + CHECK_NULL_VOID(subMenuContext); + subMenuContext->UpdateOpacity(0.0f); + CHECK_NULL_VOID(mainMenuContext); + mainMenuContext->UpdateOpacity(1.0f); + opacityOption.SetDuration(MENU_OPACITY_DURATION); + AnimationUtils::Animate(opacityOption, [mainMenuContext, subMenuContext, scrollContext]() { + subMenuContext->UpdateOpacity(1.0f); + mainMenuContext->UpdateOpacity(MAIN_MENU_OPACITY); + scrollContext->UpdateBackBlur(0.0_vp, {{0, 0}}); + }); +} + +std::pair MenuPattern::GetMenuOffset(const RefPtr& mainMenu, bool isNeedRestoreNodeId) const { - CHECK_NULL_RETURN(outterMenu, std::make_pair(OffsetF(), OffsetF())); - auto scroll = outterMenu->GetFirstChild(); + CHECK_NULL_RETURN(mainMenu, std::make_pair(OffsetF(), OffsetF())); + auto scroll = mainMenu->GetFirstChild(); CHECK_NULL_RETURN(scroll, std::make_pair(OffsetF(), OffsetF())); auto innerMenu = scroll->GetFirstChild(); CHECK_NULL_RETURN(innerMenu, std::make_pair(OffsetF(), OffsetF())); @@ -1377,13 +1405,13 @@ void MenuPattern::ShowArrowRotateAnimation() const { auto host = GetHost(); CHECK_NULL_VOID(host); - auto subImageNode = GetImageNode(host); + auto subImageNode = GetArrowNode(host); CHECK_NULL_VOID(subImageNode); auto subImageContext = subImageNode->GetRenderContext(); CHECK_NULL_VOID(subImageContext); subImageContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f)); AnimationOption option = AnimationOption(); - option.SetCurve(MENU_ANIMATION_CURVE); + option.SetCurve(MAIN_MENU_ANIMATION_CURVE); AnimationUtils::Animate(option, [subImageContext]() { if (subImageContext) { subImageContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, SEMI_CIRCLE_ANGEL, 0.0f)); @@ -1391,7 +1419,7 @@ void MenuPattern::ShowArrowRotateAnimation() const }); } -RefPtr MenuPattern::GetImageNode(const RefPtr& host) const +RefPtr MenuPattern::GetArrowNode(const RefPtr& host) const { auto scroll = host->GetFirstChild(); CHECK_NULL_RETURN(scroll, nullptr); @@ -1405,18 +1433,50 @@ RefPtr MenuPattern::GetImageNode(const RefPtr& host) const return image; } -void MenuPattern::ShowStackExpandDisappearAnimation(const RefPtr& menuNode, +std::vector> MenuPattern::GetOtherMenuItemContext(const RefPtr& subMenuNode) const +{ + CHECK_NULL_RETURN(subMenuNode, {}); + auto scroll = subMenuNode->GetFirstChild(); + CHECK_NULL_RETURN(scroll, {}); + auto subInnerMenu = scroll->GetFirstChild(); + CHECK_NULL_RETURN(subInnerMenu, {}); + std::vector> otherMenuItemContext; + auto children = subInnerMenu->GetChildren(); + if (children.empty()) { + LOGW("children is empty."); + return {}; + } + auto child = children.begin(); + for (advance(child, 1); child != children.end(); ++child) { + auto menuItem = DynamicCast(*child); + CHECK_NULL_RETURN(menuItem, {}); + auto menuItemContext = menuItem->GetRenderContext(); + otherMenuItemContext.emplace_back(menuItemContext); + } + return otherMenuItemContext; +} + +void MenuPattern::ShowStackMenuDisappearAnimation(const RefPtr& menuNode, const RefPtr& subMenuNode, AnimationOption& option) const { - CHECK_NULL_VOID(menuNode); - CHECK_NULL_VOID(subMenuNode); + auto otherMenuItemContext = GetOtherMenuItemContext(subMenuNode); + option.SetCurve(Curves::FRICTION); + option.SetDuration(OTHER_MENUITEM_OPACITY_DURATION); + AnimationUtils::Animate(option, [otherMenuItemContext]() { + for (auto menuItemContext : otherMenuItemContext) { + menuItemContext->UpdateOpacity(0.0f); + } + }); + CHECK_NULL_VOID(menuNode); auto [originOffset, endOffset] = GetMenuOffset(menuNode, true); + CHECK_NULL_VOID(subMenuNode); auto subMenuPos = subMenuNode->GetPaintRectOffset(); auto menuPosition = OffsetF(subMenuPos.GetX(), originOffset.GetY()); - option.SetCurve(STACK_MENU_CURVE); - AnimationUtils::Animate(option, [menuNode, menuPosition, subMenuNode]() { + option.SetCurve(MAIN_MENU_ANIMATION_CURVE); + auto subImageNode = GetArrowNode(subMenuNode); + AnimationUtils::Animate(option, [menuNode, menuPosition, subMenuNode, subImageNode]() { auto menuContext = menuNode->GetRenderContext(); auto subMenuContext = subMenuNode->GetRenderContext(); if (subMenuContext) { @@ -1426,20 +1486,28 @@ void MenuPattern::ShowStackExpandDisappearAnimation(const RefPtr& men if (menuContext) { menuContext->UpdateTransformScale(VectorF(1.0f, 1.0f)); } + if (subImageNode) { + auto subImageContext = subImageNode->GetRenderContext(); + if (subImageContext) { + subImageContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f)); + } + } }); - option.SetCurve(MENU_ANIMATION_CURVE); - auto subImageNode = GetImageNode(subMenuNode); - AnimationUtils::Animate(option, [subImageNode]() { - CHECK_NULL_VOID(subImageNode); - auto subImageContext = subImageNode->GetRenderContext(); - CHECK_NULL_VOID(subImageContext); - subImageContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f)); - }); + ShowStackMenuDisappearOpacityAndBlurAnimation(menuNode, subMenuNode, option); +} +void MenuPattern::ShowStackMenuDisappearOpacityAndBlurAnimation(const RefPtr& menuNode, + const RefPtr& subMenuNode, AnimationOption& option) const +{ + auto scroll = subMenuNode->GetFirstChild(); + CHECK_NULL_VOID(scroll); + auto scrollContext = AceType::DynamicCast(scroll)->GetRenderContext(); + CHECK_NULL_VOID(scrollContext); + scrollContext->UpdateBackBlur(Dimension(BLUR_RADIUS), {{0, 0}}); option.SetCurve(Curves::FRICTION); - option.SetDuration(STACK_EXPAND_DISAPPEAR_DURATION); - AnimationUtils::Animate(option, [menuNode, subMenuNode]() { + option.SetDuration(MENU_OPACITY_DURATION); + AnimationUtils::Animate(option, [menuNode, subMenuNode, scrollContext]() { auto menuContext = menuNode->GetRenderContext(); auto subMenuContext = subMenuNode->GetRenderContext(); if (subMenuContext) { @@ -1448,6 +1516,9 @@ void MenuPattern::ShowStackExpandDisappearAnimation(const RefPtr& men if (menuContext) { menuContext->UpdateOpacity(1.0f); } + if (scrollContext) { + scrollContext->UpdateBackBlur(0.0_vp, {{0, 0}}); + } }, option.GetOnFinishEvent()); } @@ -1491,7 +1562,7 @@ bool MenuPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dirty, c { ShowPreviewMenuAnimation(); ShowMenuAppearAnimation(); - ShowStackExpandMenu(); + ShowStackMenuAppearAnimation(); auto host = GetHost(); CHECK_NULL_RETURN(host, false); auto menuPosition = host->GetPaintRectOffset(); diff --git a/frameworks/core/components_ng/pattern/menu/menu_pattern.h b/frameworks/core/components_ng/pattern/menu/menu_pattern.h index 8636c7b0b13310f531c1fc8538f4a6d417ae3388..94d549fc64a2becfc705999ed9a66c60f597bf75 100644 --- a/frameworks/core/components_ng/pattern/menu/menu_pattern.h +++ b/frameworks/core/components_ng/pattern/menu/menu_pattern.h @@ -462,7 +462,7 @@ public: } void ShowMenuDisappearAnimation(); - void ShowStackExpandDisappearAnimation(const RefPtr& menuNode, + void ShowStackMenuDisappearAnimation(const RefPtr& menuNode, const RefPtr& subMenuNode, AnimationOption& option) const; void SetBuilderFunc(SelectMakeCallback&& makeFunc) @@ -623,13 +623,17 @@ private: void ShowPreviewPositionAnimation(AnimationOption& option, int32_t delay); void ShowPreviewMenuScaleAnimation(const RefPtr& menuTheme, AnimationOption& option, int32_t delay); void ShowMenuAppearAnimation(); - void ShowStackExpandMenu(); - std::pair GetMenuOffset(const RefPtr& outterMenu, + void ShowStackMenuAppearAnimation(); + std::pair GetMenuOffset(const RefPtr& mainMenu, bool isNeedRestoreNodeId = false) const; MenuItemInfo GetInnerMenuOffset(const RefPtr& child, bool isNeedRestoreNodeId) const; MenuItemInfo GetMenuItemInfo(const RefPtr& child, bool isNeedRestoreNodeId) const; + void ShowStackMenuAppearOpacityAndBlurAnimation(const RefPtr& mainMenuContext) const; + void ShowStackMenuDisappearOpacityAndBlurAnimation(const RefPtr& menuNode, + const RefPtr& subMenuNode, AnimationOption& option) const; + std::vector> GetOtherMenuItemContext(const RefPtr& subMenuNode) const; void ShowArrowRotateAnimation() const; - RefPtr GetImageNode(const RefPtr& host) const; + RefPtr GetArrowNode(const RefPtr& host) const; // arrowNode in subMenu void InitPanEvent(const RefPtr& gestureHub); void HandleDragEnd(float offsetX, float offsetY, float velocity); diff --git a/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp b/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp index 491a0cbf0926786d07474bf88091aeee1f032229..56de7a21a69b7bbfbd4523c1477387cd8bbd8b38 100644 --- a/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp +++ b/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp @@ -365,7 +365,7 @@ void MenuWrapperPattern::HideStackExpandMenu(const RefPtr& subMenu) }); auto menuNodePattern = DynamicCast(menuNode)->GetPattern(); CHECK_NULL_VOID(menuNodePattern); - menuNodePattern->ShowStackExpandDisappearAnimation(DynamicCast(menuNode), + menuNodePattern->ShowStackMenuDisappearAnimation(DynamicCast(menuNode), DynamicCast(subMenu), option); menuNodePattern->SetDisappearAnimation(true); } diff --git a/test/unittest/core/pattern/menu/menu_pattern_test_ng.cpp b/test/unittest/core/pattern/menu/menu_pattern_test_ng.cpp index c9ca2ac789ca37e510aa50a160778ff264320e12..bc8bab5e5a6b7338fb1c6905c661ffeaee3e6268 100644 --- a/test/unittest/core/pattern/menu/menu_pattern_test_ng.cpp +++ b/test/unittest/core/pattern/menu/menu_pattern_test_ng.cpp @@ -1577,7 +1577,7 @@ HWTEST_F(MenuPatternTestNg, MenuPatternTestNg086, TestSize.Level1) /** * @tc.name: MenuPatternTest087 - * @tc.desc: Test ShowStackExpandDisappearAnimation. + * @tc.desc: Test ShowStackMenuDisappearAnimation. * @tc.type: FUNC */ HWTEST_F(MenuPatternTestNg, MenuPatternTestNg087, TestSize.Level1) @@ -1611,7 +1611,7 @@ HWTEST_F(MenuPatternTestNg, MenuPatternTestNg087, TestSize.Level1) auto children = subMenuNode->GetChildren(); const RefPtr MENU_ANIMATION_CURVE = AceType::MakeRefPtr(VELOCITY, MASS, STIFFNESS, DAMPING); - menuPattern->ShowStackExpandDisappearAnimation(menuNode, subMenuNode, animationOption); + menuPattern->ShowStackMenuDisappearAnimation(menuNode, subMenuNode, animationOption); EXPECT_FALSE(animationOption.curve_->IsEqual(MENU_ANIMATION_CURVE)); }