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/animation/simple_spring_chain.h"
17
18 #include "base/utils/utils.h"
19
20 namespace OHOS::Ace {
21 namespace {
22
23 constexpr double DEFAULT_CHAIN_STIFFNESS = 228.0;
24 constexpr double DEFAULT_CHAIN_DAMPING = 30.0;
25 const RefPtr<SpringProperty> DEFAULT_OVER_SPRING_PROPERTY =
26 AceType::MakeRefPtr<SpringProperty>(1.0, DEFAULT_CHAIN_STIFFNESS, DEFAULT_CHAIN_DAMPING);
27 constexpr double DEFAULT_FRICTION = 1.0;
28 constexpr int32_t DEFAULT_CHAIN_FRAME_DELTA = 1;
29
30 } // namespace
31
SimpleSpringChain(const RefPtr<SpringAdapter> & springAdapter)32 SimpleSpringChain::SimpleSpringChain(const RefPtr<SpringAdapter>& springAdapter)
33 {
34 if (springAdapter) {
35 springAdapter_ = springAdapter;
36 } else {
37 springAdapter_ = AceType::MakeRefPtr<SimpleSpringAdapter>();
38 }
39 springAdapter_->SetObserve(AceType::WeakClaim(this));
40 stiffnessTransfer_ = AceType::MakeRefPtr<ExpParamTransfer>(1.0);
41 dampingTransfer_ = AceType::MakeRefPtr<ExpParamTransfer>(0.0);
42 controlStiffness_ = DEFAULT_CHAIN_STIFFNESS;
43 controlDamping_ = DEFAULT_CHAIN_DAMPING;
44 frameDelta_ = DEFAULT_CHAIN_FRAME_DELTA;
45 }
46
OnNodeAdd(RefPtr<SpringNode> & node)47 void SimpleSpringChain::OnNodeAdd(RefPtr<SpringNode>& node)
48 {
49 if (!node) {
50 return;
51 }
52 SetParams(node);
53 }
54
OnNodeDelete(RefPtr<SpringNode> & node)55 void SimpleSpringChain::OnNodeDelete(RefPtr<SpringNode>& node)
56 {
57 if (!node) {
58 return;
59 }
60 auto next = springAdapter_->GetNext(node);
61 while (next) {
62 next->SetIndex(next->GetIndex() - 1);
63 SetParams(next);
64 next = springAdapter_->GetNext(next);
65 }
66 }
67
SetDeltaValue(double delta)68 void SimpleSpringChain::SetDeltaValue(double delta)
69 {
70 for (int32_t index = 0; index < springAdapter_->GetSize(); index++) {
71 auto node = springAdapter_->GetNode(index);
72 if (node) {
73 node->SetDeltaValue(delta);
74 }
75 }
76 }
77
SetValue(double value)78 void SimpleSpringChain::SetValue(double value)
79 {
80 auto node = springAdapter_->GetControlNode();
81 if (node) {
82 node->SetValue(value);
83 }
84 }
85
FlushAnimation()86 void SimpleSpringChain::FlushAnimation()
87 {
88 // flush from control to edge.
89 springAdapter_->FlushAnimation();
90 }
91
EndToPosition(double value,double velocity)92 void SimpleSpringChain::EndToPosition(double value, double velocity)
93 {
94 auto node = springAdapter_->GetControlNode();
95 if (node) {
96 node->EndToValue(value, velocity);
97 }
98 }
99
Cancel()100 void SimpleSpringChain::Cancel()
101 {
102 auto currentNode = springAdapter_->GetControlNode();
103 for (int32_t idx = 0; idx < springAdapter_->GetSize(); idx++) {
104 if (currentNode) {
105 currentNode->Cancel();
106 currentNode = springAdapter_->GetNext(currentNode);
107 } else {
108 LOGW("Node size mismatch. size: %{public}d, current size: %{public}d", springAdapter_->GetSize(), idx + 1);
109 break;
110 }
111 }
112 }
113
TransferParamsInternal()114 void SimpleSpringChain::TransferParamsInternal()
115 {
116 for (int32_t idx = 0; idx < springAdapter_->GetSize(); idx++) {
117 auto currentNode = springAdapter_->GetNode(idx);
118 SetParams(currentNode);
119 }
120 }
121
SetParams(RefPtr<SpringNode> & node)122 void SimpleSpringChain::SetParams(RefPtr<SpringNode>& node)
123 {
124 int32_t index = node->GetIndex();
125 auto controlNode = springAdapter_->GetControlNode();
126 if (!controlNode) {
127 controlNode = node;
128 }
129 int32_t delta = std::abs(index - controlNode->GetIndex());
130 double transferStiffness = stiffnessTransfer_->Transfer(controlStiffness_, delta);
131 double transferDamping = dampingTransfer_->Transfer(controlDamping_, delta);
132 node->TransferParams(transferStiffness, transferDamping);
133 node->SetFrameDelta(frameDelta_);
134 node->SetDecoration(decoration_);
135 // make sure minDecoration <= decoration <= maxDecoration
136 node->SetMinDecoration(std::min(minDecoration_, decoration_));
137 node->SetMaxDecoration(std::max(maxDecoration_, decoration_));
138 if (!node->GetAdapter()) {
139 node->SetAdapter(springAdapter_);
140 }
141 }
142
GetDefaultOverSpringProperty()143 const RefPtr<SpringProperty>& SpringChainProperty::GetDefaultOverSpringProperty()
144 {
145 return DEFAULT_OVER_SPRING_PROPERTY;
146 }
147
GetDefaultFriction()148 double SpringChainProperty::GetDefaultFriction()
149 {
150 return DEFAULT_FRICTION;
151 }
152
153 } // namespace OHOS::Ace