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}