1 /*
2  * Copyright (c) 2021 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 
16 #include "core/components/tab_bar/tab_bar_size_animation.h"
17 
18 namespace OHOS::Ace {
19 namespace {
20 
21 constexpr int32_t SIZE_TRANSITION_DURATION = 300;
22 constexpr int32_t ACTIVE_TEXT_SIZE = 24;
23 constexpr int32_t INACTIVE_TEXT_SIZE = 18;
24 constexpr double ACTIVE_TEXT_OPACITY = 0.9;
25 constexpr double INACTIVE_TEXT_OPACITY = 18;
26 
27 } // namespace
28 
GetTextItem(const RefPtr<RenderNode> & node)29 RefPtr<RenderText> GetTextItem(const RefPtr<RenderNode>& node)
30 {
31     for (const auto& item : node->GetChildren()) {
32         for (const auto& textItem : item->GetChildren()) {
33             return AceType::DynamicCast<RenderText>(textItem);
34         }
35     }
36     return nullptr;
37 }
38 
Initialize(const WeakPtr<PipelineContext> & context)39 void TabBarSizeAnimation::Initialize(const WeakPtr<PipelineContext>& context)
40 {
41     ItemAnimationProp onFocusItem(Dimension(ACTIVE_TEXT_SIZE, DimensionUnit::VP), ACTIVE_TEXT_OPACITY);
42     ItemAnimationProp onBlurItem(Dimension(INACTIVE_TEXT_SIZE, DimensionUnit::VP), INACTIVE_TEXT_OPACITY);
43 
44     onFocusTranslate_ =
45         AceType::MakeRefPtr<CurveAnimation<ItemAnimationProp>>(onBlurItem, onFocusItem, Curves::FRICTION);
46     onBlurTranslate_ =
47         AceType::MakeRefPtr<CurveAnimation<ItemAnimationProp>>(onFocusItem, onBlurItem, Curves::FRICTION);
48     auto weak = AceType::WeakClaim(this);
49     controller_ = CREATE_ANIMATOR(context);
50     onFocusTranslate_->AddListener(Animation<ItemAnimationProp>::ValueCallback([weak](ItemAnimationProp value) {
51         auto tabBar = weak.Upgrade();
52         if (tabBar) {
53             tabBar->ChangeItemProp(tabBar->onFocusItemText_, value);
54         }
55     }));
56     onBlurTranslate_->AddListener(Animation<ItemAnimationProp>::ValueCallback([weak](ItemAnimationProp value) {
57         auto tabBar = weak.Upgrade();
58         if (tabBar) {
59             tabBar->ChangeItemProp(tabBar->onBlurItemText_, value);
60         }
61     }));
62     controller_->SetDuration(SIZE_TRANSITION_DURATION);
63     controller_->AddInterpolator(onFocusTranslate_);
64     controller_->AddInterpolator(onBlurTranslate_);
65 }
66 
Start(const WeakPtr<RenderNode> & weakTabbar,int32_t from,int32_t to)67 void TabBarSizeAnimation::Start(const WeakPtr<RenderNode>& weakTabbar, int32_t from, int32_t to)
68 {
69     auto tabBar = weakTabbar.Upgrade();
70     if (!tabBar) {
71         return;
72     }
73     auto lastSelected = tabBar->GetChildren().begin();
74     std::advance(lastSelected, from);
75 
76     onBlurItemText_ = GetTextItem(*lastSelected);
77 
78     auto currentSelected = tabBar->GetChildren().begin();
79     std::advance(currentSelected, to);
80     onFocusItemText_ = GetTextItem(*currentSelected);
81 
82     layoutCallback_ = [weakTabbar]() {
83         auto tabBar = weakTabbar.Upgrade();
84         if (tabBar) {
85             tabBar->MarkNeedLayout();
86         }
87     };
88     controller_->Play();
89 }
90 
ChangeItemProp(const RefPtr<RenderText> & renderText,const ItemAnimationProp & animationProp)91 void TabBarSizeAnimation::ChangeItemProp(const RefPtr<RenderText>& renderText, const ItemAnimationProp& animationProp)
92 {
93     if (renderText) {
94         TextStyle textStyle;
95         textStyle.SetTextColor(Color::FromRGBO(0, 0, 0, animationProp.opacity));
96         textStyle.SetFontSize(animationProp.fontSize);
97         textStyle.SetMaxLines(1);
98         textStyle.SetTextOverflow(TextOverflow::CLIP);
99         renderText->SetTextStyle(textStyle);
100         renderText->MarkNeedMeasure();
101         renderText->MarkNeedLayout();
102     }
103     layoutCallback_();
104 }
105 
106 } // namespace OHOS::Ace
107