• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 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
16const animationDuration: number = 500; // move动画时长
17const opacityChangeValue: number = 0.1; // opacity每次变化的值
18const opacityChangeRange: number = 1; // opacity变化的范围
19const translateYChangeValue: number = 180; // translateY每次变化的值
20const translateYChangeRange: number = 250; // translateY变化的范围
21const scaleXChangeValue: number = 0.6; // scaleX每次变化的值
22const scaleXChangeRange: number = 0.8; // scaleX每次变化的值
23
24// 缩放属性类
25@Observed
26class ScaleStyle {
27  public scaleX: number = 0.3;
28  public scaleY: number = 0.3;
29}
30
31// 位移属性类
32@Observed
33class TranslateStyle {
34  public translateX: number = 0;
35  public translateY: number = 0;
36}
37
38// 样式属性类,嵌套ScaleStyle, TranslateStyle
39@Observed
40class UIStyle {
41  translateStyle: TranslateStyle = new TranslateStyle();
42  scaleStyle: ScaleStyle = new ScaleStyle();
43}
44
45@Component
46struct SpecialImage {
47  @Link specialImageScaleStyle: ScaleStyle;
48  private opacityNum: number = 0.5; // 默认透明度
49
50  private isRenderSpecialImage(): number {
51    // Image每次渲染时透明度增加0.1, 在0-1之间循环
52    this.opacityNum = (this.opacityNum + opacityChangeValue) % opacityChangeRange;
53    return this.opacityNum;
54  }
55
56  build() {
57    Column() {
58      Image($r('app.media.icon'))
59        .width($r('app.integer.special_image_width'))
60        .height($r('app.integer.special_image_width'))
61        .margin({ top: $r('app.integer.image_margin_top') })
62        .scale({
63          x: this.specialImageScaleStyle.scaleX,
64          y: this.specialImageScaleStyle.scaleY
65        })
66        .opacity(this.isRenderSpecialImage())
67      Text("SpecialImage")
68        .fontColor($r('app.color.text_color'))
69        .fontWeight(FontWeight.Medium)
70        .fontSize($r('app.integer.button_font_size'))
71        .margin({ top: $r('app.integer.text_margin_top') })
72    }
73    .backgroundColor($r('app.color.stack_color'))
74    .width($r('app.integer.stack_width'))
75    .height($r('app.integer.stack_height'))
76    .margin({ top: $r('app.integer.stack_margin_top') })
77    .borderRadius($r('app.integer.stack_border_radius'))
78  }
79}
80
81@Component
82struct ComponentA {
83  @ObjectLink scaleStyle: ScaleStyle;
84  @ObjectLink translateStyle: TranslateStyle;
85
86  build() {
87    Column() {
88      // 受状态变量影响的组件
89      SpecialImage({
90        specialImageScaleStyle: this.scaleStyle
91      })
92      Stack() {
93        Column() {
94          Image($r('app.media.icon'))
95            .opacity($r('app.float.icon_opacity'))
96            .scale({
97              x: this.scaleStyle.scaleX,
98              y: this.scaleStyle.scaleY
99            })
100            .width($r('app.integer.stack_icon_width'))
101            .height($r('app.integer.stack_icon_height'))
102        }
103        .width('100%')
104        .position({ y: $r('app.integer.stack_column_position_y') })
105
106        Stack() {
107          Text("Hello World")
108            .fontColor($r('app.color.text_color'))
109            .fontWeight(FontWeight.Medium)
110            .fontSize($r('app.integer.button_font_size'))
111            .margin({ top: $r('app.integer.text_margin_top') })
112        }
113        .position({
114          x: $r('app.integer.text_position_x'),
115          y: $r('app.integer.text_position_y')
116        })
117        .width('100%')
118        .height('100%')
119      }
120      .margin({ top: $r('app.integer.stack_margin_top') })
121      .borderRadius($r('app.integer.stack_border_radius'))
122      .backgroundColor($r('app.color.stack_color'))
123      .width($r('app.integer.stack_width'))
124      .height($r('app.integer.stack_height'))
125      .translate({
126        x: this.translateStyle.translateX,
127        y: this.translateStyle.translateY
128      })
129
130      // 通过按钮点击回调修改状态变量的值,引起相应的组件刷新
131      Column() {
132        Button("Move")
133          .width($r('app.integer.button_width'))
134          .fontSize($r('app.integer.button_font_size'))
135          .backgroundColor($r('app.color.button_color'))
136          .margin({ bottom: $r('app.integer.button_margin_bottom') })
137          .onClick(() => {
138            animateTo({
139              duration: animationDuration
140            }, () => {
141              this.translateStyle.translateY = (this.translateStyle.translateY + translateYChangeValue) % translateYChangeRange;
142            })
143          })
144        Button("Scale")
145          .backgroundColor($r('app.color.button_color'))
146          .fontSize($r('app.integer.button_font_size'))
147          .width($r('app.integer.button_width'))
148          .margin({ bottom: $r('app.integer.button_margin_bottom') })
149          .onClick(() => {
150            this.scaleStyle.scaleX = (this.scaleStyle.scaleX + scaleXChangeValue) % scaleXChangeRange;
151          })
152      }
153      .position({
154        y: $r('app.integer.button_column_position_y')
155      })
156      .height('100%')
157      .width('100%')
158    }
159    .width('100%')
160    .height('100%')
161  }
162}
163
164@Component
165export struct DFXStateAfterOptimization {
166  @State uiStyle: UIStyle = new UIStyle();
167
168  build() {
169    Stack() {
170      ComponentA({
171        scaleStyle: this.uiStyle.scaleStyle,
172        translateStyle: this.uiStyle.translateStyle,
173      })
174    }
175    .backgroundColor($r('app.color.stack_background'))
176  }
177}