• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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_ng/pattern/particle/particle_pattern.h"
17 
18 #include "core/components_ng/render/adapter/rosen_particle_context.h"
19 
20 namespace OHOS::Ace::NG {
21 namespace {
22 std::unordered_map<ParticleDisturbanceShapeType, std::string> shapes = {
23     { ParticleDisturbanceShapeType::RECT, "RECT" },
24     { ParticleDisturbanceShapeType::CIRCLE, "CIRCLE" },
25     { ParticleDisturbanceShapeType::ELLIPSE, "ELLIPSE" } };
ShapeTypeToString(ParticleDisturbanceShapeType type)26 std::string ShapeTypeToString(ParticleDisturbanceShapeType type)
27 {
28     auto it = shapes.find(type);
29     if (it != shapes.end()) {
30         return it->second;
31     }
32     return "Unknown";
33 }
34 } // namespace
35 class RosenRenderParticle;
OnVisibleChange(bool isVisible)36 void ParticlePattern::OnVisibleChange(bool isVisible)
37 {
38     if (HaveUnVisibleParent() == !isVisible) {
39         return;
40     }
41     SetHaveUnVisibleParent(!isVisible);
42     if (isVisible) {
43         auto host = GetHost();
44         auto context = host->GetRenderContext();
45         context->OnParticleOptionArrayUpdate(context->GetParticleOptionArray().value());
46     }
47 }
48 
OnAttachToMainTree()49 void ParticlePattern::OnAttachToMainTree()
50 {
51     auto host = GetHost();
52     auto parent = host->GetParent();
53     while (parent) {
54         if (InstanceOf<FrameNode>(parent)) {
55             auto frameNode = DynamicCast<FrameNode>(parent);
56             if (!frameNode->IsVisible()) {
57                 SetHaveUnVisibleParent(true);
58                 return;
59             }
60         }
61         parent = parent->GetParent();
62     }
63 }
64 
ParseAnnulusRegionJson(const ParticleAnnulusRegion & annulusRegion) const65 std::unique_ptr<JsonValue> ParticlePattern::ParseAnnulusRegionJson(const ParticleAnnulusRegion& annulusRegion) const
66 {
67     auto objectAnnulusRegionJson = JsonUtil::Create(true);
68     auto center = annulusRegion.GetCenter();
69     auto centerObj = JsonUtil::Create(true);
70     centerObj->Put("x", center.first.ToString().c_str());
71     centerObj->Put("y", center.second.ToString().c_str());
72     objectAnnulusRegionJson->Put("center", centerObj);
73     objectAnnulusRegionJson->Put("innerRadius", std::to_string(annulusRegion.GetInnerRadius().ConvertToPx()).c_str());
74     objectAnnulusRegionJson->Put("outerRadius", std::to_string(annulusRegion.GetOuterRadius().ConvertToPx()).c_str());
75     objectAnnulusRegionJson->Put("startAngle", std::to_string(annulusRegion.GetStartAngle()).c_str());
76     objectAnnulusRegionJson->Put("endAngle", std::to_string(annulusRegion.GetEndAngle()).c_str());
77     return objectAnnulusRegionJson;
78 }
79 
ParseEmitterParticleJson(const ParticleOption & particleOption) const80 std::unique_ptr<JsonValue> ParticlePattern::ParseEmitterParticleJson(const ParticleOption& particleOption) const
81 {
82     auto emitterOptionOpt = particleOption.GetEmitterOption();
83     auto objectParticleJson = JsonUtil::Create(true);
84     auto particle = emitterOptionOpt.GetParticle();
85     auto particleType = particle.GetParticleType();
86     auto particleConfig = particle.GetConfig();
87     if (particleType == ParticleType::POINT) {
88         auto objectConfigJson = JsonUtil::Create(true);
89         objectParticleJson->Put("type", "ParticleType.POINT");
90         auto pointParameter = particleConfig.GetPointParticleParameter();
91         auto radius = pointParameter.GetRadius();
92         objectConfigJson->Put("radius", std::to_string(radius).c_str());
93         objectParticleJson->Put("config", objectConfigJson);
94     } else {
95         objectParticleJson->Put("type", "ParticleType.IMAGE");
96         auto objectConfigJson = JsonUtil::Create(true);
97         auto imageParameter = particleConfig.GetImageParticleParameter();
98         auto imageSource = imageParameter.GetImageSource();
99         auto imageSize = imageParameter.GetSize();
100         auto imageWidth = imageSize.first.ToString();
101         auto imageHeight = imageSize.second.ToString();
102         objectConfigJson->Put("src", imageSource.c_str());
103         auto dimension = "[" + imageWidth + "," + imageHeight + "]";
104         objectConfigJson->Put("size", dimension.c_str());
105         auto objectFit = imageParameter.GetImageFit();
106         static const char* OBJECTFITVALUE[] = { "ImageFit.Fill", "ImageFit.Contain", "ImageFit.Cover", "ImageFit.Auto",
107             "ImageFit.FitHeight", "ImageFit.None", "ImageFit.ScaleDown", "ImageFit.TOP_START", "ImageFit.TOP",
108             "ImageFit.TOP_END", "ImageFit.START", "ImageFit.CENTER", "ImageFit.END", "ImageFit.BOTTOM_START",
109             "ImageFit.BOTTOM", "ImageFit.BOTTOM_END" };
110         if (objectFit.has_value()) {
111             auto objectFitValue = static_cast<uint32_t>(objectFit.value());
112             if (objectFitValue < sizeof(OBJECTFITVALUE) / sizeof(char*)) {
113                 objectConfigJson->Put("objectFit", OBJECTFITVALUE[objectFitValue]);
114             }
115         }
116         objectParticleJson->Put("config", objectConfigJson);
117     }
118     auto particleCount = particle.GetCount();
119     objectParticleJson->Put("count", std::to_string(particleCount).c_str());
120     auto lifeTimeOpt = particle.GetLifeTime();
121     if (lifeTimeOpt.has_value()) {
122         objectParticleJson->Put("lifetime", std::to_string(lifeTimeOpt.value()).c_str());
123     }
124     auto lifeTimeRangeOpt = particle.GetLifeTimeRange();
125     if (lifeTimeRangeOpt.has_value()) {
126         objectParticleJson->Put("lifetimeRange", std::to_string(lifeTimeRangeOpt.value()).c_str());
127     }
128     return objectParticleJson;
129 }
130 
GetEmitterJson(const std::unique_ptr<JsonValue> & objectParticlesJson,const ParticleOption & particleOption) const131 void ParticlePattern::GetEmitterJson(const std::unique_ptr<JsonValue>& objectParticlesJson,
132     const ParticleOption& particleOption) const
133 {
134     auto objectEmitterJson = JsonUtil::Create(true);
135     auto objectParticleJson = ParseEmitterParticleJson(particleOption);
136     objectEmitterJson->Put("particle", objectParticleJson);
137 
138     auto emitterOptionOpt = particleOption.GetEmitterOption();
139     auto emitterRateOpt = emitterOptionOpt.GetEmitterRate();
140     if (emitterRateOpt.has_value()) {
141         objectEmitterJson->Put("emitRate", std::to_string(emitterRateOpt.value()).c_str());
142     }
143     auto shapeOpt = emitterOptionOpt.GetShape();
144     if (shapeOpt.has_value()) {
145         auto shapeInt = static_cast<int32_t>(shapeOpt.value());
146         if (shapeInt == ParticleEmitterShape::CIRCLE) {
147             objectEmitterJson->Put("shape", "ParticleEmitterShape.CIRCLE");
148         } else if (shapeInt == ParticleEmitterShape::ELLIPSE) {
149             objectEmitterJson->Put("shape", "ParticleEmitterShape.ELLIPSE");
150         } else if (shapeInt == ParticleEmitterShape::ANNULUS) {
151             objectEmitterJson->Put("shape", "ParticleEmitterShape.ANNULUS");
152         } else {
153             objectEmitterJson->Put("shape", "ParticleEmitterShape.RECTANGLE");
154         }
155     }
156     auto pointOpt = emitterOptionOpt.GetPosition();
157     if (pointOpt.has_value()) {
158         auto position = "[" + pointOpt.value().first.ToString() + "," + pointOpt.value().second.ToString() + "]";
159         objectEmitterJson->Put("position", position.c_str());
160     }
161     auto sizeOpt = emitterOptionOpt.GetSize();
162     if (sizeOpt.has_value()) {
163         auto position = "[" + sizeOpt.value().first.ToString() + "," + sizeOpt.value().second.ToString() + "]";
164         objectEmitterJson->Put("size", position.c_str());
165     }
166     auto annulusRegionOpt = emitterOptionOpt.GetAnnulusRegion();
167     if (annulusRegionOpt.has_value()) {
168         auto objectAnnulusRegionJson = ParseAnnulusRegionJson(annulusRegionOpt.value());
169         objectEmitterJson->Put("annulusRegion", objectAnnulusRegionJson);
170     }
171     objectParticlesJson->Put("emitter", objectEmitterJson);
172 }
173 
ParseColorUpdater(ParticleColorPropertyUpdater & updater) const174 std::unique_ptr<JsonValue> ParticlePattern::ParseColorUpdater(ParticleColorPropertyUpdater& updater) const
175 {
176     auto updateType = updater.GetUpdateType();
177     auto config = updater.GetConfig();
178     auto objectUpdaterJson = JsonUtil::Create(true);
179     if (updateType == UpdaterType::RANDOM) {
180         objectUpdaterJson->Put("type", "ParticleUpdater.RANDOM");
181         auto randomConfig = config.GetRandomConfig();
182         auto redRandom = randomConfig.GetRedRandom();
183         auto greenRandom = randomConfig.GetGreenRandom();
184         auto blueRandom = randomConfig.GetBlueRandom();
185         auto alphaRandom = randomConfig.GetAlphaRandom();
186         auto configJson = JsonUtil::Create(true);
187         auto rString = "[" + std::to_string(redRandom.first) + "," +
188             std::to_string(redRandom.second) + "]";
189         configJson->Put("r", rString.c_str());
190         auto gString = "[" + std::to_string(greenRandom.first) + "," +
191             std::to_string(greenRandom.second) + "]";
192         configJson->Put("g", gString.c_str());
193         auto bString = "[" + std::to_string(blueRandom.first) + "," +
194             std::to_string(blueRandom.second) + "]";
195         configJson->Put("b", bString.c_str());
196         auto aString = "[" + std::to_string(alphaRandom.first) +  "," +
197             std::to_string(alphaRandom.second) + "]";
198         configJson->Put("a", aString.c_str());
199         objectUpdaterJson->Put("config", configJson);
200     } else if (updateType == UpdaterType::CURVE) {
201         objectUpdaterJson->Put("type", "ParticleUpdater.CURVE");
202         auto configArrayJson = JsonUtil::CreateArray(true);
203         auto& curveConfig = config.GetAnimationArray();
204         for (const auto& colorAnimationConfig : curveConfig) {
205             auto fromColor = colorAnimationConfig.GetFrom().ToString();
206             auto toColor = colorAnimationConfig.GetTo().ToString();
207             auto startMills = colorAnimationConfig.GetStartMills();
208             auto endMills = colorAnimationConfig.GetEndMills();
209             auto curve = colorAnimationConfig.GetCurve();
210             auto configJson = JsonUtil::Create(true);
211             configJson->Put("from", fromColor.c_str());
212             configJson->Put("to", toColor.c_str());
213             configJson->Put("startMillis", std::to_string(startMills).c_str());
214             configJson->Put("endMillis", std::to_string(endMills).c_str());
215             configJson->Put("curve", curve->ToString().c_str());
216             configArrayJson->Put(configJson);
217         }
218         objectUpdaterJson->Put("config", configArrayJson);
219     } else {
220         objectUpdaterJson->Put("type", "ParticleUpdater.NONE");
221         objectUpdaterJson->Put("config", "");
222     }
223     return objectUpdaterJson;
224 }
225 
GetColorJson(const std::unique_ptr<JsonValue> & objectParticlesJson,const ParticleOption & particleOption) const226 void ParticlePattern::GetColorJson(const std::unique_ptr<JsonValue>& objectParticlesJson,
227     const ParticleOption& particleOption) const
228 {
229     auto colorOptionOpt = particleOption.GetParticleColorOption();
230     if (!colorOptionOpt.has_value()) {
231         return;
232     }
233     auto objectColorJson = JsonUtil::Create(true);
234     auto colorOption = colorOptionOpt.value();
235     auto initRange = colorOption.GetRange();
236     auto colorDist = colorOption.GetDistribution();
237     objectColorJson->Put("range", ("[" + initRange.first.ToString() + "," +
238         initRange.second.ToString() +"]").c_str());
239     auto colorDistInt = colorDist.value_or(DistributionType::UNIFORM);
240     if (colorDistInt == DistributionType::UNIFORM) {
241         objectColorJson->Put("distributionType", "DistributionType::UNIFORM");
242     } else {
243         objectColorJson->Put("distributionType", "DistributionType::GAUSSIAN");
244     }
245     auto updaterOpt = colorOption.GetUpdater();
246     if (!updaterOpt.has_value()) {
247         objectParticlesJson->Put("color", objectColorJson);
248         return;
249     }
250     auto updater = updaterOpt.value();
251     auto objectUpdaterJson = ParseColorUpdater(updater);
252     objectColorJson->Put("updater", objectUpdaterJson);
253     objectParticlesJson->Put("color", objectColorJson);
254 }
255 
GetOpacityJson(const std::unique_ptr<JsonValue> & objectParticlesJson,const ParticleOption & particleOption) const256 void ParticlePattern::GetOpacityJson(const std::unique_ptr<JsonValue>& objectParticlesJson,
257     const ParticleOption& particleOption) const
258 {
259     auto opacityOptionOpt = particleOption.GetParticleOpacityOption();
260     if (!opacityOptionOpt.has_value()) {
261         return;
262     }
263     objectParticlesJson->Put("opacity", ParseFloatObjectJson(opacityOptionOpt.value()));
264 }
265 
GetScaleJson(const std::unique_ptr<JsonValue> & objectParticlesJson,const ParticleOption & particleOption) const266 void ParticlePattern::GetScaleJson(const std::unique_ptr<JsonValue>& objectParticlesJson,
267     const ParticleOption& particleOption) const
268 {
269     auto scaleOptionOpt = particleOption.GetParticleScaleOption();
270     if (!scaleOptionOpt.has_value()) {
271         return;
272     }
273     objectParticlesJson->Put("scale", ParseFloatObjectJson(scaleOptionOpt.value()));
274 }
275 
GetVelocityJson(const std::unique_ptr<JsonValue> & objectParticlesJson,const ParticleOption & particleOption) const276 void ParticlePattern::GetVelocityJson(const std::unique_ptr<JsonValue>& objectParticlesJson,
277     const ParticleOption& particleOption) const
278 {
279     auto velocityOptionOpt = particleOption.GetParticleVelocityOption();
280     if (!velocityOptionOpt.has_value()) {
281         return;
282     }
283     auto objectVelocityJson = JsonUtil::Create(true);
284     auto velocityValue = velocityOptionOpt.value();
285     auto speed = velocityValue.GetSpeedRange();
286     auto angle = velocityValue.GetAngleRange();
287     auto speedString = "[" + std::to_string(speed.first) + "," +
288             std::to_string(speed.second) + "]";
289     objectVelocityJson->Put("speed", speedString.c_str());
290     auto angleString = "[" + std::to_string(angle.first) + "," +
291             std::to_string(angle.second) + "]";
292     objectVelocityJson->Put("angle", angleString.c_str());
293     objectParticlesJson->Put("velocity", objectVelocityJson);
294 }
295 
GetAccelerationJson(const std::unique_ptr<JsonValue> & objectParticlesJson,const ParticleOption & particleOption) const296 void ParticlePattern::GetAccelerationJson(const std::unique_ptr<JsonValue>& objectParticlesJson,
297     const ParticleOption& particleOption) const
298 {
299     auto accelerationOpt = particleOption.GetParticleAccelerationOption();
300     if (!accelerationOpt.has_value()) {
301         return;
302     }
303     auto objectAccelerationJson = JsonUtil::Create(true);
304     auto acceleration = accelerationOpt.value();
305     auto speedOpt = acceleration.GetSpeed();
306     auto angleOpt = acceleration.GetAngle();
307     if (speedOpt.has_value()) {
308         objectAccelerationJson->Put("speed", ParseFloatObjectJson(speedOpt.value()));
309     }
310     if (angleOpt.has_value()) {
311         objectAccelerationJson->Put("angle", ParseFloatObjectJson(angleOpt.value()));
312     }
313     objectParticlesJson->Put("acceleration", objectAccelerationJson);
314 }
315 
GetSpinJson(const std::unique_ptr<JsonValue> & objectParticlesJson,const ParticleOption & particleOption) const316 void ParticlePattern::GetSpinJson(const std::unique_ptr<JsonValue>& objectParticlesJson,
317     const ParticleOption& particleOption) const
318 {
319     auto spinOptionOpt = particleOption.GetParticleSpinOption();
320     auto objectSpinJson = JsonUtil::Create(true);
321     if (!spinOptionOpt.has_value()) {
322         return;
323     }
324     objectParticlesJson->Put("spin", ParseFloatObjectJson(spinOptionOpt.value()));
325 }
326 
ParseFloatObjectJson(const ParticleFloatPropertyOption & floatObject) const327 std::unique_ptr<JsonValue> ParticlePattern::ParseFloatObjectJson(const ParticleFloatPropertyOption& floatObject) const
328 {
329     auto objectJson = JsonUtil::Create(true);
330     auto initRange = floatObject.GetRange();
331     objectJson->Put("range", ("[" + std::to_string(initRange.first) + "," +
332         std::to_string(initRange.second) + "]").c_str());
333 
334     auto updaterOpt = floatObject.GetUpdater();
335     if (!updaterOpt.has_value()) {
336         return objectJson;
337     }
338     auto objectUpdaterJson = JsonUtil::Create(true);
339     auto updater = updaterOpt.value();
340     auto updateType = updater.GetUpdaterType();
341     auto config = updater.GetConfig();
342     if (updateType == UpdaterType::RANDOM) {
343         objectUpdaterJson->Put("type", "ParticleUpdater.RANDOM");
344         auto randomConfig = config.GetRandomConfig();
345         auto configString = "[" + std::to_string(randomConfig.first) + "," +
346             std::to_string(randomConfig.second) + "]";
347         objectUpdaterJson->Put("config", configString.c_str());
348     } else if (updateType == UpdaterType::CURVE) {
349         objectUpdaterJson->Put("type", "ParticleUpdater.CURVE");
350         auto configArrayJson = JsonUtil::CreateArray(true);
351         auto& curveConfig = config.GetAnimations();
352         for (const auto& animationConfig : curveConfig) {
353             auto fromColor = animationConfig.GetFrom();
354             auto toColor = animationConfig.GetTo();
355             auto startMills = animationConfig.GetStartMills();
356             auto endMills = animationConfig.GetEndMills();
357             auto curve = animationConfig.GetCurve();
358             auto configJson = JsonUtil::Create(true);
359             configJson->Put("from", std::to_string(fromColor).c_str());
360             configJson->Put("to", std::to_string(toColor).c_str());
361             configJson->Put("startMillis", std::to_string(startMills).c_str());
362             configJson->Put("endMillis", std::to_string(endMills).c_str());
363             configJson->Put("curve", curve->ToString().c_str());
364             configArrayJson->Put(configJson);
365         }
366         objectUpdaterJson->Put("config", configArrayJson);
367     } else if (updateType == UpdaterType::NONE_UPDATER) {
368         objectUpdaterJson->Put("type", "ParticleUpdater.NONE");
369         objectUpdaterJson->Put("config", "");
370     }
371     objectJson->Put("updater", objectUpdaterJson);
372     return objectJson;
373 }
374 
ParseParticleObject(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const375 void ParticlePattern::ParseParticleObject(std::unique_ptr<JsonValue>& json,
376     const InspectorFilter& filter) const
377 {
378     auto host = GetHost();
379     CHECK_NULL_VOID(host);
380     auto context = host->GetRenderContext();
381     CHECK_NULL_VOID(context);
382     if (!context->GetParticleOptionArray().has_value()) {
383         return;
384     }
385     auto particleArray = context->GetParticleOptionArray().value();
386     auto objectParticlesArrayJson = JsonUtil::CreateArray(true);
387     for (auto& particle : particleArray) {
388         auto objectParticlesJson = JsonUtil::Create(true);
389         GetEmitterJson(objectParticlesJson, particle);
390         GetColorJson(objectParticlesJson, particle);
391         GetOpacityJson(objectParticlesJson, particle);
392         GetScaleJson(objectParticlesJson, particle);
393         GetVelocityJson(objectParticlesJson, particle);
394         GetAccelerationJson(objectParticlesJson, particle);
395         GetSpinJson(objectParticlesJson, particle);
396         objectParticlesArrayJson->Put(objectParticlesJson);
397     }
398     json->PutExtAttr("particles", objectParticlesArrayJson, filter);
399 }
400 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const401 void ParticlePattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
402 {
403     auto props = GetEmitterProperty();
404     if (props.size() > 0) {
405         auto array = JsonUtil::CreateArray(true);
406         for (size_t i = 0; i < props.size(); i++) {
407             auto object = ToEmitterPropertyJsonValue(props[i]);
408             array->Put(std::to_string(i).c_str(), object);
409         }
410         json->Put("emitter", array);
411     }
412     auto disturbance = GetDisturbance();
413     if (disturbance.size() > 0) {
414         auto disturbanceFieldsArray = JsonUtil::CreateArray(true);
415         for (size_t i = 0; i < disturbance.size(); i++) {
416             auto object = JsonUtil::Create(true);
417             object->Put("strength", disturbance[i].strength);
418             object->Put("shape", ShapeTypeToString(disturbance[i].shape).c_str());
419             auto size = JsonUtil::Create(true);
420             size->Put("width", disturbance[i].size[0]);
421             size->Put("height", disturbance[i].size[1]);
422             object->Put("size", size);
423             auto position = JsonUtil::Create(true);
424             size->Put("x", disturbance[i].position[0]);
425             size->Put("y", disturbance[i].position[1]);
426             object->Put("feather", disturbance[i].feather);
427             object->Put("noiseScale", disturbance[i].noiseScale);
428             object->Put("noiseFrequency", disturbance[i].noiseFrequency);
429             object->Put("noiseAmplitude", disturbance[i].noiseAmplitude);
430             disturbanceFieldsArray->Put(std::to_string(i).c_str(), object);
431         }
432         json->Put("disturbanceFields", disturbanceFieldsArray);
433     }
434     ParseParticleObject(json, filter);
435 }
436 
ToEmitterPropertyJsonValue(const EmitterProperty & emitterProperty) const437 std::unique_ptr<JsonValue> ParticlePattern::ToEmitterPropertyJsonValue(const EmitterProperty& emitterProperty) const
438 {
439     auto object = JsonUtil::Create(true);
440     object->Put("index", std::to_string(emitterProperty.index).c_str());
441     if (emitterProperty.emitRate.has_value()) {
442         object->Put("emitRate", std::to_string(*emitterProperty.emitRate).c_str());
443     }
444     if (emitterProperty.position.has_value()) {
445         auto positionObj = JsonUtil::Create(true);
446         positionObj->Put("x", std::to_string(emitterProperty.position->x).c_str());
447         positionObj->Put("y", std::to_string(emitterProperty.position->y).c_str());
448         object->Put("position", positionObj);
449     }
450     if (emitterProperty.size.has_value()) {
451         auto sizeObj = JsonUtil::Create(true);
452         sizeObj->Put("x", std::to_string(emitterProperty.size->x).c_str());
453         sizeObj->Put("y", std::to_string(emitterProperty.size->y).c_str());
454         object->Put("size", sizeObj);
455     }
456     if (emitterProperty.annulusRegion.has_value()) {
457         auto annulusRegionObj = ParseAnnulusRegionJson(emitterProperty.annulusRegion.value());
458         object->Put("annulusRegion", annulusRegionObj);
459     }
460     return object;
461 }
462 
UpdateDisturbance(const std::vector<ParticleDisturbance> & disturbanceArray)463 void ParticlePattern::UpdateDisturbance(const std::vector<ParticleDisturbance>& disturbanceArray)
464 {
465     if (disturbanceArray.size() == 0) {
466         return;
467     }
468     const std::vector<ParticleDisturbance>& disturbance = GetDisturbance();
469     if (disturbance.size() != disturbanceArray.size()) {
470         SetDisturbance(disturbanceArray);
471         auto frameNode = GetHost();
472         RosenRenderParticle::UpdateDisturbance(frameNode, disturbanceArray);
473         return;
474     }
475     bool equal = true;
476     for (size_t i = 0; i < disturbance.size(); i++) {
477         ParticleDisturbance src = disturbance[i];
478         ParticleDisturbance dst = disturbanceArray[i];
479         if (src != dst) {
480             equal = false;
481             break;
482         }
483     }
484     if (equal) {
485         return;
486     }
487     SetDisturbance(disturbanceArray);
488     auto frameNode = GetHost();
489     RosenRenderParticle::UpdateDisturbance(frameNode, disturbanceArray);
490 }
491 
updateEmitterPosition(std::vector<EmitterProperty> & props)492 void ParticlePattern::updateEmitterPosition(std::vector<EmitterProperty>& props)
493 {
494     auto frameNode = GetHost();
495     for (EmitterProperty& prop : props) {
496         prop.index = prop.index >= GetEmitterCount() ? 0 : prop.index;
497     }
498     SetEmitterProperty(props);
499     RosenRenderParticle::updateEmitterPosition(frameNode, props);
500 }
501 } // namespace OHOS::Ace::NG