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