1 /*
2 * Copyright (c) 2021-2022 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 "click_spring_effect.h"
17 #include "render_transform.h"
18
19 namespace OHOS::Ace {
20 namespace {
21
22 struct SpringEffectProperty {
23 double scale_;
24 double velocity_;
25 RefPtr<SpringProperty> springProperty_;
26 };
27
28 const static std::unordered_map<ClickSpringEffectType, SpringEffectProperty> CLICK_SPRING_EFFECT_PROPERTIES = {
29 { ClickSpringEffectType::SMALL, { 0.9, 1, AceType::MakeRefPtr<SpringProperty>(0.5, 410.0, 38.0) } },
30 { ClickSpringEffectType::MEDIUM, { 0.95, 0.5, AceType::MakeRefPtr<SpringProperty>(0.5, 350.0, 35.0) } },
31 { ClickSpringEffectType::LARGE, { 0.95, 0, AceType::MakeRefPtr<SpringProperty>(0.5, 240.0, 28.0) } },
32 };
33
34 } // namespace
35
ClickSpringEffect(const WeakPtr<PipelineContext> & context)36 ClickSpringEffect::ClickSpringEffect(const WeakPtr<PipelineContext>& context)
37 {
38 controller_ = CREATE_ANIMATOR(context);
39 }
40
FinishPreviousAnimation()41 void ClickSpringEffect::FinishPreviousAnimation()
42 {
43 if (controller_ && !controller_->IsStopped()) {
44 controller_->Finish();
45 }
46 }
47
ShowAnimation(TouchType touchType,ClickSpringEffectType type)48 void ClickSpringEffect::ShowAnimation(TouchType touchType, ClickSpringEffectType type)
49 {
50 FinishPreviousAnimation();
51 auto propertyPos = CLICK_SPRING_EFFECT_PROPERTIES.find(type);
52 if (propertyPos == CLICK_SPRING_EFFECT_PROPERTIES.end()) {
53 LOGE("can't find type %{public}d", type);
54 return;
55 }
56
57 auto& effectProperty = propertyPos->second;
58 RefPtr<SpringMotion> springMotion;
59 switch (touchType) {
60 case TouchType::DOWN:
61 springMotion = AceType::MakeRefPtr<SpringMotion>(
62 GetScale(), effectProperty.scale_, effectProperty.velocity_, effectProperty.springProperty_);
63 break;
64 case TouchType::UP:
65 case TouchType::CANCEL:
66 springMotion = AceType::MakeRefPtr<SpringMotion>(
67 GetScale(), 1.0, effectProperty.velocity_, effectProperty.springProperty_);
68 break;
69 default:
70 return;
71 }
72 if (!springMotion) {
73 return;
74 }
75
76 springMotion->AddListener([weakEffect = AceType::WeakClaim(this)](double value) {
77 auto effect = weakEffect.Upgrade();
78 if (effect) {
79 effect->SetScale(value);
80 effect->MarkRender();
81 }
82 });
83
84 if (controller_) {
85 controller_->PlayMotion(springMotion);
86 }
87 }
88
MarkRender()89 void ClickSpringEffect::MarkRender()
90 {
91 auto node = renderNode_.Upgrade();
92 if (node == nullptr) {
93 return;
94 }
95
96 node->MarkNeedLayout();
97 auto transform = AceType::DynamicCast<RenderTransform>(node);
98 if (transform == nullptr) {
99 return;
100 }
101 transform->SetPendingUpdateTransformLayer();
102 }
103
104 } // namespace OHOS::Ace
105