1 /*
2 * Copyright (c) 2025 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/pattern/text_field/auto_fill_controller.h"
16
17 #include <algorithm>
18 #include <cstdint>
19 #include <string>
20
21 #include "base/utils/string_utils.h"
22 #include "base/utils/utf_helper.h"
23 #include "base/utils/utils.h"
24 #include "core/components_ng/pattern/text/text_layout_property.h"
25 #include "core/components_ng/pattern/text/text_pattern.h"
26 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
27
28 namespace OHOS::Ace::NG {
29 namespace {
30 constexpr int32_t AUTO_FILL_ICON_ANIMATION_DURATION = 250;
31 constexpr float AUTO_FILL_SPRING_RESPONSE = 0.513f;
32 constexpr float AUTO_FILL_SPRING_DAMPING_FRACTION = 0.94f;
33 constexpr float AUTO_FILL_SPRING_RESPONSE_EXTRA_LONG = 0.613f;
34 constexpr float AUTO_FILL_SPRING_DAMPING_FRACTION_EXTRA_LONG = 0.93f;
35 constexpr uint32_t AUTO_FILL_SYMBOL_RENDERING_STRATEGY = 1;
36 constexpr float AUTO_FILL_ICON_INIT_SCALE = 0.2f;
37 constexpr int32_t AUTO_FILL_TEXT_SCROLL_DELAY_DURATION = 500;
38 constexpr int32_t AUTO_FILL_DEFAULT_CHAR_DELAY_DURATION = 150;
39 constexpr int32_t AUTO_FILL_ICON_HIDE_DELAY_DURATION_SHORT = 800;
40 constexpr int32_t AUTO_FILL_ICON_HIDE_DELAY_DURATION_MEDIUM = 900;
41 constexpr int32_t AUTO_FILL_ICON_HIDE_DELAY_DURATION_LONG = 1000;
42 constexpr int32_t AUTO_FILL_ICON_HIDE_DELAY_DURATION_EXTRA_LONG = 1100;
43 } // namespace
44
StartAutoFillAnimation(const std::function<void ()> & onFinishCallback,const std::u16string & content)45 void AutoFillController::StartAutoFillAnimation(
46 const std::function<void()>& onFinishCallback, const std::u16string& content)
47 {
48 auto initParagraphSuc = InitAutoFillParagraph(content);
49 auto createAutoFillIconSuc = CreateAutoFillIcon();
50 if (!initParagraphSuc || !createAutoFillIconSuc) {
51 if (onFinishCallback) {
52 onFinishCallback();
53 }
54 ResetAutoFillAnimationStatus();
55 return;
56 }
57 AutoFillContentLengthMode mode = GetAutoFillContentLengthMode();
58 if (mode == AutoFillContentLengthMode::INVALID) {
59 if (onFinishCallback) {
60 onFinishCallback();
61 }
62 ResetAutoFillAnimationStatus();
63 return;
64 }
65 auto pattern = pattern_.Upgrade();
66 CHECK_NULL_VOID(pattern);
67 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
68 CHECK_NULL_VOID(textFieldPattern);
69 textFieldPattern->StopTwinkling();
70 UpdateAnimationTextRect();
71 if (mode == AutoFillContentLengthMode::EXTRA_LONG) {
72 PlayAutoFillIconShowAnimation(mode);
73 PlayAutoFillTextScrollAnimation();
74 PlayAutoFillIconHideAnimation(onFinishCallback, mode);
75 } else {
76 PlayAutoFillIconShowAnimation(mode);
77 PlayAutoFillIconHideAnimation(onFinishCallback, mode);
78 }
79 }
80
GetAutoFillContentLengthMode()81 AutoFillContentLengthMode AutoFillController::GetAutoFillContentLengthMode()
82 {
83 auto pattern = pattern_.Upgrade();
84 CHECK_NULL_RETURN(pattern, AutoFillContentLengthMode::INVALID);
85 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
86 CHECK_NULL_RETURN(textFieldPattern, AutoFillContentLengthMode::INVALID);
87 CHECK_NULL_RETURN(autoFillParagraph_, AutoFillContentLengthMode::INVALID);
88
89 float autoFillParagraphWidth = std::max(autoFillParagraph_->GetLongestLine(), 0.0f);
90 auto contentRect = textFieldPattern->GetTextContentRect();
91 float textFieldContentWidth = std::max(contentRect.Width(), 0.0f);
92 if (LessOrEqual(autoFillParagraphWidth, 0.0f) || LessOrEqual(textFieldContentWidth, 0.0f)) {
93 return AutoFillContentLengthMode::INVALID;
94 }
95
96 if (GreatNotEqual(autoFillParagraphWidth, textFieldContentWidth)) {
97 return AutoFillContentLengthMode::EXTRA_LONG;
98 }
99
100 auto shortContentLength = textFieldContentWidth * 1.0f / 3.0f;
101 auto middleContentLength = textFieldContentWidth * 2.0f / 3.0f;
102 if (LessOrEqual(autoFillParagraphWidth, shortContentLength)) {
103 return AutoFillContentLengthMode::SHORT;
104 }
105
106 if (LessOrEqual(autoFillParagraphWidth, middleContentLength)) {
107 return AutoFillContentLengthMode::MEDIUM;
108 }
109
110 return AutoFillContentLengthMode::LONG;
111 }
112
InitAutoFillParagraph(const std::u16string & content)113 bool AutoFillController::InitAutoFillParagraph(const std::u16string& content)
114 {
115 auto pattern = pattern_.Upgrade();
116 CHECK_NULL_RETURN(pattern, false);
117 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
118 CHECK_NULL_RETURN(textFieldPattern, false);
119 autoFillParagraph_ = textFieldPattern->GetParagraph();
120 CHECK_NULL_RETURN(autoFillParagraph_, false);
121 auto textFieldContentModifier = textFieldPattern->GetContentModifier();
122 CHECK_NULL_RETURN(textFieldContentModifier, false);
123 textFieldContentModifier->SetAutoFillOriginTextColor(autoFillOriginTextColor_);
124 return true;
125 }
126
PlayAutoFillIconShowAnimation(const AutoFillContentLengthMode & mode)127 void AutoFillController::PlayAutoFillIconShowAnimation(const AutoFillContentLengthMode& mode)
128 {
129 auto symbolNode = autoFillIconNode_.Upgrade();
130 CHECK_NULL_VOID(symbolNode);
131 auto symbolRenderContext = symbolNode->GetRenderContext();
132 CHECK_NULL_VOID(symbolRenderContext);
133 AnimationOption option = AnimationOption();
134 option.SetDuration(AUTO_FILL_ICON_ANIMATION_DURATION);
135 option.SetCurve(Curves::FRICTION);
136 AnimationUtils::Animate(
137 option,
138 [symbolRenderContext]() {
139 symbolRenderContext->UpdateOpacity(1.0);
140 symbolRenderContext->UpdateTransformScale({ 1.0, 1.0 });
141 },
142 [weak = AceType::WeakClaim(this), mode]() {
143 auto autofillController = weak.Upgrade();
144 CHECK_NULL_VOID(autofillController);
145 autofillController->PlayAutoFillTranslationAnimation(mode);
146 autofillController->PlayAutoFillDefaultCharAnimation(mode);
147 }, nullptr, symbolNode->GetContextRefPtr());
148 }
149
PlayAutoFillDefaultCharAnimation(const AutoFillContentLengthMode & mode)150 void AutoFillController::PlayAutoFillDefaultCharAnimation(const AutoFillContentLengthMode& mode)
151 {
152 if (!autoFillParagraph_) {
153 ResetAutoFillAnimationStatus();
154 return;
155 }
156 auto pattern = pattern_.Upgrade();
157 CHECK_NULL_VOID(pattern);
158 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
159 CHECK_NULL_VOID(textFieldPattern);
160 auto contentLength = autoFillParagraph_->GetParagraphText().length();
161 auto response = GetSpringAnimationResponse(mode);
162 auto damping = GetSpringAnimationDamping(mode);
163 auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(response, damping);
164 AnimationOption option;
165 option.SetCurve(motion);
166 option.SetDelay(AUTO_FILL_DEFAULT_CHAR_DELAY_DURATION);
167 AnimationUtils::Animate(option, [weak = AceType::WeakClaim(this), weakPattern = pattern_, contentLength]() {
168 auto autofillController = weak.Upgrade();
169 CHECK_NULL_VOID(autofillController);
170 auto pattern = weakPattern.Upgrade();
171 CHECK_NULL_VOID(pattern);
172 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
173 CHECK_NULL_VOID(textFieldPattern);
174 auto textFieldContentModifier = textFieldPattern->GetContentModifier();
175 CHECK_NULL_VOID(textFieldContentModifier);
176 autofillController->autoFillAnimationStatus_ = AutoFillAnimationStatus::TRANSLATION;
177 textFieldContentModifier->SetAutoFillDefaultCharIndex(std::max(contentLength - 1.0f, 0.0f));
178 }, nullptr, nullptr, Claim(pattern->GetContext()));
179 }
180
PlayAutoFillTranslationAnimation(const AutoFillContentLengthMode & mode)181 void AutoFillController::PlayAutoFillTranslationAnimation(const AutoFillContentLengthMode& mode)
182 {
183 if (!autoFillParagraph_) {
184 ResetAutoFillAnimationStatus();
185 return;
186 }
187 auto pattern = pattern_.Upgrade();
188 CHECK_NULL_VOID(pattern);
189 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
190 CHECK_NULL_VOID(textFieldPattern);
191 auto symbolNode = autoFillIconNode_.Upgrade();
192 CHECK_NULL_VOID(symbolNode);
193 auto symbolRenderContext = symbolNode->GetRenderContext();
194 CHECK_NULL_VOID(symbolRenderContext);
195 float autoFillParagraphWidth = std::max(autoFillParagraph_->GetLongestLine(), 0.0f);
196 auto contentRect = textFieldPattern->GetTextContentRect();
197 float textFieldContentWidth = std::max(contentRect.Width(), 0.0f);
198 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
199 CHECK_NULL_VOID(layoutProperty);
200 auto isRTL = layoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
201 auto theme = textFieldPattern->GetTheme();
202 CHECK_NULL_VOID(theme);
203 auto iconSize = theme->GetAutoFillIconSize();
204 auto iconWidth = static_cast<float>(iconSize.ConvertToPx());
205 auto translationOffset =
206 std::min(autoFillParagraphWidth + autoFillFirstCharOffset_, textFieldContentWidth - iconWidth);
207 if (isRTL) {
208 translationOffset = -translationOffset;
209 }
210 auto contentLength = autoFillParagraph_->GetParagraphText().length();
211 auto response = GetSpringAnimationResponse(mode);
212 auto damping = GetSpringAnimationDamping(mode);
213 auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(response, damping);
214 AnimationOption option;
215 option.SetCurve(motion);
216 AnimationUtils::Animate(option, [weak = AceType::WeakClaim(this), weakPattern = pattern_, translationOffset,
217 symbolRenderContext, contentLength]() {
218 auto autofillController = weak.Upgrade();
219 CHECK_NULL_VOID(autofillController);
220 auto pattern = weakPattern.Upgrade();
221 CHECK_NULL_VOID(pattern);
222 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
223 CHECK_NULL_VOID(textFieldPattern);
224 auto textFieldContentModifier = textFieldPattern->GetContentModifier();
225 CHECK_NULL_VOID(textFieldContentModifier);
226 autofillController->autoFillAnimationStatus_ = AutoFillAnimationStatus::TRANSLATION;
227 textFieldContentModifier->SetAutoFillEmphasizeCharIndex(std::max(contentLength - 1.0f, 0.0f));
228 textFieldContentModifier->SetAutoFillTranslationOffset(translationOffset);
229 symbolRenderContext->UpdateTransformTranslate({ translationOffset, 0.0f, 0.0f });
230 }, nullptr, nullptr, Claim(pattern->GetContext()));
231 }
232
PlayAutoFillTextScrollAnimation()233 void AutoFillController::PlayAutoFillTextScrollAnimation()
234 {
235 if (!autoFillParagraph_) {
236 ResetAutoFillAnimationStatus();
237 return;
238 }
239 auto pattern = pattern_.Upgrade();
240 CHECK_NULL_VOID(pattern);
241 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
242 CHECK_NULL_VOID(textFieldPattern);
243 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
244 CHECK_NULL_VOID(layoutProperty);
245 auto isRTL = layoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
246 float autoFillParagraphWidth = std::max(autoFillParagraph_->GetLongestLine(), 0.0f);
247 auto contentRect = textFieldPattern->GetTextContentRect();
248 float textFieldContentWidth = std::max(contentRect.Width(), 0.0f);
249 auto startScrollOffset = isRTL ? autoFillParagraphWidth - textFieldContentWidth : 0;
250 auto endScrollOffset = isRTL ? 0 : autoFillParagraphWidth - textFieldContentWidth;
251 auto textFieldContentModifier = textFieldPattern->GetContentModifier();
252 CHECK_NULL_VOID(textFieldContentModifier);
253 textFieldContentModifier->SetAutoFillTextScrollOffset(startScrollOffset);
254 auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(
255 AUTO_FILL_SPRING_RESPONSE_EXTRA_LONG, AUTO_FILL_SPRING_DAMPING_FRACTION_EXTRA_LONG);
256 AnimationOption option;
257 option.SetCurve(motion);
258 option.SetDelay(AUTO_FILL_TEXT_SCROLL_DELAY_DURATION);
259 AnimationUtils::Animate(option, [weak = AceType::WeakClaim(this), weakPattern = pattern_, endScrollOffset]() {
260 auto autofillController = weak.Upgrade();
261 CHECK_NULL_VOID(autofillController);
262 auto pattern = weakPattern.Upgrade();
263 CHECK_NULL_VOID(pattern);
264 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
265 CHECK_NULL_VOID(textFieldPattern);
266 auto textFieldContentModifier = textFieldPattern->GetContentModifier();
267 CHECK_NULL_VOID(textFieldContentModifier);
268 autofillController->autoFillAnimationStatus_ = AutoFillAnimationStatus::TRANSLATION;
269 textFieldContentModifier->SetAutoFillTextScrollOffset(endScrollOffset);
270 }, nullptr, nullptr, Claim(pattern->GetContext()));
271 }
272
PlayAutoFillIconHideAnimation(const std::function<void ()> & onFinishCallback,const AutoFillContentLengthMode & mode)273 void AutoFillController::PlayAutoFillIconHideAnimation(
274 const std::function<void()>& onFinishCallback, const AutoFillContentLengthMode& mode)
275 {
276 auto symbolNode = autoFillIconNode_.Upgrade();
277 if (!symbolNode) {
278 ResetAutoFillAnimationStatus();
279 return;
280 }
281 auto symbolRenderContext = symbolNode->GetRenderContext();
282 if (!symbolRenderContext) {
283 ResetAutoFillAnimationStatus();
284 return;
285 }
286 auto delayDuration = AUTO_FILL_ICON_HIDE_DELAY_DURATION_SHORT;
287 if (mode == AutoFillContentLengthMode::MEDIUM) {
288 delayDuration = AUTO_FILL_ICON_HIDE_DELAY_DURATION_MEDIUM;
289 } else if (mode == AutoFillContentLengthMode::LONG) {
290 delayDuration = AUTO_FILL_ICON_HIDE_DELAY_DURATION_LONG;
291 } else if (mode == AutoFillContentLengthMode::EXTRA_LONG) {
292 delayDuration = AUTO_FILL_ICON_HIDE_DELAY_DURATION_EXTRA_LONG;
293 }
294
295 AnimationOption option = AnimationOption();
296 option.SetDuration(AUTO_FILL_ICON_ANIMATION_DURATION);
297 option.SetCurve(Curves::FRICTION);
298 option.SetDelay(delayDuration);
299 AnimationUtils::Animate(
300 option,
301 [weak = AceType::WeakClaim(this), symbolRenderContext]() {
302 auto autofillController = weak.Upgrade();
303 CHECK_NULL_VOID(autofillController);
304 autofillController->autoFillAnimationStatus_ = AutoFillAnimationStatus::HIDE_ICON;
305 symbolRenderContext->UpdateOpacity(0.0);
306 symbolRenderContext->UpdateTransformScale({ AUTO_FILL_ICON_INIT_SCALE, AUTO_FILL_ICON_INIT_SCALE });
307 },
308 [weak = AceType::WeakClaim(this), weakPattern = pattern_, onFinish = std::move(onFinishCallback)]() {
309 auto autofillController = weak.Upgrade();
310 CHECK_NULL_VOID(autofillController);
311 auto pattern = weakPattern.Upgrade();
312 CHECK_NULL_VOID(pattern);
313 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
314 CHECK_NULL_VOID(textFieldPattern);
315 autofillController->ResetAutoFillAnimationStatus();
316 autofillController->ResetAutoFillIcon();
317 textFieldPattern->StartTwinkling();
318 if (onFinish) {
319 onFinish();
320 }
321 }, nullptr, symbolNode->GetContextRefPtr());
322 }
323
CreateAutoFillIcon()324 bool AutoFillController::CreateAutoFillIcon()
325 {
326 auto pattern = pattern_.Upgrade();
327 CHECK_NULL_RETURN(pattern, false);
328 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
329 CHECK_NULL_RETURN(textFieldPattern, false);
330 auto host = textFieldPattern->GetHost();
331 CHECK_NULL_RETURN(host, false);
332 auto symbolNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
333 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
334 CHECK_NULL_RETURN(symbolNode, false);
335 autoFillIconNode_ = WeakClaim(RawPtr(symbolNode));
336 auto symbolProperty = symbolNode->GetLayoutProperty<TextLayoutProperty>();
337 CHECK_NULL_RETURN(symbolProperty, false);
338 auto theme = textFieldPattern->GetTheme();
339 CHECK_NULL_RETURN(theme, false);
340 symbolProperty->UpdateSymbolSourceInfo(SymbolSourceInfo(theme->GetAutoFillSymbolId()));
341 symbolProperty->UpdateFontSize(theme->GetAutoFillIconSize());
342 symbolProperty->UpdateSymbolColorList(
343 { theme->GetAutoFillIconPrimaryColor(), theme->GetAutoFillIconEmphasizeColor() });
344 symbolProperty->UpdateSymbolRenderingStrategy(AUTO_FILL_SYMBOL_RENDERING_STRATEGY);
345 auto symbolRenderContext = symbolNode->GetRenderContext();
346 CHECK_NULL_RETURN(symbolRenderContext, false);
347 symbolRenderContext->UpdateOpacity(0.0);
348 symbolRenderContext->UpdateTransformScale({ AUTO_FILL_ICON_INIT_SCALE, AUTO_FILL_ICON_INIT_SCALE });
349 CHECK_NULL_RETURN(autoFillParagraph_, false);
350 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
351 CHECK_NULL_RETURN(layoutProperty, false);
352 auto isRTL = layoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
353 auto lineMetrics = autoFillParagraph_->GetLineMetrics(0);
354 autoFillFirstCharOffset_ = lineMetrics.x;
355 auto startOffset = autoFillFirstCharOffset_;
356 auto contentRect = textFieldPattern->GetTextContentRect();
357 if (isRTL) {
358 // animation from right to left
359 startOffset = contentRect.Width() - (startOffset + lineMetrics.width);
360 startOffset = std::max(startOffset, 0.0f);
361 autoFillFirstCharOffset_ = startOffset;
362 startOffset = -startOffset;
363 }
364 symbolRenderContext->UpdateTransformTranslate({ startOffset, 0.0f, 0.0f });
365 symbolNode->MountToParent(host);
366 symbolNode->MarkModifyDone();
367 symbolNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
368 return true;
369 }
370
ResetAutoFillIcon()371 void AutoFillController::ResetAutoFillIcon()
372 {
373 auto pattern = pattern_.Upgrade();
374 CHECK_NULL_VOID(pattern);
375 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
376 CHECK_NULL_VOID(textFieldPattern);
377 auto host = textFieldPattern->GetHost();
378 CHECK_NULL_VOID(host);
379 auto symbolNode = autoFillIconNode_.Upgrade();
380 CHECK_NULL_VOID(symbolNode);
381 host->RemoveChild(symbolNode);
382 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
383 }
384
ResetAutoFillAnimationStatus()385 void AutoFillController::ResetAutoFillAnimationStatus()
386 {
387 autoFillAnimationStatus_ = AutoFillAnimationStatus::INIT;
388 if (autoFillParagraph_) {
389 autoFillParagraph_ = nullptr;
390 }
391 auto pattern = pattern_.Upgrade();
392 CHECK_NULL_VOID(pattern);
393 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
394 CHECK_NULL_VOID(textFieldPattern);
395 auto textFieldContentModifier = textFieldPattern->GetContentModifier();
396 CHECK_NULL_VOID(textFieldContentModifier);
397 textFieldContentModifier->SetAutoFillTranslationOffset(0.0f);
398 textFieldContentModifier->SetAutoFillTextScrollOffset(0.0f);
399 textFieldContentModifier->SetAutoFillEmphasizeCharIndex(0.0f);
400 textFieldContentModifier->SetAutoFillDefaultCharIndex(0.0f);
401 }
402
GetSpringAnimationResponse(const AutoFillContentLengthMode & mode)403 float AutoFillController::GetSpringAnimationResponse(const AutoFillContentLengthMode& mode)
404 {
405 return mode == AutoFillContentLengthMode::EXTRA_LONG ? AUTO_FILL_SPRING_RESPONSE_EXTRA_LONG
406 : AUTO_FILL_SPRING_RESPONSE;
407 }
408
GetSpringAnimationDamping(const AutoFillContentLengthMode & mode)409 float AutoFillController::GetSpringAnimationDamping(const AutoFillContentLengthMode& mode)
410 {
411 return mode == AutoFillContentLengthMode::EXTRA_LONG ? AUTO_FILL_SPRING_DAMPING_FRACTION_EXTRA_LONG
412 : AUTO_FILL_SPRING_DAMPING_FRACTION;
413 }
414
UpdateAnimationTextRect()415 void AutoFillController::UpdateAnimationTextRect()
416 {
417 auto pattern = pattern_.Upgrade();
418 CHECK_NULL_VOID(pattern);
419 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern);
420 CHECK_NULL_VOID(textFieldPattern);
421 auto textRect = textFieldPattern->GetTextRect();
422 auto contentRect = textFieldPattern->GetTextContentRect();
423 animationTextRect_ = textRect;
424 animationTextRect_.SetLeft(contentRect.GetX());
425 }
426 } // namespace OHOS::Ace::NG