Showing
11 changed files
with
418 additions
and
6 deletions
| @@ -3,15 +3,15 @@ | @@ -3,15 +3,15 @@ | ||
| 3 | { | 3 | { |
| 4 | "name": "shared_desc", | 4 | "name": "shared_desc", |
| 5 | "value": "全局工具包" | 5 | "value": "全局工具包" |
| 6 | - } , | 6 | + }, |
| 7 | { | 7 | { |
| 8 | "name": "net_core_no_network", | 8 | "name": "net_core_no_network", |
| 9 | "value": "当前无网络,请重试" | 9 | "value": "当前无网络,请重试" |
| 10 | - } , | 10 | + }, |
| 11 | { | 11 | { |
| 12 | "name": "net_core_weak_network", | 12 | "name": "net_core_weak_network", |
| 13 | "value": "当前无网络,请重试" | 13 | "value": "当前无网络,请重试" |
| 14 | - } , | 14 | + }, |
| 15 | { | 15 | { |
| 16 | "name": "net_core_page_error_network", | 16 | "name": "net_core_page_error_network", |
| 17 | "value": "网络出小差了,请检查下网络" | 17 | "value": "网络出小差了,请检查下网络" |
| @@ -47,6 +47,10 @@ | @@ -47,6 +47,10 @@ | ||
| 47 | { | 47 | { |
| 48 | "name": "auditing_core_error", | 48 | "name": "auditing_core_error", |
| 49 | "value": "内容已下线" | 49 | "value": "内容已下线" |
| 50 | + }, | ||
| 51 | + { | ||
| 52 | + "name": "image_request_fail", | ||
| 53 | + "value": "图片加载失败,请检查网络" | ||
| 50 | } | 54 | } |
| 51 | ] | 55 | ] |
| 52 | } | 56 | } |
| 1 | import { PhotoListBean } from 'wdBean/Index'; | 1 | import { PhotoListBean } from 'wdBean/Index'; |
| 2 | import { Logger } from 'wdKit/Index'; | 2 | import { Logger } from 'wdKit/Index'; |
| 3 | -import { MultiPictureDetailItemComponent } from './MultiPictureDetailItemComponent'; | ||
| 4 | import { display, router } from '@kit.ArkUI'; | 3 | import { display, router } from '@kit.ArkUI'; |
| 5 | import { ImageDownloadComponent } from './ImageDownloadComponent'; | 4 | import { ImageDownloadComponent } from './ImageDownloadComponent'; |
| 5 | +import { ImageItemView } from './view/ImageItemView'; | ||
| 6 | 6 | ||
| 7 | const TAG = 'ImageSwiperComponent'; | 7 | const TAG = 'ImageSwiperComponent'; |
| 8 | 8 | ||
| @@ -17,6 +17,9 @@ export struct ImageSwiperComponent { | @@ -17,6 +17,9 @@ export struct ImageSwiperComponent { | ||
| 17 | private screenWidth: number = 0 | 17 | private screenWidth: number = 0 |
| 18 | private picWidth: number = 0 | 18 | private picWidth: number = 0 |
| 19 | @State picHeight: number = 0 | 19 | @State picHeight: number = 0 |
| 20 | + @State isEnableSwipe: boolean = true; | ||
| 21 | + | ||
| 22 | + // @Provide bgc: Color = Color.White; | ||
| 20 | 23 | ||
| 21 | //watch监听页码回调 | 24 | //watch监听页码回调 |
| 22 | onCurrentPageNumUpdated(): void { | 25 | onCurrentPageNumUpdated(): void { |
| @@ -53,7 +56,8 @@ export struct ImageSwiperComponent { | @@ -53,7 +56,8 @@ export struct ImageSwiperComponent { | ||
| 53 | if (this.photoList && this.photoList?.length > 0) { | 56 | if (this.photoList && this.photoList?.length > 0) { |
| 54 | Swiper(this.swiperController) { | 57 | Swiper(this.swiperController) { |
| 55 | ForEach(this.photoList, (item: PhotoListBean) => { | 58 | ForEach(this.photoList, (item: PhotoListBean) => { |
| 56 | - MultiPictureDetailItemComponent({ MultiPictureDetailItem: item }) | 59 | + // MultiPictureDetailItemComponent({ MultiPictureDetailItem: item }) |
| 60 | + ImageItemView({ MultiPictureDetailItem: item, isEnableSwipe: this.isEnableSwipe }) | ||
| 57 | }) | 61 | }) |
| 58 | } | 62 | } |
| 59 | .index(this.swiperIndex) | 63 | .index(this.swiperIndex) |
| 1 | +import { image } from '@kit.ImageKit'; | ||
| 2 | +import { matrix4, promptAction, window } from '@kit.ArkUI'; | ||
| 3 | +import { BusinessError } from '@kit.BasicServicesKit'; | ||
| 4 | +import { ScaleModel } from '../../model/ScaleModel'; | ||
| 5 | +import { OffsetModel } from '../../model/OffsetModel'; | ||
| 6 | +import { windowSizeManager } from '../../utils/Managers'; | ||
| 7 | +import { runWithAnimation } from '../../utils/FuncUtils'; | ||
| 8 | +import { PhotoListBean } from 'wdBean/Index'; | ||
| 9 | +import { http } from '@kit.NetworkKit'; | ||
| 10 | + | ||
| 11 | +// TODO:知识点:组件复用 | ||
| 12 | +@Reusable | ||
| 13 | +@Component | ||
| 14 | +export struct ImageItemView { | ||
| 15 | + @Consume private bgc: Color; | ||
| 16 | + @Link isEnableSwipe: boolean; // TODO:需求:多图切换 | ||
| 17 | + @State isEnableOffset: boolean = false; | ||
| 18 | + @State imageScaleInfo: ScaleModel = new ScaleModel(1.0, 1.0, 1.5, 0.3); | ||
| 19 | + @State imageOffsetInfo: OffsetModel = new OffsetModel(0, 0); | ||
| 20 | + @State matrix: matrix4.Matrix4Transit = matrix4.identity().copy(); | ||
| 21 | + @State imagePixelMap: image.PixelMap | null = null; // 当前图片pixelMap,用于Image组件显示 | ||
| 22 | + @State fitWH: "width" | "height" | undefined = undefined; // 表示当前图片是根据宽度适配还是高度适配 | ||
| 23 | + @State imageDefaultSize: image.Size = { width: 0, height: 0 }; // 图片默认大小,即,与屏幕大小最适配的显示大小 | ||
| 24 | + imageUri: string = ""; // 当前图片uri | ||
| 25 | + imageWHRatio: number = 0; // 图片原始宽高比 | ||
| 26 | + private MultiPictureDetailItem: PhotoListBean = {} as PhotoListBean | ||
| 27 | + @State imageBuffer: ArrayBuffer | undefined = undefined; // 图片ArrayBuffer | ||
| 28 | + | ||
| 29 | + aboutToAppear(): void { | ||
| 30 | + this.imageUri = this.MultiPictureDetailItem.picPath | ||
| 31 | + this.getPicture() | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 通过http的request方法从网络下载图片资源 | ||
| 36 | + */ | ||
| 37 | + async getPicture() { | ||
| 38 | + console.info(`cj2024 getPicture`) | ||
| 39 | + http.createHttp() | ||
| 40 | + .request(this.imageUri, | ||
| 41 | + (error: BusinessError, data: http.HttpResponse) => { | ||
| 42 | + if (error) { | ||
| 43 | + // 下载失败时弹窗提示检查网络,不执行后续逻辑 | ||
| 44 | + promptAction.showToast({ | ||
| 45 | + message: $r('app.string.image_request_fail'), | ||
| 46 | + duration: 2000 | ||
| 47 | + }) | ||
| 48 | + return; | ||
| 49 | + } | ||
| 50 | + this.transcodePixelMap(data); | ||
| 51 | + // 判断网络获取到的资源是否为ArrayBuffer类型 | ||
| 52 | + console.info(`cj2024 getPicture ${data.result}`) | ||
| 53 | + if (data.result instanceof ArrayBuffer) { | ||
| 54 | + console.info(`cj2024 getPicture 222`) | ||
| 55 | + this.imageBuffer = data.result as ArrayBuffer; | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + ) | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * 使用createPixelMap将ArrayBuffer类型的图片装换为PixelMap类型 | ||
| 63 | + * @param data:网络获取到的资源 | ||
| 64 | + */ | ||
| 65 | + transcodePixelMap(data: http.HttpResponse) { | ||
| 66 | + console.info(`cj2024 transcodePixelMap ${data.responseCode}`) | ||
| 67 | + if (http.ResponseCode.OK === data.responseCode) { | ||
| 68 | + const imageData: ArrayBuffer = data.result as ArrayBuffer; | ||
| 69 | + // 通过ArrayBuffer创建图片源实例。 | ||
| 70 | + const imageSource: image.ImageSource = image.createImageSource(imageData); | ||
| 71 | + this.initCurrentImageInfo(imageSource); | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + /** | ||
| 76 | + * 根据图片宽高比及窗口大小计算图片的默认宽高,即,图片最适配屏幕的大小 | ||
| 77 | + * @param imageWHRatio:图片原始宽高比 | ||
| 78 | + * @param size:窗口大小{with:number,height:number} | ||
| 79 | + * @returns image.Size | ||
| 80 | + */ | ||
| 81 | + calcImageDefaultSize(imageWHRatio: number, size: window.Size): image.Size { | ||
| 82 | + let width = 0 | ||
| 83 | + let height = 0; | ||
| 84 | + if (imageWHRatio > size.width / size.height) { | ||
| 85 | + // 图片宽高比大于屏幕宽高比,图片默认以屏幕宽度进行显示 | ||
| 86 | + width = size.width; | ||
| 87 | + height = size.width / imageWHRatio; | ||
| 88 | + } else { | ||
| 89 | + height = size.height; | ||
| 90 | + width = size.height * imageWHRatio; | ||
| 91 | + } | ||
| 92 | + return { width: width, height: height }; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * TODO:知识点:根据图片大小(宽高<=屏幕宽高)和屏幕大小计算图片放大适配屏幕进行显示的缩放倍率 | ||
| 97 | + * @param imageSize:图片当前大小 | ||
| 98 | + * @param windowSize:窗口大小 | ||
| 99 | + * @returns:缩放倍率 | ||
| 100 | + */ | ||
| 101 | + calcFitScaleRatio(imageSize: image.Size, windowSize: window.Size): number { | ||
| 102 | + let ratio: number = 1.0; | ||
| 103 | + if (windowSize.width > imageSize.width) { | ||
| 104 | + ratio = windowSize.width / imageSize.width; | ||
| 105 | + } else { | ||
| 106 | + ratio = windowSize.height / imageSize.height; | ||
| 107 | + } | ||
| 108 | + return ratio; | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + /** | ||
| 112 | + * 设置当前图片的相关信息:uri、whRatio、pixelMap、fitWH、defaultSize、maxScaleValue | ||
| 113 | + * TODO:知识点:提前获取图片的信息,以进行Image组件的尺寸设置及后续的相关计算 | ||
| 114 | + */ | ||
| 115 | + initCurrentImageInfo(imageSource: image.ImageSource): void { | ||
| 116 | + this.matrix = matrix4.identity().copy(); | ||
| 117 | + // const imageSource: image.ImageSource = image.createImageSource(this.imageUri); | ||
| 118 | + imageSource.getImageInfo(0).then((data: image.ImageInfo) => { | ||
| 119 | + this.imageWHRatio = data.size.width / data.size.height; | ||
| 120 | + this.imageDefaultSize = this.calcImageDefaultSize(this.imageWHRatio, windowSizeManager.get()); | ||
| 121 | + if (this.imageDefaultSize.width === windowSizeManager.get().width) { | ||
| 122 | + this.fitWH = "width"; | ||
| 123 | + } else { | ||
| 124 | + this.fitWH = "height"; | ||
| 125 | + } | ||
| 126 | + this.imageScaleInfo.maxScaleValue += this.fitWH === "width" ? | ||
| 127 | + (windowSizeManager.get().height / this.imageDefaultSize.height) : | ||
| 128 | + (windowSizeManager.get().width / this.imageDefaultSize.width); | ||
| 129 | + }).catch((err: BusinessError) => { | ||
| 130 | + console.error(`[error][getImageInfo]${err.message}`); | ||
| 131 | + }); | ||
| 132 | + imageSource.createPixelMap().then((data: image.PixelMap) => { | ||
| 133 | + this.imagePixelMap = data; | ||
| 134 | + }).catch((err: BusinessError) => { | ||
| 135 | + console.error(`[error][createPixelMap]${err.message}`); | ||
| 136 | + }); | ||
| 137 | + this.isEnableOffset = false; | ||
| 138 | + this.imageScaleInfo.reset(); | ||
| 139 | + this.imageOffsetInfo.reset(); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + /** | ||
| 143 | + * 在图片消失时,将当前图片的信息设置为默认值 | ||
| 144 | + */ | ||
| 145 | + resetCurrentImageInfo(): void { | ||
| 146 | + this.imageScaleInfo.reset(); | ||
| 147 | + this.imageOffsetInfo.reset(); | ||
| 148 | + this.matrix = matrix4.identity().copy(); | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + /** | ||
| 152 | + * TODO:需求:在偏移时评估是否到达边界,以便进行位移限制与图片的切换 | ||
| 153 | + * @returns:长度为4的boolean数组,表示上下左右是否到达边界 | ||
| 154 | + */ | ||
| 155 | + evaluateBound(): boolean[] { | ||
| 156 | + return [false, false, false, false]; | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + build() { | ||
| 160 | + Stack() { | ||
| 161 | + Image(this.imagePixelMap)// TODO:知识点:宽高只根据其尺寸设置一个,通过保持宽高比来设置另一个属性 | ||
| 162 | + .width(this.fitWH === "width" ? "100%" : undefined) | ||
| 163 | + .height(this.fitWH === "height" ? "100%" : undefined) | ||
| 164 | + .aspectRatio(this.imageWHRatio) | ||
| 165 | + .objectFit(ImageFit.Cover)// TODO:知识点:保持宽高比进行缩放,可以超出父组件,以便实现多图切换的增强功能 | ||
| 166 | + .autoResize(false) | ||
| 167 | + .transform(this.matrix)// TODO:知识点:通过matrix控制图片的缩放 | ||
| 168 | + .defaultFocus(true) | ||
| 169 | + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) | ||
| 170 | + .offset({ | ||
| 171 | + // TODO:知识点:通过offset控制图片的偏移 | ||
| 172 | + x: this.imageOffsetInfo.currentX, | ||
| 173 | + y: this.imageOffsetInfo.currentY | ||
| 174 | + }) | ||
| 175 | + } | ||
| 176 | + .onBlur(() => { | ||
| 177 | + this.resetCurrentImageInfo(); | ||
| 178 | + }) | ||
| 179 | + // .backgroundColor(this.bgc) | ||
| 180 | + .alignContent(Alignment.Center) | ||
| 181 | + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) | ||
| 182 | + .width("100%") | ||
| 183 | + .height("100%") | ||
| 184 | + .gesture( | ||
| 185 | + GestureGroup( | ||
| 186 | + GestureMode.Exclusive, | ||
| 187 | + // TODO:知识点:双击切换图片大小 | ||
| 188 | + TapGesture({ count: 2 }) | ||
| 189 | + .onAction(() => { | ||
| 190 | + let fn: Function; | ||
| 191 | + // 已经是放大状态下,双击缩小 | ||
| 192 | + if (this.imageScaleInfo.scaleValue > this.imageScaleInfo.defaultScaleValue) { | ||
| 193 | + fn = () => { | ||
| 194 | + this.isEnableSwipe = true; | ||
| 195 | + this.imageScaleInfo.reset(); | ||
| 196 | + this.imageOffsetInfo.reset(); | ||
| 197 | + this.matrix = matrix4.identity().copy(); | ||
| 198 | + }; | ||
| 199 | + } else { | ||
| 200 | + // 已经是缩小状态,双击放大 | ||
| 201 | + fn = () => { | ||
| 202 | + this.isEnableSwipe = false; | ||
| 203 | + const ratio: number = this.calcFitScaleRatio(this.imageDefaultSize, windowSizeManager.get()); | ||
| 204 | + this.imageScaleInfo.scaleValue = ratio; | ||
| 205 | + this.imageOffsetInfo.reset(); | ||
| 206 | + this.matrix = matrix4.identity().scale({ | ||
| 207 | + x: ratio, | ||
| 208 | + y: ratio, | ||
| 209 | + }).copy(); | ||
| 210 | + this.imageScaleInfo.stash(); | ||
| 211 | + } | ||
| 212 | + } | ||
| 213 | + runWithAnimation(fn); | ||
| 214 | + }), | ||
| 215 | + // 单击切换背景色 | ||
| 216 | + // TapGesture({ count: 1 }).onAction(() => { | ||
| 217 | + // runWithAnimation(() => { | ||
| 218 | + // this.bgc = this.bgc === Color.White ? Color.Black : Color.White; | ||
| 219 | + // }); | ||
| 220 | + // }), | ||
| 221 | + // TODO:知识点:双指捏合缩放图片 | ||
| 222 | + PinchGesture({ fingers: 2, distance: 1 }) | ||
| 223 | + .onActionUpdate((event: GestureEvent) => { | ||
| 224 | + this.imageScaleInfo.scaleValue = this.imageScaleInfo.lastValue * event.scale; | ||
| 225 | + // TODO:知识点:缩放时不允许大于最大缩放因子+额外缩放因子,不允许小于默认大小-额外缩放因子,额外缩放因子用于提升用户体验 | ||
| 226 | + if (this.imageScaleInfo.scaleValue > this.imageScaleInfo.maxScaleValue * | ||
| 227 | + (1 + this.imageScaleInfo.extraScaleValue) | ||
| 228 | + ) { | ||
| 229 | + this.imageScaleInfo.scaleValue = this.imageScaleInfo.maxScaleValue * | ||
| 230 | + (1 + this.imageScaleInfo.extraScaleValue); | ||
| 231 | + } | ||
| 232 | + if (this.imageScaleInfo.scaleValue < this.imageScaleInfo.defaultScaleValue * | ||
| 233 | + (1 - this.imageScaleInfo.extraScaleValue)) { | ||
| 234 | + this.imageScaleInfo.scaleValue = this.imageScaleInfo.defaultScaleValue * | ||
| 235 | + (1 - this.imageScaleInfo.extraScaleValue); | ||
| 236 | + } | ||
| 237 | + // TODO:知识点:matrix默认缩放中心为组件中心 | ||
| 238 | + this.matrix = matrix4.identity().scale({ | ||
| 239 | + x: this.imageScaleInfo.scaleValue, | ||
| 240 | + y: this.imageScaleInfo.scaleValue, | ||
| 241 | + }).copy(); | ||
| 242 | + console.debug(this.imageScaleInfo.toString()); | ||
| 243 | + }) | ||
| 244 | + .onActionEnd((event: GestureEvent) => { | ||
| 245 | + /** | ||
| 246 | + * TODO:知识点:当小于默认大小时,恢复为默认大小 | ||
| 247 | + */ | ||
| 248 | + if (this.imageScaleInfo.scaleValue < this.imageScaleInfo.defaultScaleValue) { | ||
| 249 | + runWithAnimation(() => { | ||
| 250 | + this.imageScaleInfo.reset(); | ||
| 251 | + this.imageOffsetInfo.reset(); | ||
| 252 | + this.matrix = matrix4.identity().copy(); | ||
| 253 | + }) | ||
| 254 | + } | ||
| 255 | + // TODO:知识点:当大于最大缩放因子时,恢复到最大 | ||
| 256 | + if (this.imageScaleInfo.scaleValue > this.imageScaleInfo.maxScaleValue) { | ||
| 257 | + runWithAnimation(() => { | ||
| 258 | + this.imageScaleInfo.scaleValue = this.imageScaleInfo.maxScaleValue; | ||
| 259 | + this.matrix = matrix4.identity() | ||
| 260 | + .scale({ | ||
| 261 | + x: this.imageScaleInfo.maxScaleValue, | ||
| 262 | + y: this.imageScaleInfo.maxScaleValue | ||
| 263 | + }); | ||
| 264 | + }) | ||
| 265 | + } | ||
| 266 | + this.imageScaleInfo.stash(); | ||
| 267 | + }), | ||
| 268 | + // // TODO:知识点:滑动图片 | ||
| 269 | + // PanGesture({ fingers: 1 })// TODO:需求:默认大小下左右滑动应当是切换图片 | ||
| 270 | + // .onActionUpdate((event: GestureEvent) => { | ||
| 271 | + // if (this.imageScaleInfo.scaleValue === this.imageScaleInfo.defaultScaleValue) { | ||
| 272 | + // // 默认大小下不允许移动 | ||
| 273 | + // return; | ||
| 274 | + // } | ||
| 275 | + // this.imageOffsetInfo.currentX = this.imageOffsetInfo.lastX + event.offsetX; | ||
| 276 | + // this.imageOffsetInfo.currentY = this.imageOffsetInfo.lastY + event.offsetY; | ||
| 277 | + // }) | ||
| 278 | + // .onActionEnd((event: GestureEvent) => { | ||
| 279 | + // this.imageOffsetInfo.stash(); | ||
| 280 | + // }) | ||
| 281 | + ), | ||
| 282 | + ) | ||
| 283 | + } | ||
| 284 | +} |
| 1 | +@Observed | ||
| 2 | +export class OffsetModel { | ||
| 3 | + public currentX: number; | ||
| 4 | + public currentY: number; | ||
| 5 | + public lastX: number = 0; | ||
| 6 | + public lastY: number = 0; | ||
| 7 | + | ||
| 8 | + constructor(currentX: number = 0, currentY: number = 0) { | ||
| 9 | + this.currentX = currentX; | ||
| 10 | + this.currentY = currentY; | ||
| 11 | + } | ||
| 12 | + | ||
| 13 | + reset(): void { | ||
| 14 | + this.currentX = 0; | ||
| 15 | + this.currentY = 0; | ||
| 16 | + this.lastX = 0; | ||
| 17 | + this.lastY = 0; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + stash(): void { | ||
| 21 | + this.lastX = this.currentX; | ||
| 22 | + this.lastY = this.currentY; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + toString(): string { | ||
| 26 | + return `[currentX: ${this.currentX} currentY: ${this.currentY} lastX: ${this.lastX} lastY: ${this.lastY}]`; | ||
| 27 | + } | ||
| 28 | +} |
| 1 | +@Observed | ||
| 2 | +export class ScaleModel { | ||
| 3 | + /** | ||
| 4 | + * scaleValue: 本次缩放因子,用于控制图片的大小显示 | ||
| 5 | + * lastValue:记录上次缩放完后的缩放因子 | ||
| 6 | + * defaultMaxScaleValue:默认的最大放大值 | ||
| 7 | + * defaultScaleValue:默认缩放值,1 | ||
| 8 | + */ | ||
| 9 | + public scaleValue: number; | ||
| 10 | + public lastValue: number; | ||
| 11 | + public maxScaleValue: number; | ||
| 12 | + public extraScaleValue: number; | ||
| 13 | + public readonly defaultScaleValue: number = 1; | ||
| 14 | + | ||
| 15 | + constructor(scaleValue: number = 1.0, lastValue: number = 1.0, | ||
| 16 | + maxScaleValue: number = 1.5, extraScaleValue: number = 0.2) { | ||
| 17 | + this.scaleValue = scaleValue; | ||
| 18 | + this.lastValue = lastValue; | ||
| 19 | + this.maxScaleValue = maxScaleValue; | ||
| 20 | + this.extraScaleValue = extraScaleValue; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + reset(): void { | ||
| 24 | + this.scaleValue = this.defaultScaleValue; | ||
| 25 | + this.lastValue = this.scaleValue; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + stash(): void { | ||
| 29 | + this.lastValue = this.scaleValue; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + toString(): string { | ||
| 33 | + return `[scaleValue: ${this.scaleValue} lastValue: ${this.lastValue}]`; | ||
| 34 | + } | ||
| 35 | +} |
| 1 | +/** | ||
| 2 | + * 给函数的执行加上动画 | ||
| 3 | + * @param fn:要在动画内执行的回调函数,通常fn里面会改变状态变量 | ||
| 4 | + * @param duration:动画持续时长 | ||
| 5 | + * @param curve:动画区线 | ||
| 6 | + */ | ||
| 7 | +import { ImageViewerConstants } from '../constants/ImageViewerConstants'; | ||
| 8 | + | ||
| 9 | +export function runWithAnimation( | ||
| 10 | + fn: Function, | ||
| 11 | + duration: number = ImageViewerConstants.ANIMATE_DURATION, | ||
| 12 | + curve: Curve = Curve.Smooth): void { | ||
| 13 | + animateTo({ duration: duration, curve: curve }, () => { | ||
| 14 | + fn(); | ||
| 15 | + }) | ||
| 16 | +} |
| 1 | +import { window } from '@kit.ArkUI'; | ||
| 2 | + | ||
| 3 | +class WindowSizeManager { | ||
| 4 | + private size: window.Size = { width: 0, height: 0 }; | ||
| 5 | + | ||
| 6 | + constructor() { | ||
| 7 | + window.getLastWindow(getContext()).then((value: window.Window) => { | ||
| 8 | + const rect: window.Rect = value.getWindowProperties().windowRect; | ||
| 9 | + this.size.width = px2vp(rect.width); | ||
| 10 | + this.size.height = px2vp(rect.height); | ||
| 11 | + console.log(`[windowWidth]${this.size.width} [windowHeight]${this.size.height}`); | ||
| 12 | + }) | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + get(): window.Size { | ||
| 16 | + return this.size; | ||
| 17 | + } | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +export const windowSizeManager: WindowSizeManager = new WindowSizeManager(); |
| @@ -39,6 +39,14 @@ | @@ -39,6 +39,14 @@ | ||
| 39 | { | 39 | { |
| 40 | "name": "image_request_fail", | 40 | "name": "image_request_fail", |
| 41 | "value": "图片加载失败,请检查网络" | 41 | "value": "图片加载失败,请检查网络" |
| 42 | + }, | ||
| 43 | + { | ||
| 44 | + "name": "EntryAbility_desc", | ||
| 45 | + "value": "$string:app_desc" | ||
| 46 | + }, | ||
| 47 | + { | ||
| 48 | + "name": "reason_read_write_media", | ||
| 49 | + "value": "user_grant" | ||
| 42 | } | 50 | } |
| 43 | ] | 51 | ] |
| 44 | } | 52 | } |
-
Please register or login to post a comment