• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
16 
17 #include "core/common/ace_engine.h"
18 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
19 #include "core/components_ng/manager/drag_drop/drag_drop_controller_func_wrapper.h"
20 #include "core/components_ng/pattern/image/image_pattern.h"
21 #include "core/components_ng/pattern/menu/menu_theme.h"
22 #include "core/components_ng/pattern/menu/menu_view.h"
23 #include "core/components_ng/pattern/menu/preview/menu_preview_pattern.h"
24 #include "core/components_ng/pattern/relative_container/relative_container_pattern.h"
25 #include "core/components_ng/pattern/stack/stack_pattern.h"
26 #include "core/components_ng/pattern/text/text_pattern.h"
27 
28 namespace OHOS::Ace::NG {
29 namespace {
30 constexpr int32_t BEFORE_LIFTING_TIME = 650;
31 constexpr int32_t IMAGE_SHOW_TIME = 50;
32 constexpr int32_t PIXELMAP_ANIMATION_DURATION = 300;
33 constexpr int32_t BADGE_ANIMATION_DURATION = 200;
34 constexpr int32_t BADGE_ANIMATION_DELAY = 100;
35 constexpr int32_t NODE_RESET_DURATION = 200;
36 constexpr float DEFAULT_ANIMATION_SCALE = 0.95f;
37 constexpr float GATHER_SPRING_RESPONSE = 0.304f;
38 constexpr float GATHER_SPRING_DAMPING_FRACTION = 0.97f;
39 constexpr float GRID_MOVE_SCALE = 0.2f;
40 constexpr float LIST_MOVE_SCALE = 0.2f;
41 constexpr float EULER_NUMBER = 2.71828f;
42 constexpr float GATHER_OFFSET_RADIUS = 0.1f;
43 constexpr float PIXELMAP_DRAG_SCALE_MULTIPLE = 1.05f;
44 constexpr float BADGE_ANIMATION_SCALE = 1.0f;
45 constexpr Dimension BADGE_RELATIVE_OFFSET = 8.0_vp;
46 constexpr Dimension BADGE_DEFAULT_SIZE = 24.0_vp;
47 constexpr Dimension BADGE_TEXT_FONT_SIZE = 14.0_fp;
48 const Color BADGE_TEXT_FONT_COLOR = Color::FromString("#ffffffff");
49 const Color BADGE_BACKGROUND_COLOR = Color::FromString("#ff007dff");
50 constexpr float DEFAULT_INTERPOLATING_SPRING_VELOCITY = 10.0f;
51 constexpr float DEFAULT_INTERPOLATING_SPRING_MASS = 1.0f;
52 constexpr float DEFAULT_INTERPOLATING_SPRING_STIFFNESS = 410.0f;
53 constexpr float DEFAULT_INTERPOLATING_SPRING_DAMPING = 38.0f;
54 constexpr float DEFAULT_GRAYED = 0.4f;
55 constexpr float HALF_DIVIDE = 2.0f;
56 const RefPtr<InterpolatingSpring> DRAG_START_ANIMATION_CURVE =
57     AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 0.0f, 380.0f, 34.0f);
58 const RefPtr<InterpolatingSpring> DRAG_END_ANIMATION_CURVE =
59     AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 0.0f, 228.0f, 29.0f);
60 const RefPtr<Curve> DRAG_CONTROL_ANIMATION_CURVE =
61     AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
62 }
63 
CalcDistanceBeforeLifting(bool isGrid,CalcResult & calcResult,OffsetF gatherNodeCenter,const std::vector<GatherNodeChildInfo> & gatherNodeChildrenInfo)64 void DragAnimationHelper::CalcDistanceBeforeLifting(bool isGrid, CalcResult& calcResult, OffsetF gatherNodeCenter,
65     const std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo)
66 {
67     for (const auto& child : gatherNodeChildrenInfo) {
68         auto imageNode = child.imageNode.Upgrade();
69         CHECK_NULL_VOID(imageNode);
70         auto width = child.width;
71         auto height = child.height;
72         OffsetF curPos = {child.offset.GetX() + child.halfWidth, child.offset.GetY() + child.halfHeight};
73         float dis = sqrt(pow(gatherNodeCenter.GetX() - curPos.GetX(), 2) +
74             pow(gatherNodeCenter.GetY() - curPos.GetY(), 2));
75         calcResult.maxDistance = std::max(calcResult.maxDistance, dis);
76         calcResult.minDistance = calcResult.minDistance < 0 ? dis : std::min(calcResult.minDistance, dis);
77         if (isGrid) {
78             calcResult.maxTranslation = calcResult.maxTranslation < 0 ? std::min(width, height) :
79                 std::min(calcResult.maxTranslation, std::min(width, height));
80         } else {
81             calcResult.maxTranslation = calcResult.maxTranslation < 0 ? height :
82                 std::min(calcResult.maxTranslation, height);
83         }
84     }
85     calcResult.maxTranslation *= isGrid ? GRID_MOVE_SCALE : LIST_MOVE_SCALE;
86 }
87 
CalcOffsetToTarget(OffsetF curPos,OffsetF targetPos,CalcResult & calcResult)88 OffsetF DragAnimationHelper::CalcOffsetToTarget(OffsetF curPos, OffsetF targetPos, CalcResult& calcResult)
89 {
90     if (NearZero(calcResult.maxDistance) || NearZero(calcResult.minDistance) || calcResult.maxTranslation < 0) {
91         return { 0.0f, 0.0f };
92     }
93 
94     float xDis = targetPos.GetX() - curPos.GetX();
95     float yDis = targetPos.GetY() - curPos.GetY();
96     float dis = sqrt(pow(xDis, 2) + pow(yDis, 2));
97     if (NearZero(dis)) {
98         return { 0.0f, 0.0f };
99     }
100     auto trans = calcResult.maxTranslation * pow(EULER_NUMBER, -(dis - calcResult.minDistance) /
101         calcResult.maxDistance * GATHER_OFFSET_RADIUS);
102     float x = xDis * trans / dis;
103     float y = yDis * trans / dis;
104     return { x, y };
105 }
106 
PlayGatherNodeTranslateAnimation(const RefPtr<FrameNode> & frameNode,const RefPtr<OverlayManager> & overlayManager)107 void DragAnimationHelper::PlayGatherNodeTranslateAnimation(const RefPtr<FrameNode>& frameNode,
108     const RefPtr<OverlayManager>& overlayManager)
109 {
110     CHECK_NULL_VOID(overlayManager);
111     CHECK_NULL_VOID(frameNode);
112     AnimationOption option;
113     option.SetDuration(BEFORE_LIFTING_TIME);
114     option.SetCurve(Curves::SHARP);
115     auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenterToScreen(frameNode);
116     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
117 
118     bool isGrid = frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG;
119     CalcResult calcResult = { 0.0f, -1.0f, -1.0f };
120     CalcDistanceBeforeLifting(isGrid, calcResult, gatherNodeCenter, gatherNodeChildrenInfo);
121     auto pipeline = frameNode->GetContextRefPtr();
122     CHECK_NULL_VOID(pipeline);
123     AnimationUtils::Animate(
124         option,
125         [gatherNodeCenter, gatherNodeChildrenInfo, calcResult]() mutable {
126             for (const auto& child : gatherNodeChildrenInfo) {
127                 auto imageNode = child.imageNode.Upgrade();
128                 auto curPos = child.offset + OffsetF(child.halfWidth, child.halfHeight);
129                 auto offset = CalcOffsetToTarget(curPos, gatherNodeCenter, calcResult);
130                 offset += child.offset;
131                 DragDropFuncWrapper::UpdateNodePositionToScreen(imageNode, offset);
132             }
133         }, nullptr, nullptr, pipeline);
134 }
135 
PlayGatherNodeOpacityAnimation(const RefPtr<OverlayManager> & overlayManager)136 void DragAnimationHelper::PlayGatherNodeOpacityAnimation(const RefPtr<OverlayManager>& overlayManager)
137 {
138     CHECK_NULL_VOID(overlayManager);
139     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
140 
141     AnimationOption opacityOption;
142     opacityOption.SetDuration(IMAGE_SHOW_TIME);
143     opacityOption.SetCurve(AceType::MakeRefPtr<CubicCurve>(0.0f, 0.0f, 1.0f, 1.0f));
144 
145     for (const auto& child : gatherNodeChildrenInfo) {
146         auto imageNode = child.imageNode.Upgrade();
147         CHECK_NULL_VOID(imageNode);
148         auto imageContext = imageNode->GetRenderContext();
149         CHECK_NULL_VOID(imageContext);
150         imageContext->OpacityAnimation(opacityOption, 0.0f, 1.0f);
151     }
152 }
153 
PlayGatherAnimationBeforeLifting(const RefPtr<DragEventActuator> & actuator)154 void DragAnimationHelper::PlayGatherAnimationBeforeLifting(const RefPtr<DragEventActuator>& actuator)
155 {
156     TAG_LOGI(AceLogTag::ACE_DRAG, "Play gather animation before lifting");
157     CHECK_NULL_VOID(actuator);
158     if (!actuator->IsNeedGather()) {
159         return;
160     }
161     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
162     CHECK_NULL_VOID(pipeline);
163     auto manager = pipeline->GetOverlayManager();
164     CHECK_NULL_VOID(manager);
165     auto frameNode = actuator->GetFrameNode();
166     CHECK_NULL_VOID(frameNode);
167     auto gatherNode = actuator->GetGatherNode();
168     CHECK_NULL_VOID(gatherNode);
169     auto imageContext = gatherNode->GetRenderContext();
170     CHECK_NULL_VOID(imageContext);
171     imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(0.0f), Dimension(0.0f)));
172     auto gatherNodeChildrenInfo = actuator->GetGatherNodeChildrenInfo();
173     DragEventActuator::MountGatherNode(manager, frameNode, gatherNode, gatherNodeChildrenInfo);
174     actuator->ClearGatherNodeChildrenInfo();
175     actuator->InitGatherNodesPosition(gatherNodeChildrenInfo);
176     pipeline->FlushSyncGeometryNodeTasks();
177     manager->SetIsGatherWithMenu(false);
178     PlayGatherNodeOpacityAnimation(manager);
179     PlayGatherNodeTranslateAnimation(frameNode, manager);
180 }
181 
PlayNodeAnimationBeforeLifting(const RefPtr<FrameNode> & frameNode)182 void DragAnimationHelper::PlayNodeAnimationBeforeLifting(const RefPtr<FrameNode>& frameNode)
183 {
184     CHECK_NULL_VOID(frameNode);
185     auto previewOptions = frameNode->GetDragPreviewOption();
186     if (!previewOptions.defaultAnimationBeforeLifting) {
187         return;
188     }
189     AnimationOption option;
190     option.SetDuration(BEFORE_LIFTING_TIME);
191     auto springCurve = AceType::MakeRefPtr<InterpolatingSpring>(DEFAULT_INTERPOLATING_SPRING_VELOCITY,
192         DEFAULT_INTERPOLATING_SPRING_MASS, DEFAULT_INTERPOLATING_SPRING_STIFFNESS,
193         DEFAULT_INTERPOLATING_SPRING_DAMPING);
194     option.SetCurve(springCurve);
195     auto renderContext = frameNode->GetRenderContext();
196     CHECK_NULL_VOID(renderContext);
197     auto context = frameNode->GetContextRefPtr();
198     CHECK_NULL_VOID(context);
199     renderContext->UpdateTransformScale({ 1.0f, 1.0f });
200 
201     AnimationUtils::Animate(
202         option,
203         [renderContext]() mutable {
204             CHECK_NULL_VOID(renderContext);
205             renderContext->UpdateTransformScale({ DEFAULT_ANIMATION_SCALE, DEFAULT_ANIMATION_SCALE });
206         }, nullptr, nullptr, context);
207 }
208 
PlayNodeResetAnimation(const RefPtr<DragEventActuator> & actuator)209 void DragAnimationHelper::PlayNodeResetAnimation(const RefPtr<DragEventActuator>& actuator)
210 {
211     CHECK_NULL_VOID(actuator);
212     auto frameNode = actuator->GetFrameNode();
213     CHECK_NULL_VOID(frameNode);
214     bool defaultAnimationBeforeLifting = frameNode->GetDragPreviewOption().defaultAnimationBeforeLifting;
215     if (!defaultAnimationBeforeLifting) {
216         return;
217     }
218     auto frameContext = frameNode->GetRenderContext();
219     CHECK_NULL_VOID(frameContext);
220     auto context = frameNode->GetContextRefPtr();
221     CHECK_NULL_VOID(context);
222     auto layoutProperty = frameNode->GetLayoutProperty();
223     if (layoutProperty) {
224         layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
225     }
226     AnimationOption option;
227     option.SetDuration(PIXELMAP_ANIMATION_DURATION);
228     const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.33f, 0.67f, 1.0f);
229     option.SetCurve(curve);
230     AnimationUtils::Animate(
231         option,
232         [frameContext]() mutable {
233             frameContext->UpdateTransformScale({ 1.0f, 1.0f });
234         },
235         option.GetOnFinishEvent(), nullptr, context);
236 }
237 
GetLiftingNodeScale(const RefPtr<RenderContext> & renderContext)238 float DragAnimationHelper::GetLiftingNodeScale(const RefPtr<RenderContext>& renderContext)
239 {
240     CHECK_NULL_RETURN(renderContext, PIXELMAP_DRAG_SCALE_MULTIPLE);
241     VectorF defaultScale = VectorF(PIXELMAP_DRAG_SCALE_MULTIPLE, PIXELMAP_DRAG_SCALE_MULTIPLE);
242     return renderContext->GetTransformScaleValue(defaultScale).x;
243 }
244 
PlayGatherAnimation(const RefPtr<FrameNode> & frameNode,const RefPtr<OverlayManager> & overlayManager)245 void DragAnimationHelper::PlayGatherAnimation(const RefPtr<FrameNode>& frameNode,
246     const RefPtr<OverlayManager>& overlayManager)
247 {
248     TAG_LOGI(AceLogTag::ACE_DRAG, "Play gather animation");
249     CHECK_NULL_VOID(frameNode);
250     auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenter(frameNode);
251     CHECK_NULL_VOID(overlayManager);
252     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
253     BorderRadiusProperty borderRadius;
254     borderRadius.SetRadius(0.0_vp);
255     borderRadius.multiValued = false;
256     for (const auto& child : gatherNodeChildrenInfo) {
257         auto imageNode = child.imageNode.Upgrade();
258         CHECK_NULL_VOID(imageNode);
259         auto imageContext = imageNode->GetRenderContext();
260         CHECK_NULL_VOID(imageContext);
261         imageContext->UpdateBorderRadius(borderRadius);
262     }
263 
264     AnimationOption option;
265     option.SetDuration(PIXELMAP_ANIMATION_DURATION);
266     const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(GATHER_SPRING_RESPONSE,
267         GATHER_SPRING_DAMPING_FRACTION, 0.0f);
268     option.SetCurve(curve);
269     auto geometryNode = frameNode->GetGeometryNode();
270     CHECK_NULL_VOID(geometryNode);
271     auto frameNodeSize = geometryNode->GetFrameSize();
272     auto renderContext = frameNode->GetRenderContext();
273     CHECK_NULL_VOID(renderContext);
274     auto scale = GetLiftingNodeScale(renderContext);
275     GatherAnimationInfo gatherAnimationInfo = { scale, frameNodeSize.Width(),
276         frameNodeSize.Height(), gatherNodeCenter, renderContext->GetBorderRadius() };
277     auto pipeline = frameNode->GetContextRefPtr();
278     CHECK_NULL_VOID(pipeline);
279     AnimationUtils::Animate(
280         option,
281         [weakOverlayManager = AceType::WeakClaim(AceType::RawPtr(overlayManager)), gatherAnimationInfo,
282             weak = AceType::WeakClaim(AceType::RawPtr(frameNode))]() {
283             auto overlayManager = weakOverlayManager.Upgrade();
284             auto frameNode = weak.Upgrade();
285             DragDropManager::UpdateGatherNodeAttr(overlayManager, gatherAnimationInfo);
286             DragDropManager::UpdateGatherNodePosition(overlayManager, frameNode);
287         },
288         option.GetOnFinishEvent(), nullptr, pipeline);
289 }
290 
ShowMenuHideAnimation(const PreparedInfoForDrag & data)291 void DragAnimationHelper::ShowMenuHideAnimation(const PreparedInfoForDrag& data)
292 {
293     if (data.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT) {
294         return;
295     }
296     auto menuNode = data.menuNode;
297     CHECK_NULL_VOID(menuNode);
298     auto menuNodeRenderContext = menuNode->GetRenderContext();
299     CHECK_NULL_VOID(menuNodeRenderContext);
300     if (data.isMenuNotShow) {
301         menuNodeRenderContext->UpdateOpacity(0.0f);
302     } else {
303         MenuView::ExecuteMenuDisappearAnimation(data);
304     }
305 }
306 
ShowBadgeAnimation(const RefPtr<FrameNode> & textNode)307 void DragAnimationHelper::ShowBadgeAnimation(const RefPtr<FrameNode>& textNode)
308 {
309     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
310     CHECK_NULL_VOID(pipelineContext);
311     auto dragDropManager = pipelineContext->GetDragDropManager();
312     CHECK_NULL_VOID(dragDropManager);
313     CHECK_NULL_VOID(textNode);
314     auto textNodeContext = textNode->GetRenderContext();
315     CHECK_NULL_VOID(textNodeContext);
316     auto context = textNode->GetContextRefPtr();
317     CHECK_NULL_VOID(context);
318     textNodeContext->SetVisible(true);
319     auto windowScale = dragDropManager->GetWindowScale();
320     auto badgeScale = GreatNotEqual(windowScale, 0.0f) ? BADGE_ANIMATION_SCALE / windowScale : BADGE_ANIMATION_SCALE;
321     if (!dragDropManager->IsShowBadgeAnimation()) {
322         textNodeContext->UpdateTransformScale({ badgeScale, badgeScale });
323         return;
324     }
325     textNodeContext->UpdateTransformScale({ 0.0f, 0.0f });
326     RefPtr<Curve> interpolatingSpring = AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 628.0f, 40.0f);
327     CHECK_NULL_VOID(interpolatingSpring);
328     AnimationOption textOption;
329     textOption.SetDuration(BADGE_ANIMATION_DURATION);
330     textOption.SetCurve(interpolatingSpring);
331     textOption.SetDelay(BADGE_ANIMATION_DELAY);
332     AnimationUtils::Animate(
333         textOption,
334         [textNodeContext, badgeScale]() mutable {
335             textNodeContext->UpdateTransformScale({ badgeScale, badgeScale });
336         },
337         textOption.GetOnFinishEvent(), nullptr, context);
338 
339     dragDropManager->SetIsShowBadgeAnimation(false);
340 }
341 
CalcBadgeTextOffset(const RefPtr<MenuPattern> & menuPattern,const RefPtr<FrameNode> & imageNode,const RefPtr<PipelineBase> & context,int32_t badgeLength)342 OffsetF DragAnimationHelper::CalcBadgeTextOffset(const RefPtr<MenuPattern>& menuPattern,
343     const RefPtr<FrameNode>& imageNode, const RefPtr<PipelineBase>& context, int32_t badgeLength)
344 {
345     CHECK_NULL_RETURN(imageNode, OffsetF());
346     CHECK_NULL_RETURN(menuPattern, OffsetF());
347     auto offset = imageNode->GetPaintRectOffset();
348     if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
349         double textOffsetX = offset.GetX() - BADGE_RELATIVE_OFFSET.ConvertToPx();
350         double textOffsetY = offset.GetY() - BADGE_RELATIVE_OFFSET.ConvertToPx();
351         return OffsetF(textOffsetX, textOffsetY);
352     }
353     auto width = imageNode->GetGeometryNode()->GetFrameSize().Width();
354     auto scaleAfter = menuPattern->GetPreviewAfterAnimationScale();
355     auto menuTheme = context->GetTheme<NG::MenuTheme>();
356     CHECK_NULL_RETURN(menuTheme, OffsetF());
357     auto previewAfterAnimationScale =
358         LessNotEqual(scaleAfter, 0.0) ? menuTheme->GetPreviewAfterAnimationScale() : scaleAfter;
359     double textOffsetX = offset.GetX() + width * previewAfterAnimationScale -
360         BADGE_RELATIVE_OFFSET.ConvertToPx() - (BADGE_RELATIVE_OFFSET.ConvertToPx() * badgeLength);
361     double textOffsetY = offset.GetY() - BADGE_RELATIVE_OFFSET.ConvertToPx();
362     return OffsetF(textOffsetX, textOffsetY);
363 }
364 
CalcBadgeTextPosition(const RefPtr<MenuPattern> & menuPattern,const RefPtr<OverlayManager> & manager,const RefPtr<FrameNode> & imageNode,const RefPtr<FrameNode> & textNode)365 void DragAnimationHelper::CalcBadgeTextPosition(const RefPtr<MenuPattern>& menuPattern,
366     const RefPtr<OverlayManager>& manager, const RefPtr<FrameNode>& imageNode, const RefPtr<FrameNode>& textNode)
367 {
368     CHECK_NULL_VOID(manager);
369     CHECK_NULL_VOID(textNode);
370     CHECK_NULL_VOID(menuPattern);
371     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
372     CHECK_NULL_VOID(pipelineContext);
373     auto dragDropManager = pipelineContext->GetDragDropManager();
374     CHECK_NULL_VOID(dragDropManager);
375     auto frameNode = FrameNode::GetFrameNode(menuPattern->GetTargetTag(), menuPattern->GetTargetId());
376     CHECK_NULL_VOID(frameNode);
377     auto badgeNumber = frameNode->GetDragPreviewOption().GetCustomerBadgeNumber();
378     auto childSize = badgeNumber.has_value() ? static_cast<size_t>(badgeNumber.value()) :
379                                         manager->GetGatherNodeChildrenInfo().size() + 1;
380     TAG_LOGI(AceLogTag::ACE_DRAG, "Badge node number %{public}d, children count %{public}d",
381         badgeNumber.value_or(-1), static_cast<int32_t>(manager->GetGatherNodeChildrenInfo().size()));
382     auto badgeLength = std::to_string(childSize).size();
383     UpdateBadgeLayoutAndRenderContext(textNode, badgeLength, childSize);
384     auto textRenderContext = textNode->GetRenderContext();
385     CHECK_NULL_VOID(textRenderContext);
386     auto offset = CalcBadgeTextOffset(menuPattern, imageNode, pipelineContext, badgeLength);
387     textRenderContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
388     textNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
389     textNode->MarkModifyDone();
390     textNode->SetLayoutDirtyMarked(true);
391     textNode->SetActive(true);
392     auto context = textNode->GetContext();
393     if (context) {
394         context->FlushUITaskWithSingleDirtyNode(textNode);
395     }
396     pipelineContext->FlushSyncGeometryNodeTasks();
397 }
398 
UpdateBadgeLayoutAndRenderContext(const RefPtr<FrameNode> & textNode,int32_t badgeLength,int32_t childSize)399 void DragAnimationHelper::UpdateBadgeLayoutAndRenderContext(
400     const RefPtr<FrameNode>& textNode, int32_t badgeLength, int32_t childSize)
401 {
402     if (childSize <= 1) {
403         return;
404     }
405     CHECK_NULL_VOID(textNode);
406     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
407     CHECK_NULL_VOID(textLayoutProperty);
408     textLayoutProperty->UpdateContent(std::to_string(childSize));
409     textLayoutProperty->UpdateMaxLines(1);
410     textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
411     textLayoutProperty->UpdateTextColor(BADGE_TEXT_FONT_COLOR);
412     textLayoutProperty->UpdateFontSize(BADGE_TEXT_FONT_SIZE);
413     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
414     int64_t textWidth = BADGE_DEFAULT_SIZE.ConvertToPx() + (BADGE_RELATIVE_OFFSET.ConvertToPx() * (badgeLength - 1));
415     auto textSize = CalcSize(NG::CalcLength(textWidth), NG::CalcLength(BADGE_DEFAULT_SIZE.ConvertToPx()));
416     textLayoutProperty->UpdateUserDefinedIdealSize(textSize);
417     textLayoutProperty->UpdateMinFontScale(1.0f);
418     textLayoutProperty->UpdateMaxFontScale(1.0f);
419     textLayoutProperty->UpdateEnableVariableFontWeight(true);
420 
421     auto textRenderContext = textNode->GetRenderContext();
422     CHECK_NULL_VOID(textRenderContext);
423     textRenderContext->SetVisible(true);
424     textRenderContext->UpdateBackgroundColor(BADGE_BACKGROUND_COLOR);
425     BorderRadiusProperty borderRadius;
426     borderRadius.SetRadius(BADGE_DEFAULT_SIZE);
427     textRenderContext->UpdateBorderRadius(borderRadius);
428 }
429 
UpdateGatherNodeToTop()430 void DragAnimationHelper::UpdateGatherNodeToTop()
431 {
432     auto mainPipeline = PipelineContext::GetMainPipelineContext();
433     CHECK_NULL_VOID(mainPipeline);
434     auto manager = mainPipeline->GetOverlayManager();
435     CHECK_NULL_VOID(manager);
436     manager->UpdateGatherNodeToTop();
437 }
438 
SwapGatherNodeToSubwindowInUIExtension(const RefPtr<FrameNode> & menuWrapperNode)439 void SwapGatherNodeToSubwindowInUIExtension(const RefPtr<FrameNode>& menuWrapperNode)
440 {
441     CHECK_NULL_VOID(menuWrapperNode);
442     auto mainPipeline = PipelineContext::GetMainPipelineContext();
443     CHECK_NULL_VOID(mainPipeline);
444     auto container = AceEngine::Get().GetContainer(mainPipeline->GetInstanceId());
445     CHECK_NULL_VOID(container);
446     if (!container->IsUIExtensionWindow()) {
447         return;
448     }
449     auto manager = mainPipeline->GetOverlayManager();
450     CHECK_NULL_VOID(manager);
451     auto gatherNode = manager->GetGatherNode();
452     CHECK_NULL_VOID(gatherNode);
453     if (gatherNode->GetContextRefPtr() != mainPipeline) {
454         return;
455     }
456     auto rootNode = manager->GetRootNode().Upgrade();
457     CHECK_NULL_VOID(rootNode);
458     auto subwindowRootNode = menuWrapperNode->GetParent();
459     CHECK_NULL_VOID(subwindowRootNode);
460     rootNode->RemoveChild(gatherNode);
461     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
462     subwindowRootNode->AddChildBefore(gatherNode, menuWrapperNode);
463     gatherNode->OnMountToParentDone();
464     subwindowRootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
465 }
466 
ShowGatherAnimationWithMenu(const RefPtr<FrameNode> & menuWrapperNode)467 void DragAnimationHelper::ShowGatherAnimationWithMenu(const RefPtr<FrameNode>& menuWrapperNode)
468 {
469     auto mainPipeline = PipelineContext::GetMainPipelineContext();
470     CHECK_NULL_VOID(mainPipeline);
471     auto manager = mainPipeline->GetOverlayManager();
472     CHECK_NULL_VOID(manager);
473     manager->SetIsGatherWithMenu(true);
474 
475     mainPipeline->AddAfterRenderTask([weakWrapperNode = AceType::WeakClaim(AceType::RawPtr(menuWrapperNode)),
476         weakManager = AceType::WeakClaim(AceType::RawPtr(manager))]() {
477         auto menuWrapperNode = weakWrapperNode.Upgrade();
478         CHECK_NULL_VOID(menuWrapperNode);
479         SwapGatherNodeToSubwindowInUIExtension(menuWrapperNode);
480         auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
481         CHECK_NULL_VOID(menuWrapperPattern);
482         auto manager = weakManager.Upgrade();
483         auto textNode = menuWrapperPattern->GetBadgeNode();
484         auto imageNode = menuWrapperPattern->GetPreview();
485         auto menuNode = menuWrapperPattern->GetMenu();
486         CHECK_NULL_VOID(menuNode);
487         auto menuPattern = menuNode->GetPattern<MenuPattern>();
488         DragAnimationHelper::HideDragNodeCopy(manager);
489         DragAnimationHelper::PlayGatherAnimation(imageNode, manager);
490         DragAnimationHelper::CalcBadgeTextPosition(menuPattern, manager, imageNode, textNode);
491         DragAnimationHelper::ShowBadgeAnimation(textNode);
492     });
493 }
494 
SetPreOpacity(const RefPtr<FrameNode> & preNode)495 void DragAnimationHelper::SetPreOpacity(const RefPtr<FrameNode>& preNode)
496 {
497     auto grayedOpacity = preNode->GetPreGrayedOpacity();
498     DoGrayedAnimation(preNode, grayedOpacity, DRAG_END_ANIMATION_CURVE);
499 }
500 
DoDragStartGrayedAnimation(const RefPtr<FrameNode> & frameNode)501 void DragAnimationHelper::DoDragStartGrayedAnimation(const RefPtr<FrameNode>& frameNode)
502 {
503     CHECK_NULL_VOID(frameNode);
504     auto renderContext = frameNode->GetRenderContext();
505     CHECK_NULL_VOID(renderContext);
506     float opacity = 1.0f;
507     if (renderContext->HasOpacity()) {
508         opacity = renderContext->GetOpacityValue();
509         frameNode->SetPreGrayedOpacity(opacity);
510     }
511     DoGrayedAnimation(frameNode, opacity * DEFAULT_GRAYED, DRAG_START_ANIMATION_CURVE);
512 }
513 
DoGrayedAnimation(const RefPtr<FrameNode> & frameNode,float opacity,RefPtr<InterpolatingSpring> cure)514 void DragAnimationHelper::DoGrayedAnimation(
515     const RefPtr<FrameNode>& frameNode, float opacity, RefPtr<InterpolatingSpring> cure)
516 {
517     CHECK_NULL_VOID(frameNode);
518     auto frameTag = frameNode->GetTag();
519     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
520     CHECK_NULL_VOID(gestureHub);
521     auto context = frameNode->GetContextRefPtr();
522     CHECK_NULL_VOID(context);
523     if (gestureHub->IsTextCategoryComponent(frameTag)) {
524         return;
525     }
526     AnimationOption option;
527     option.SetCurve(cure);
528     AnimationUtils::Animate(
529         option, [frameNode, opacity]() { ACE_UPDATE_NODE_RENDER_CONTEXT(Opacity, opacity, frameNode); },
530         option.GetOnFinishEvent(), nullptr, context);
531 }
532 
CreateImageNode(const RefPtr<PixelMap> & pixelMap)533 RefPtr<FrameNode> DragAnimationHelper::CreateImageNode(const RefPtr<PixelMap>& pixelMap)
534 {
535     CHECK_NULL_RETURN(pixelMap, nullptr);
536     auto width = pixelMap->GetWidth();
537     auto height = pixelMap->GetHeight();
538     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
539         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
540     CHECK_NULL_RETURN(imageNode, nullptr);
541     auto renderProps = imageNode->GetPaintProperty<ImageRenderProperty>();
542     CHECK_NULL_RETURN(renderProps, nullptr);
543     renderProps->UpdateImageInterpolation(ImageInterpolation::HIGH);
544     renderProps->UpdateNeedBorderRadius(false);
545     auto props = imageNode->GetLayoutProperty<ImageLayoutProperty>();
546     CHECK_NULL_RETURN(props, nullptr);
547     props->UpdateAutoResize(false);
548     props->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
549     auto targetSize = CalcSize(NG::CalcLength(width), NG::CalcLength(height));
550     props->UpdateUserDefinedIdealSize(targetSize);
551     auto imageContext = imageNode->GetRenderContext();
552     CHECK_NULL_RETURN(imageContext, nullptr);
553     Vector5F rotate = Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
554     imageContext->UpdateTransformRotate(rotate);
555     imageContext->UpdateClipEdge(true);
556     imageContext->UpdateBorderRadius(BorderRadiusProperty(Dimension()));
557     imageContext->UpdateOpacity(1.0f);
558     auto imagePattern = imageNode->GetPattern<ImagePattern>();
559     if (imagePattern) {
560         imagePattern->SetSyncLoad(true);
561     }
562     ClickEffectInfo clickEffectInfo;
563     clickEffectInfo.level = ClickEffectLevel::LIGHT;
564     clickEffectInfo.scaleNumber = DEFAULT_ANIMATION_SCALE;
565     imageContext->UpdateClickEffectLevel(clickEffectInfo);
566     return imageNode;
567 }
568 
CreateGatherNode(const RefPtr<FrameNode> & frameNode,std::vector<GatherNodeChildInfo> & gatherNodeInfo)569 RefPtr<FrameNode> DragAnimationHelper::CreateGatherNode(const RefPtr<FrameNode>& frameNode,
570     std::vector<GatherNodeChildInfo>& gatherNodeInfo)
571 {
572     CHECK_NULL_RETURN(frameNode, nullptr);
573     auto parentNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
574     CHECK_NULL_RETURN(parentNode, nullptr);
575     auto scrollPattern = parentNode->GetPattern<ScrollablePattern>();
576     CHECK_NULL_RETURN(scrollPattern, nullptr);
577     auto children = scrollPattern->GetVisibleSelectedItems();
578     if (children.empty()) {
579         return nullptr;
580     }
581 
582     auto stackNode = FrameNode::GetOrCreateFrameNode(V2::STACK_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
583         []() { return AceType::MakeRefPtr<StackPattern>(); });
584     CHECK_NULL_RETURN(stackNode, nullptr);
585     auto geometryNode = stackNode->GetGeometryNode();
586     CHECK_NULL_RETURN(geometryNode, nullptr);
587     geometryNode->SetFrameOffset({0.0f, 0.0f});
588     gatherNodeInfo.clear();
589     for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
590         auto itemFrameNode = (*iter);
591         if (itemFrameNode == frameNode) {
592             continue;
593         }
594         GatherNodeChildInfo gatherNodeChildInfo;
595         auto imageNode = CreateGatherImageNode(itemFrameNode, gatherNodeChildInfo);
596         if (!imageNode) {
597             TAG_LOGW(AceLogTag::ACE_DRAG, "Create gather image node failed");
598             continue;
599         }
600         stackNode->AddChild(imageNode);
601         gatherNodeInfo.push_back(gatherNodeChildInfo);
602     }
603     TAG_LOGI(AceLogTag::ACE_DRAG, "Create gather node success, count %{public}d",
604         static_cast<int32_t>(children.size()));
605     return stackNode;
606 }
607 
GetOrCreateGatherNode(const RefPtr<NG::OverlayManager> & overlayManager,const RefPtr<DragEventActuator> & actuator,std::vector<GatherNodeChildInfo> & info)608 RefPtr<FrameNode> DragAnimationHelper::GetOrCreateGatherNode(const RefPtr<NG::OverlayManager>& overlayManager,
609     const RefPtr<DragEventActuator>& actuator, std::vector<GatherNodeChildInfo>& info)
610 {
611     CHECK_NULL_RETURN(actuator, nullptr);
612     if (!actuator->IsNeedGather()) {
613         return nullptr;
614     }
615     auto frameNode = actuator->GetFrameNode();
616     CHECK_NULL_RETURN(frameNode, nullptr);
617     auto previewOptions = frameNode->GetDragPreviewOption();
618     if (!previewOptions.isMultiSelectionEnabled) {
619         return nullptr;
620     }
621     CHECK_NULL_RETURN(overlayManager, nullptr);
622     auto gatherNode = overlayManager->GetGatherNode();
623     if (!gatherNode) {
624         gatherNode = CreateGatherNode(frameNode, info);
625         if (gatherNode) {
626             MarkDirtyNode(gatherNode);
627         }
628         return gatherNode;
629     } else {
630         info = overlayManager->GetGatherNodeChildrenInfo();
631         overlayManager->RemoveGatherNode();
632     }
633     return gatherNode;
634 }
635 
CreateGatherImageNode(const RefPtr<FrameNode> & frameNode,GatherNodeChildInfo & gatherNodeChildInfo)636 RefPtr<FrameNode> DragAnimationHelper::CreateGatherImageNode(const RefPtr<FrameNode>& frameNode,
637     GatherNodeChildInfo& gatherNodeChildInfo)
638 {
639     CHECK_NULL_RETURN(frameNode, nullptr);
640     auto pixelMap = DragDropFuncWrapper::GetGatherNodePreviewPixelMap(frameNode);
641     CHECK_NULL_RETURN(pixelMap, nullptr);
642     int32_t width = pixelMap->GetWidth();
643     int32_t height = pixelMap->GetHeight();
644     auto offset = DragDropFuncWrapper::GetPaintRectCenter(frameNode) - OffsetF(width / 2.0f, height / 2.0f);
645     auto imageNode = CreateImageNode(pixelMap);
646     CHECK_NULL_RETURN(imageNode, nullptr);
647     auto imageContext = imageNode->GetRenderContext();
648     CHECK_NULL_RETURN(imageContext, nullptr);
649     imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
650 
651     gatherNodeChildInfo = { imageNode,
652         offset + DragDropFuncWrapper::GetCurrentWindowOffset(frameNode->GetContextRefPtr()), width, height,
653         width / 2.0f, height / 2.0f, WeakPtr<FrameNode>(frameNode) };
654     return imageNode;
655 }
656 
MountGatherNode(const RefPtr<OverlayManager> & overlayManager,const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & gatherNode,const std::vector<GatherNodeChildInfo> & gatherNodeInfo)657 void DragAnimationHelper::MountGatherNode(const RefPtr<OverlayManager>& overlayManager,
658     const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& gatherNode,
659     const std::vector<GatherNodeChildInfo>& gatherNodeInfo)
660 {
661     if (!overlayManager || !frameNode || !gatherNode) {
662         return;
663     }
664     TAG_LOGI(AceLogTag::ACE_DRAG, "Mount gather node");
665     auto container = Container::Current();
666     if (container && container->IsSceneBoardWindow()) {
667         auto windowScene = overlayManager->FindWindowScene(frameNode);
668         overlayManager->MountGatherNodeToWindowScene(gatherNode, gatherNodeInfo, windowScene);
669     } else {
670         overlayManager->MountGatherNodeToRootNode(gatherNode, gatherNodeInfo);
671     }
672 }
673 
MarkDirtyNode(const RefPtr<FrameNode> & frameNode)674 void DragAnimationHelper::MarkDirtyNode(const RefPtr<FrameNode>& frameNode)
675 {
676     CHECK_NULL_VOID(frameNode);
677     frameNode->MarkModifyDone();
678     frameNode->SetLayoutDirtyMarked(true);
679     auto context = frameNode->GetContext();
680     if (context) {
681         context->FlushUITaskWithSingleDirtyNode(frameNode);
682     }
683 
684     auto children = frameNode->GetChildren();
685     for (const auto& child : children) {
686         CHECK_NULL_VOID(child);
687         auto frameNode = AceType::DynamicCast<FrameNode>(child);
688         CHECK_NULL_VOID(frameNode);
689         MarkDirtyNode(frameNode);
690     }
691 }
692 
InitGatherNodeAttr(const RefPtr<FrameNode> & gatherNode,const std::vector<GatherNodeChildInfo> & gatherNodeInfo)693 void DragAnimationHelper::InitGatherNodeAttr(const RefPtr<FrameNode>& gatherNode,
694     const std::vector<GatherNodeChildInfo>& gatherNodeInfo)
695 {
696     CHECK_NULL_VOID(gatherNode);
697     auto renderContext = gatherNode->GetRenderContext();
698     if (renderContext) {
699         renderContext->UpdatePosition(OffsetT<Dimension>(Dimension(0.0f), Dimension(0.0f)));
700     }
701     for (auto childInfo : gatherNodeInfo) {
702         auto imageNode = childInfo.imageNode.Upgrade();
703         DragDropFuncWrapper::UpdateNodePositionToScreen(imageNode, childInfo.offset);
704     }
705 }
706 
ShowGatherNodeAnimation(const RefPtr<FrameNode> & frameNode)707 bool DragAnimationHelper::ShowGatherNodeAnimation(const RefPtr<FrameNode>& frameNode)
708 {
709     TAG_LOGI(AceLogTag::ACE_DRAG, "Show gather node animation");
710     CHECK_NULL_RETURN(frameNode, false);
711     auto pipeline = frameNode->GetContextRefPtr();
712     CHECK_NULL_RETURN(pipeline, false);
713     auto manager = pipeline->GetOverlayManager();
714     CHECK_NULL_RETURN(manager, false);
715 
716     if (manager->GetHasGatherNode()) {
717         TAG_LOGW(AceLogTag::ACE_DRAG, "Not need create gather node, already have");
718         return false;
719     }
720 
721     //create gather node
722     std::vector<GatherNodeChildInfo> gatherNodeInfo;
723     auto gatherNode = CreateGatherNode(frameNode, gatherNodeInfo);
724     CHECK_NULL_RETURN(gatherNode, false);
725     MountGatherNode(manager, frameNode, gatherNode, gatherNodeInfo);
726     InitGatherNodeAttr(gatherNode, gatherNodeInfo);
727     AddDragNodeCopy(manager, frameNode, gatherNode);
728     MarkDirtyNode(gatherNode);
729 
730     pipeline->FlushPipelineImmediately();
731     manager->SetIsGatherWithMenu(false);
732 
733     //do gather animation before lifting
734     PlayGatherNodeOpacityAnimation(manager);
735     PlayGatherNodeTranslateAnimation(frameNode, manager);
736     ShowDragNodeCopyAnimation(manager, frameNode);
737     return true;
738 }
739 
AddDragNodeCopy(const RefPtr<OverlayManager> & overlayManager,const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & gatherNode)740 void DragAnimationHelper::AddDragNodeCopy(const RefPtr<OverlayManager>& overlayManager,
741     const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& gatherNode)
742 {
743     CHECK_NULL_VOID(frameNode);
744     CHECK_NULL_VOID(gatherNode);
745     CHECK_NULL_VOID(overlayManager);
746     //create frameNode copy
747     auto renderContext = frameNode->GetRenderContext();
748     CHECK_NULL_VOID(renderContext);
749     auto pixelMap = renderContext->GetThumbnailPixelMap(true, false);
750     CHECK_NULL_VOID(pixelMap);
751     auto dragNodeCopy = CreateImageNode(pixelMap);
752     CHECK_NULL_VOID(dragNodeCopy);
753 
754     //mount to gatherNode
755     gatherNode->AddChild(dragNodeCopy);
756     overlayManager->SetDragNodeCopy(dragNodeCopy);
757 
758     //update position
759     int32_t width = pixelMap->GetWidth();
760     int32_t height = pixelMap->GetHeight();
761     auto offset = DragDropFuncWrapper::GetPaintRectCenter(frameNode) -
762         OffsetF(width / HALF_DIVIDE, height / HALF_DIVIDE);
763     DragDropFuncWrapper::UpdateNodePositionToWindow(dragNodeCopy, offset);
764     auto copyNodeRenderContext = dragNodeCopy->GetRenderContext();
765     CHECK_NULL_VOID(copyNodeRenderContext);
766     copyNodeRenderContext->UpdateTransformScale({ 1.0f, 1.0f });
767 }
768 
ShowDragNodeCopyAnimation(const RefPtr<OverlayManager> & overlayManager,const RefPtr<FrameNode> & frameNode)769 void DragAnimationHelper::ShowDragNodeCopyAnimation(const RefPtr<OverlayManager>& overlayManager,
770     const RefPtr<FrameNode>& frameNode)
771 {
772     CHECK_NULL_VOID(frameNode);
773     CHECK_NULL_VOID(overlayManager);
774     auto dragNodeCopy = overlayManager->GetDragNodeCopy();
775     CHECK_NULL_VOID(dragNodeCopy);
776     auto previewOptions = frameNode->GetDragPreviewOption();
777     if (!previewOptions.defaultAnimationBeforeLifting) {
778         return;
779     }
780     auto layoutProperty = frameNode->GetLayoutProperty();
781     if (layoutProperty) {
782         layoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
783     }
784     auto renderContext = dragNodeCopy->GetRenderContext();
785     CHECK_NULL_VOID(renderContext);
786     auto context = dragNodeCopy->GetContextRefPtr();
787     CHECK_NULL_VOID(context);
788     AnimationOption option;
789     option.SetDuration(BEFORE_LIFTING_TIME);
790     auto springCurve = AceType::MakeRefPtr<InterpolatingSpring>(DEFAULT_INTERPOLATING_SPRING_VELOCITY,
791         DEFAULT_INTERPOLATING_SPRING_MASS, DEFAULT_INTERPOLATING_SPRING_STIFFNESS,
792         DEFAULT_INTERPOLATING_SPRING_DAMPING);
793     option.SetCurve(springCurve);
794     AnimationUtils::Animate(
795         option,
796         [renderContext]() mutable {
797             CHECK_NULL_VOID(renderContext);
798             renderContext->UpdateTransformScale({ DEFAULT_ANIMATION_SCALE, DEFAULT_ANIMATION_SCALE });
799         },
800         option.GetOnFinishEvent(), nullptr, context
801     );
802 }
803 
HideDragNodeCopyWithAnimation(const RefPtr<OverlayManager> & overlayManager,const RefPtr<FrameNode> & frameNode)804 void DragAnimationHelper::HideDragNodeCopyWithAnimation(const RefPtr<OverlayManager>& overlayManager,
805     const RefPtr<FrameNode>& frameNode)
806 {
807     CHECK_NULL_VOID(frameNode);
808     CHECK_NULL_VOID(overlayManager);
809     auto dragNodeCopy = overlayManager->GetDragNodeCopy();
810     auto defaultAnimation = frameNode->GetDragPreviewOption().defaultAnimationBeforeLifting;
811     if (!dragNodeCopy) {
812         auto layoutProperty = frameNode->GetLayoutProperty();
813         if (layoutProperty && defaultAnimation) {
814             layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
815         }
816         return;
817     }
818     auto renderContext = dragNodeCopy->GetRenderContext();
819     CHECK_NULL_VOID(renderContext);
820     auto context = dragNodeCopy->GetContextRefPtr();
821     CHECK_NULL_VOID(context);
822     AnimationOption option;
823     option.SetDuration(NODE_RESET_DURATION);
824     option.SetCurve(Curves::SHARP);
825     option.SetOnFinishEvent([renderContext, weak = AceType::WeakClaim(AceType::RawPtr(frameNode)),
826         defaultAnimation]() {
827         auto frameNode = weak.Upgrade();
828         if (frameNode) {
829             auto layoutProperty = frameNode->GetLayoutProperty();
830             if (layoutProperty && defaultAnimation) {
831                 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
832             }
833         }
834         if (renderContext) {
835             renderContext->UpdateOpacity(0.0f);
836         }
837     });
838 
839     AnimationUtils::Animate(
840         option,
841         [renderContext]() mutable {
842             CHECK_NULL_VOID(renderContext);
843             renderContext->UpdateTransformScale({ 1.0, 1.0f });
844         },
845         option.GetOnFinishEvent(), nullptr, context
846     );
847 }
848 
HideDragNodeCopy(const RefPtr<OverlayManager> & overlayManager)849 void DragAnimationHelper::HideDragNodeCopy(const RefPtr<OverlayManager>& overlayManager)
850 {
851     CHECK_NULL_VOID(overlayManager);
852     auto dragNodeCopy = overlayManager->GetDragNodeCopy();
853     CHECK_NULL_VOID(dragNodeCopy);
854     auto renderContext = dragNodeCopy->GetRenderContext();
855     CHECK_NULL_VOID(renderContext);
856     renderContext->UpdateOpacity(0.0f);
857 }
858 
UpdateBadgeTextNodePosition(const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & textNode,int32_t childSize,float previewScale,OffsetF previewOffset)859 void DragAnimationHelper::UpdateBadgeTextNodePosition(const RefPtr<FrameNode>& frameNode,
860     const RefPtr<FrameNode>& textNode, int32_t childSize, float previewScale, OffsetF previewOffset)
861 {
862     if (childSize <= 1) {
863         return;
864     }
865     CHECK_NULL_VOID(frameNode);
866     CHECK_NULL_VOID(textNode);
867     auto textRenderContext = textNode->GetRenderContext();
868     CHECK_NULL_VOID(textRenderContext);
869     auto pixelMap = frameNode->GetDragPixelMap();
870     CHECK_NULL_VOID(pixelMap);
871     auto width = pixelMap->GetWidth();
872     auto height = pixelMap->GetHeight();
873     auto offset = previewOffset.NonOffset()
874                       ? DragDropFuncWrapper::GetFrameNodeOffsetToWindow(textNode, frameNode, width, height)
875                       : previewOffset;
876     auto badgeLength = std::to_string(childSize).size();
877     double textOffsetX = 0.0f;
878     double textOffsetY = 0.0f;
879     if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
880         textOffsetX = offset.GetX() - BADGE_RELATIVE_OFFSET.ConvertToPx() - width * (previewScale - 1) / HALF_DIVIDE;
881         textOffsetY = offset.GetY() - BADGE_RELATIVE_OFFSET.ConvertToPx() - height * (previewScale - 1) / HALF_DIVIDE;
882     } else {
883         textOffsetX = offset.GetX() + width * (previewScale + 1) / HALF_DIVIDE - BADGE_RELATIVE_OFFSET.ConvertToPx() -
884             (BADGE_RELATIVE_OFFSET.ConvertToPx() * badgeLength);
885         textOffsetY = offset.GetY() - height * (previewScale - 1) / HALF_DIVIDE - BADGE_RELATIVE_OFFSET.ConvertToPx();
886     }
887     textRenderContext->UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
888     textRenderContext->UpdatePosition(OffsetT<Dimension>(Dimension(textOffsetX), Dimension(textOffsetY)));
889 }
890 
CreateBadgeTextNode(int32_t childSize)891 RefPtr<FrameNode> DragAnimationHelper::CreateBadgeTextNode(int32_t childSize)
892 {
893     if (childSize <= 1) {
894         return nullptr;
895     }
896     auto textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
897         []() { return AceType::MakeRefPtr<TextPattern>(); });
898     CHECK_NULL_RETURN(textNode, nullptr);
899     auto badgeLength = std::to_string(childSize).size();
900     DragAnimationHelper::UpdateBadgeLayoutAndRenderContext(textNode, badgeLength, childSize);
901 
902     textNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
903     textNode->MarkModifyDone();
904     textNode->SetLayoutDirtyMarked(true);
905     textNode->SetActive(true);
906     return textNode;
907 }
908 
ShowPreviewBadgeAnimation(const RefPtr<GestureEventHub> & gestureHub,const RefPtr<OverlayManager> & manager)909 void DragAnimationHelper::ShowPreviewBadgeAnimation(
910     const RefPtr<GestureEventHub>& gestureHub, const RefPtr<OverlayManager>& manager)
911 {
912     CHECK_NULL_VOID(gestureHub);
913     auto frameNode = gestureHub->GetFrameNode();
914     CHECK_NULL_VOID(frameNode);
915     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
916     auto badgeNumber = dragPreviewOptions.GetCustomerBadgeNumber();
917     int32_t childSize = badgeNumber.has_value() ? badgeNumber.value()
918                                                 : static_cast<int32_t>(manager->GetGatherNodeChildrenInfo().size()) + 1;
919     auto textNode = DragAnimationHelper::CreateBadgeTextNode(childSize);
920     CHECK_NULL_VOID(textNode);
921     auto column = manager->GetPixelMapNode();
922     CHECK_NULL_VOID(column);
923     column->AddChild(textNode);
924 
925     DragAnimationHelper::UpdateBadgeTextNodePosition(frameNode, textNode, childSize, PIXELMAP_DRAG_SCALE_MULTIPLE);
926     DragAnimationHelper::ShowBadgeAnimation(textNode);
927 }
928 
929 // update ImageNode default attr before floating
SetImageNodeInitAttr(const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & imageNode)930 void DragAnimationHelper::SetImageNodeInitAttr(const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& imageNode)
931 {
932     CHECK_NULL_VOID(imageNode);
933     CHECK_NULL_VOID(frameNode);
934     auto imageContext = imageNode->GetRenderContext();
935     CHECK_NULL_VOID(imageContext);
936     auto dragPreviewOption = frameNode->GetDragPreviewOption();
937 
938     // update default scale
939     imageContext->UpdateTransformScale({ 1.0f, 1.0f });
940 
941     // update shadow
942     auto shadow = Shadow::CreateShadow(ShadowStyle::None);
943     if (dragPreviewOption.options.shadow.has_value()) {
944         shadow = dragPreviewOption.options.shadow.value();
945         shadow.SetColor(Color(0x00000000));
946     }
947     imageContext->UpdateBackShadow(shadow);
948 
949     // update radius
950     auto borderRadius = DragDropFuncWrapper::GetDragFrameNodeBorderRadius(frameNode);
951     imageContext->UpdateBorderRadius(borderRadius);
952 
953     // update opacity
954     imageContext->UpdateOpacity(1.0f);
955 }
956 
SetImageNodeFinishAttr(const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & imageNode)957 void DragAnimationHelper::SetImageNodeFinishAttr(const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& imageNode)
958 {
959     CHECK_NULL_VOID(imageNode);
960     CHECK_NULL_VOID(frameNode);
961     auto imageContext = imageNode->GetRenderContext();
962     CHECK_NULL_VOID(imageContext);
963     auto dragPreviewOption = frameNode->GetDragPreviewOption();
964     if (dragPreviewOption.options.shadow.has_value() && !dragPreviewOption.options.shadow->GetIsFilled()) {
965         imageContext->UpdateBackShadow(dragPreviewOption.options.shadow.value());
966     }
967 }
968 
PreLayout(const RefPtr<FrameNode> & imageNode)969 void DragAnimationHelper::PreLayout(const RefPtr<FrameNode>& imageNode)
970 {
971     CHECK_NULL_VOID(imageNode);
972     auto subwindowContext = imageNode->GetContext();
973     if (subwindowContext) {
974         subwindowContext->FlushSyncGeometryNodeTasks();
975         subwindowContext->PreLayout(subwindowContext->GetTimeFromExternalTimer(), 0);
976     }
977 }
978 
SetNodeVisible(const RefPtr<FrameNode> & frameNode,bool visible)979 void DragAnimationHelper::SetNodeVisible(const RefPtr<FrameNode>& frameNode, bool visible)
980 {
981     CHECK_NULL_VOID(frameNode);
982     auto renderContext = frameNode->GetRenderContext();
983     CHECK_NULL_VOID(renderContext);
984     renderContext->SetVisible(visible);
985 }
986 
DragStartAnimation(const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,const OffsetF & gatherNodeCenter,Point point,int32_t containerId)987 void DragAnimationHelper::DragStartAnimation(const Offset& newOffset, const RefPtr<OverlayManager>& overlayManager,
988     const OffsetF& gatherNodeCenter, Point point, int32_t containerId)
989 {
990     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
991     CHECK_NULL_VOID(pipelineContext);
992     auto dragDropManager = pipelineContext->GetDragDropManager();
993     CHECK_NULL_VOID(dragDropManager);
994     AnimationOption option;
995     constexpr int32_t animateDuration = 300;
996     option.SetCurve(DRAG_CONTROL_ANIMATION_CURVE);
997     option.SetDuration(animateDuration);
998     option.SetOnFinishEvent([weakManager = AceType::WeakClaim(AceType::RawPtr(dragDropManager)), containerId]() {
999        auto dragDropManager = weakManager.Upgrade();
1000        dragDropManager->SetStartAnimation(true);
1001        if (dragDropManager && !dragDropManager->IsPullMoveReceivedForCurrentDrag()) {
1002            DragControllerFuncWrapper::TransDragWindowToDragFwk(containerId);
1003        }
1004     });
1005     auto imageNode = dragDropManager->GetDragPreviewInfo().imageNode;
1006     CHECK_NULL_VOID(imageNode);
1007     auto renderContext = imageNode->GetRenderContext();
1008     CHECK_NULL_VOID(renderContext);
1009     auto context = imageNode->GetContextRefPtr();
1010     CHECK_NULL_VOID(context);
1011     AnimationUtils::Animate(
1012         option,
1013         [renderContext, info = dragDropManager->GetDragPreviewInfo(), newOffset, overlayManager,
1014             dragDropManager, gatherNodeCenter]() {
1015                 CHECK_NULL_VOID(renderContext);
1016                 renderContext->UpdateTransformScale({ info.scale, info.scale });
1017                 renderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
1018                 GatherAnimationInfo gatherAnimationInfo = { info.scale, info.width, info.height,
1019                     gatherNodeCenter, renderContext->GetBorderRadius() };
1020                 dragDropManager->UpdateGatherNodeAttr(overlayManager, gatherAnimationInfo);
1021                 dragDropManager->UpdateTextNodePosition(info.textNode, newOffset);
1022         },
1023         option.GetOnFinishEvent(), nullptr, context);
1024 }
1025 
InitImageNodeProperties(const RefPtr<FrameNode> & imageNode,const RefPtr<PixelMap> & pixelMap)1026 void DragAnimationHelper::InitImageNodeProperties(const RefPtr<FrameNode>& imageNode, const RefPtr<PixelMap>& pixelMap)
1027 {
1028     CHECK_NULL_VOID(imageNode);
1029     auto renderProps = imageNode->GetPaintProperty<ImageRenderProperty>();
1030     CHECK_NULL_VOID(renderProps);
1031     renderProps->UpdateImageInterpolation(ImageInterpolation::HIGH);
1032     auto props = imageNode->GetLayoutProperty<ImageLayoutProperty>();
1033     props->UpdateAutoResize(false);
1034     props->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
1035     auto targetSize = CalcSize(NG::CalcLength(pixelMap->GetWidth()), NG::CalcLength(pixelMap->GetHeight()));
1036     props->UpdateUserDefinedIdealSize(targetSize);
1037 
1038     auto imagePattern = imageNode->GetPattern<ImagePattern>();
1039     CHECK_NULL_VOID(imagePattern);
1040     imagePattern->SetSyncLoad(true);
1041 }
1042 
CreatePreviewNode(const RefPtr<FrameNode> & frameNode,RefPtr<FrameNode> & imageNode,float dragPreviewScale,PreparedInfoForDrag & data)1043 void DragAnimationHelper::CreatePreviewNode(const RefPtr<FrameNode>& frameNode, RefPtr<FrameNode>& imageNode,
1044     float dragPreviewScale, PreparedInfoForDrag& data)
1045 {
1046     CHECK_NULL_VOID(frameNode);
1047     auto pixelMap = frameNode->GetDragPixelMap();
1048     CHECK_NULL_VOID(pixelMap);
1049     auto center = DragDropFuncWrapper::GetPaintRectCenter(frameNode);
1050     auto frameOffset = OffsetF(0, 0);
1051     imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1052         []() { return AceType::MakeRefPtr<ImagePattern>(); });
1053     CHECK_NULL_VOID(imageNode);
1054     imageNode->SetDragPreviewOptions(frameNode->GetDragPreviewOption());
1055 
1056     InitImageNodeProperties(imageNode, pixelMap);
1057 
1058     if (data.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT && data.badgeNumber <= 1) {
1059         frameOffset =
1060                 OffsetF(center.GetX() - (pixelMap->GetWidth() / 2.0f), center.GetY() - (pixelMap->GetHeight() / 2.0f));
1061         DragEventActuator::UpdatePreviewPositionAndScale(imageNode, frameOffset, dragPreviewScale);
1062     }
1063     if (data.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
1064             data.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION || data.badgeNumber > 1) {
1065         frameOffset = OffsetF(center.GetX() - (data.originPreviewRect.Width() / 2.0f),
1066             center.GetY() - (data.originPreviewRect.Height() / 2.0f));
1067         CHECK_NULL_VOID(data.relativeContainerNode);
1068         auto relativeContainerRenderContext = data.relativeContainerNode->GetRenderContext();
1069         CHECK_NULL_VOID(relativeContainerRenderContext);
1070         relativeContainerRenderContext->UpdatePosition(
1071             OffsetT<Dimension>(Dimension(frameOffset.GetX()), Dimension(frameOffset.GetY())));
1072         data.relativeContainerNode->SetDragPreviewOptions(frameNode->GetDragPreviewOption());
1073         if (data.badgeNumber > 1 && data.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT) {
1074             auto imageNodeLayoutProperty = imageNode->GetLayoutProperty();
1075             CHECK_NULL_VOID(imageNodeLayoutProperty);
1076             imageNodeLayoutProperty->UpdateUserDefinedIdealSize(
1077                 { CalcLength(data.originPreviewRect.Width(), DimensionUnit::PX),
1078                     CalcLength(data.originPreviewRect.Height(), DimensionUnit::PX) });
1079             imageNodeLayoutProperty->UpdateAlignRules(
1080                 { { AlignDirection::TOP, { .anchor = "__container__", .vertical = VerticalAlign::TOP } },
1081                     { AlignDirection::RIGHT, { .anchor = "__container__", .horizontal = HorizontalAlign::END } } });
1082         }
1083     }
1084     DragEventActuator::UpdatePreviewAttr(frameNode, imageNode);
1085 }
1086 
MountPixelMapWithBadge(const PreparedInfoForDrag & data,const RefPtr<FrameNode> & columnNode)1087 void DragAnimationHelper::MountPixelMapWithBadge(const PreparedInfoForDrag& data, const RefPtr<FrameNode>& columnNode)
1088 {
1089     if (!data.textRowNode) {
1090         columnNode->AddChild(data.imageNode);
1091         return;
1092     }
1093 
1094     CHECK_NULL_VOID(data.relativeContainerNode);
1095     data.relativeContainerNode->AddChild(data.imageNode);
1096     data.relativeContainerNode->AddChild(data.textRowNode);
1097     columnNode->AddChild(data.relativeContainerNode);
1098 }
1099 
MountPixelMap(const RefPtr<OverlayManager> & manager,const RefPtr<GestureEventHub> & gestureHub,PreparedInfoForDrag & data,bool isDragPixelMap)1100 void DragAnimationHelper::MountPixelMap(const RefPtr<OverlayManager>& manager,
1101     const RefPtr<GestureEventHub>& gestureHub, PreparedInfoForDrag& data, bool isDragPixelMap)
1102 {
1103     CHECK_NULL_VOID(manager);
1104     CHECK_NULL_VOID(data.imageNode);
1105     CHECK_NULL_VOID(gestureHub);
1106     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1107         AceType::MakeRefPtr<LinearLayoutPattern>(true));
1108     CHECK_NULL_VOID(columnNode);
1109     if (data.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT) {
1110         MountPixelMapWithBadge(data, columnNode);
1111     }
1112     if ((data.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
1113             data.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION)) {
1114         MountPixelMapSizeContentTransition(data, columnNode);
1115     }
1116     auto hub = columnNode->GetOrCreateGestureEventHub();
1117     CHECK_NULL_VOID(hub);
1118     hub->SetPixelMap(gestureHub->GetPixelMap());
1119     manager->MountPixelMapToRootNode(columnNode, isDragPixelMap);
1120     DragEventActuator::SetPreviewDefaultAnimateProperty(data.imageNode);
1121     columnNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
1122     columnNode->MarkModifyDone();
1123     columnNode->SetActive(true);
1124     auto renderContext = columnNode->GetRenderContext();
1125     if (renderContext) {
1126         renderContext->MarkUiFirstNode(false);
1127         renderContext->UpdatePosition(OffsetT<Dimension>(Dimension(0.0f), Dimension(0.0f)));
1128     }
1129     MarkDirtyNode(columnNode);
1130 
1131     if (!isDragPixelMap) {
1132         auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
1133         CHECK_NULL_VOID(pipeline);
1134         pipeline->FlushSyncGeometryNodeTasks();
1135     }
1136 }
1137 
MountPixelMapSizeContentTransition(PreparedInfoForDrag & data,const RefPtr<FrameNode> & columnNode)1138 void DragAnimationHelper::MountPixelMapSizeContentTransition(
1139     PreparedInfoForDrag& data, const RefPtr<FrameNode>& columnNode)
1140 {
1141     CHECK_NULL_VOID(data.imageNode);
1142     CHECK_NULL_VOID(data.relativeContainerNode);
1143     CHECK_NULL_VOID(columnNode);
1144     auto stackFrameNode = FrameNode::GetOrCreateFrameNode(V2::STACK_ETS_TAG,
1145         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<StackPattern>(); });
1146     CHECK_NULL_VOID(stackFrameNode);
1147     data.stackNode = stackFrameNode;
1148     auto stackLayoutProperty = stackFrameNode->GetLayoutProperty();
1149     CHECK_NULL_VOID(stackLayoutProperty);
1150     stackLayoutProperty->UpdateUserDefinedIdealSize({ CalcLength(data.originPreviewRect.Width(), DimensionUnit::PX),
1151         CalcLength(data.originPreviewRect.Height(), DimensionUnit::PX) });
1152     stackLayoutProperty->UpdateAlignRules(
1153         { { AlignDirection::TOP, { .anchor = "__container__", .vertical = VerticalAlign::TOP } },
1154             { AlignDirection::RIGHT, { .anchor = "__container__", .horizontal = HorizontalAlign::END } } });
1155     auto stackContext = stackFrameNode->GetContext();
1156     CHECK_NULL_VOID(stackContext);
1157     auto renderContext = stackFrameNode->GetRenderContext();
1158     CHECK_NULL_VOID(renderContext);
1159     renderContext->UpdateClipEdge(true);
1160     renderContext->UpdateBorderRadius(data.borderRadius);
1161     auto shadow = Shadow::CreateShadow(ShadowStyle::None);
1162     renderContext->UpdateBackShadow(shadow);
1163     columnNode->AddChild(data.relativeContainerNode);
1164     data.relativeContainerNode->AddChild(stackFrameNode);
1165     stackFrameNode->AddChild(data.imageNode);
1166     auto dragPreviewLayoutProperty = data.imageNode->GetLayoutProperty();
1167     CHECK_NULL_VOID(dragPreviewLayoutProperty);
1168     dragPreviewLayoutProperty->UpdateUserDefinedIdealSize(
1169         { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
1170     dragPreviewLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
1171     CreateAndMountMenuPreviewNode(data, stackFrameNode);
1172     if (data.textRowNode) {
1173         data.relativeContainerNode->AddChild(data.textRowNode);
1174     }
1175     if (data.menuNode) {
1176         auto menuNode = data.menuNode;
1177         MenuView::UpdateMenuNodePosition(data);
1178         data.relativeContainerNode->AddChild(data.menuNode);
1179     }
1180 }
1181 
CreateAndMountMenuPreviewNode(PreparedInfoForDrag & data,const RefPtr<FrameNode> & stackFrameNode)1182 void DragAnimationHelper::CreateAndMountMenuPreviewNode(
1183     PreparedInfoForDrag& data, const RefPtr<FrameNode>& stackFrameNode)
1184 {
1185     CHECK_NULL_VOID(data.imageNode);
1186     CHECK_NULL_VOID(data.menuPreviewNode);
1187     if (data.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) {
1188         auto menuPreviewImageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
1189             ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
1190         CHECK_NULL_VOID(menuPreviewImageNode);
1191         data.menuPreviewImageNode = menuPreviewImageNode;
1192         auto menuPreviewImageNodeLayoutProperty = menuPreviewImageNode->GetLayoutProperty<ImageLayoutProperty>();
1193         CHECK_NULL_VOID(menuPreviewImageNodeLayoutProperty);
1194         auto menuPreviewRenderContext = data.menuPreviewNode->GetRenderContext();
1195         CHECK_NULL_VOID(menuPreviewRenderContext);
1196         auto menuPreviewPixelMap = menuPreviewRenderContext->GetThumbnailPixelMap(true);
1197         menuPreviewImageNodeLayoutProperty->UpdateImageSourceInfo(ImageSourceInfo(menuPreviewPixelMap));
1198         auto menuPreviewImagePattern = menuPreviewImageNode->GetPattern<ImagePattern>();
1199         CHECK_NULL_VOID(menuPreviewImagePattern);
1200         menuPreviewImagePattern->SetSyncLoad(true);
1201         menuPreviewImageNodeLayoutProperty->UpdateUserDefinedIdealSize(
1202             { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
1203         menuPreviewImageNodeLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
1204         menuPreviewImageNodeLayoutProperty->UpdateImageFit(ImageFit::COVER);
1205         auto menuPreviewImageRenderContext = menuPreviewImageNode->GetRenderContext();
1206         CHECK_NULL_VOID(menuPreviewImageRenderContext);
1207         menuPreviewImageRenderContext->UpdateOpacity(1.0f);
1208         stackFrameNode->AddChild(menuPreviewImageNode);
1209         auto dragPreviewRenderContext = data.imageNode->GetRenderContext();
1210         CHECK_NULL_VOID(dragPreviewRenderContext);
1211         dragPreviewRenderContext->UpdateOpacity(0.0f);
1212     }
1213 }
1214 
GetMenuWrapperNodeFromDrag()1215 RefPtr<FrameNode> DragAnimationHelper::GetMenuWrapperNodeFromDrag()
1216 {
1217     auto pipelineContext = PipelineContext::GetMainPipelineContext();
1218     CHECK_NULL_RETURN(pipelineContext, nullptr);
1219     auto mainDragDropManager = pipelineContext->GetDragDropManager();
1220     CHECK_NULL_RETURN(mainDragDropManager, nullptr);
1221     return mainDragDropManager->GetMenuWrapperNode();
1222 }
1223 
GetMenuRenderContextFromMenuWrapper(const RefPtr<FrameNode> & menuWrapperNode)1224 RefPtr<RenderContext> DragAnimationHelper::GetMenuRenderContextFromMenuWrapper(const RefPtr<FrameNode>& menuWrapperNode)
1225 {
1226     CHECK_NULL_RETURN(menuWrapperNode, nullptr);
1227     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
1228     CHECK_NULL_RETURN(menuWrapperPattern, nullptr);
1229     auto menuNode = menuWrapperPattern->GetMenu();
1230     CHECK_NULL_RETURN(menuNode, nullptr);
1231     return menuNode->GetRenderContext();
1232 }
1233 
UpdateStartAnimation(const RefPtr<OverlayManager> & overlayManager,const RefPtr<NodeAnimatablePropertyFloat> & animateProperty,Point point,const DragDropManager::DragPreviewInfo & info,const Offset & newOffset)1234 void DragAnimationHelper::UpdateStartAnimation(const RefPtr<OverlayManager>& overlayManager,
1235     const RefPtr<NodeAnimatablePropertyFloat>& animateProperty, Point point,
1236     const DragDropManager::DragPreviewInfo& info, const Offset& newOffset)
1237 {
1238     auto offset = OffsetF(point.GetX(), point.GetY());
1239     auto menuWrapperNode = DragAnimationHelper::GetMenuWrapperNodeFromDrag();
1240     auto menuPosition = overlayManager->CalculateMenuPosition(menuWrapperNode, offset);
1241     auto menuRenderContext = DragAnimationHelper::GetMenuRenderContextFromMenuWrapper(menuWrapperNode);
1242     auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenter(info.imageNode);
1243     auto renderContext = info.imageNode->GetRenderContext();
1244     CHECK_NULL_VOID(renderContext);
1245     if (menuRenderContext && !menuPosition.NonOffset()) {
1246         menuRenderContext->UpdatePosition(
1247             OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
1248     }
1249     DragDropManager::UpdateGatherNodePosition(overlayManager, info.imageNode);
1250     GatherAnimationInfo gatherAnimationInfo = { info.scale, info.width, info.height, gatherNodeCenter,
1251         renderContext->GetBorderRadius() };
1252     DragDropManager::UpdateGatherNodeAttr(overlayManager, gatherAnimationInfo);
1253     if (animateProperty) {
1254         animateProperty->Set(1.0f);
1255     }
1256     CHECK_NULL_VOID(info.relativeContainerNode);
1257     auto relativeContainerRenderContext = info.relativeContainerNode->GetRenderContext();
1258     CHECK_NULL_VOID(relativeContainerRenderContext);
1259     relativeContainerRenderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
1260     UpdateStartTransitionOptionAnimation(info);
1261 }
1262 
UpdateStartTransitionOptionAnimation(const DragDropManager::DragPreviewInfo & info)1263 void DragAnimationHelper::UpdateStartTransitionOptionAnimation(const DragDropManager::DragPreviewInfo& info)
1264 {
1265     CHECK_NULL_VOID(info.stackNode);
1266     auto stackRenderContext = info.stackNode->GetRenderContext();
1267     CHECK_NULL_VOID(stackRenderContext);
1268     CHECK_NULL_VOID(info.imageNode);
1269     if (info.imageNode->GetDragPreviewOption().options.borderRadius.has_value()) {
1270         stackRenderContext->UpdateBorderRadius(info.imageNode->GetDragPreviewOption().options.borderRadius.value());
1271     } else {
1272         stackRenderContext->UpdateBorderRadius(BorderRadiusProperty(0.0_vp));
1273     }
1274     if (info.imageNode->GetDragPreviewOption().options.shadow.has_value()) {
1275         stackRenderContext->UpdateBackShadow(info.imageNode->GetDragPreviewOption().options.shadow.value());
1276     }
1277     CHECK_NULL_VOID(info.menuPreviewImageNode);
1278     if (info.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) {
1279         auto dragPreviewRenderContext = info.imageNode->GetRenderContext();
1280         CHECK_NULL_VOID(dragPreviewRenderContext);
1281         dragPreviewRenderContext->UpdateOpacity(info.imageNode->GetDragPreviewOption().options.opacity);
1282         auto menuPreviewImageRenderContext = info.menuPreviewImageNode->GetRenderContext();
1283         CHECK_NULL_VOID(menuPreviewImageRenderContext);
1284         menuPreviewImageRenderContext->UpdateOpacity(0.0f);
1285     }
1286 }
1287 
CreateTextNode(PreparedInfoForDrag & data)1288 void DragAnimationHelper::CreateTextNode(PreparedInfoForDrag& data)
1289 {
1290     if (data.badgeNumber <= 1) {
1291         return;
1292     }
1293     auto textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1294         []() { return AceType::MakeRefPtr<TextPattern>(); });
1295     CHECK_NULL_VOID(textNode);
1296     auto textRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1297         AceType::MakeRefPtr<LinearLayoutPattern>(false));
1298 
1299     auto textRowProperty = textRow->GetLayoutProperty();
1300     CHECK_NULL_VOID(textRowProperty);
1301     auto textNodeProperty = textNode->GetLayoutProperty();
1302     CHECK_NULL_VOID(textNodeProperty);
1303     auto textRowRenderContext = textRow->GetRenderContext();
1304     CHECK_NULL_VOID(textRowRenderContext);
1305     textNodeProperty->UpdateUserDefinedIdealSize(
1306         { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
1307     textNodeProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
1308     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
1309     CHECK_NULL_VOID(pipelineContext);
1310     auto dragDropManager = pipelineContext->GetDragDropManager();
1311     CHECK_NULL_VOID(dragDropManager);
1312     auto windowScale = dragDropManager->GetWindowScale();
1313     if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
1314         textRowRenderContext->UpdateOffset(
1315             OffsetT<Dimension>(Dimension(-BADGE_RELATIVE_OFFSET.ConvertToPx() * windowScale),
1316                 Dimension(-BADGE_RELATIVE_OFFSET.ConvertToPx() * windowScale)));
1317     } else {
1318         textRowRenderContext->UpdateOffset(
1319             OffsetT<Dimension>(Dimension(BADGE_RELATIVE_OFFSET.ConvertToPx() * windowScale),
1320                 Dimension(-BADGE_RELATIVE_OFFSET.ConvertToPx() * windowScale)));
1321     }
1322     textRowProperty->UpdateAlignRules(
1323         { { AlignDirection::TOP, { .anchor = "__container__", .vertical = VerticalAlign::TOP } },
1324             { AlignDirection::RIGHT, { .anchor = "__container__", .horizontal = HorizontalAlign::END } } });
1325     textNode->MountToParent(textRow);
1326 
1327     auto badgeLength = std::to_string(data.badgeNumber).size();
1328     DragAnimationHelper::UpdateBadgeLayoutAndRenderContext(textNode, badgeLength, data.badgeNumber);
1329 
1330     textNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
1331     textNode->MarkModifyDone();
1332     textNode->SetLayoutDirtyMarked(true);
1333     textNode->SetActive(true);
1334     data.textRowNode = textRow;
1335     data.textNode = textNode;
1336     if (!data.gatherNode || data.deviceType == SourceType::MOUSE) {
1337         DragAnimationHelper::SetNodeVisible(data.textNode, false);
1338     }
1339 }
1340 
GetPreviewMenuAnimationRate()1341 float DragAnimationHelper::GetPreviewMenuAnimationRate()
1342 {
1343     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1344     CHECK_NULL_RETURN(pipeline, 1.0f);
1345     auto dragDropManager = pipeline->GetDragDropManager();
1346     CHECK_NULL_RETURN(dragDropManager, 1.0f);
1347     auto menuWrapperNode = dragDropManager->GetMenuWrapperNode();
1348     CHECK_NULL_RETURN(menuWrapperNode, 1.0f);
1349     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
1350     CHECK_NULL_RETURN(menuWrapperPattern, 1.0f);
1351     auto animationInfo = menuWrapperPattern->GetPreviewMenuAnimationInfo();
1352     return animationInfo.clipRate;
1353 }
1354 } // namespace OHOS::Ace::NG
1355