62.Harmonyos NEXT 图片预览组件之工具类实现

embedded/2025/3/15 14:29:29/

温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦!

Harmonyos NEXT 图片预览组件之工具类实现

文章目录

  • Harmonyos NEXT 图片预览组件之工具类实现
    • 效果预览
    • 一、工具类概述
      • 1. 工具类的作用
      • 2. 工具类的设计原则
    • 二、Constrain - 约束工具
      • 1. 功能概述
      • 2. 核心枚举和接口
      • 3. 最大偏移量计算
      • 4. 偏移约束函数
      • 5. 切换判断函数
      • 6. 综合约束与动画处理
    • 三、FuncUtils - 功能工具
      • 1. 动画执行函数
      • 2. 旋转角度简化函数
    • 四、Managers - 窗口管理器
      • 1. 窗口尺寸管理器
    • 五、工具类在组件中的应用
      • 1. 约束工具在边界处理中的应用
      • 2. 动画工具在状态重置中的应用
      • 3. 窗口管理器在尺寸计算中的应用
    • 六、总结

效果预览

一、工具类概述

图片预览组件中的工具类是支撑组件功能实现的重要基础设施,它们提供了约束计算、动画效果、窗口管理等核心功能。本文将详细介绍图片预览组件中的三个核心工具类:Constrain、FuncUtils和Managers。

1. 工具类的作用

在图片预览组件中,工具类主要承担以下职责:

  1. 约束计算:确保图片在缩放和移动过程中不会超出合理范围
  2. 动画处理:提供平滑的动画效果,提升用户体验
  3. 窗口管理:提供窗口尺寸信息,用于计算图片的适配大小
  4. 旋转计算:提供旋转角度的计算和简化功能

2. 工具类的设计原则

设计原则说明实现方式
功能聚焦每个工具类专注于特定的功能领域按功能划分为不同的工具类
无状态设计工具类方法不依赖于内部状态使用纯函数实现核心功能
参数明确明确定义参数类型和返回值使用TypeScript类型系统
复用性高工具类方法可在多处复用提供通用的功能接口

二、Constrain - 约束工具

1. 功能概述

Constrain工具类主要负责图片的边界约束和切换判断,确保图片在交互过程中的合理显示。

2. 核心枚举和接口

// 图片适配类型枚举
export enum ImageFitType {TYPE_WIDTH = 'width',TYPE_HEIGHT = 'height',TYPE_DEFAULT = 'default'
}// 约束偏移计算接口
export interface ConstrainOffsetAndAnimationType {// 此次计算的方向 宽或者高dimensionWH: ImageFitType,// 此次图片的默认尺寸imageDefaultSize: image.Size,// 此次图片相对应的偏移信息imageOffsetInfo: OffsetModel,// 此次图片的放大尺寸scaleValue: number,// 当前图片的旋转角度rotate: number,// 当超出限制多少时去判断,取值:0 ~ 1TogglePercent: number,// List 偏移量imageListOffset: number,// 主轴方向listDirection: Axis
}

3. 最大偏移量计算

// 获取最大偏移量
export function getMaxAllowedOffset(winSize: number, imageSize: number, scale: number) {const maxNum = Math.max(imageSize * scale, winSize);const minNum = Math.min(imageSize * scale, winSize);return (maxNum - minNum) / 2;
}

这个函数计算图片在特定方向上可以移动的最大距离。计算逻辑如下:

  1. 当图片尺寸大于窗口尺寸时(imageSize * scale > winSize):

    • maxNum = imageSize * scale
    • minNum = winSize
    • 最大偏移量 = (imageSize * scale - winSize) / 2
  2. 当图片尺寸小于窗口尺寸时(imageSize * scale < winSize):

    • maxNum = winSize
    • minNum = imageSize * scale
    • 最大偏移量 = (winSize - imageSize * scale) / 2

4. 偏移约束函数

function constrainOffset(offset: number, winSize: number, imageSize: number, scale: number): number {let maxAllowedOffset = getMaxAllowedOffset(winSize, imageSize, scale);return Math.min(Math.max(offset, -maxAllowedOffset), maxAllowedOffset);
}

这个函数确保图片的偏移量不会超出允许的范围,通过Math.min和Math.max函数将偏移量限制在[-maxAllowedOffset, maxAllowedOffset]区间内。

5. 切换判断函数

function isToggle(offset: number, winSize: number, imageSize: number, scale: number, TogglePercent: number): boolean {let maxAllowedOffset = getMaxAllowedOffset(winSize, imageSize, scale);const deviation = Math.abs(offset) - maxAllowedOffset;const switchThreshold = winSize * TogglePercent;if (deviation > switchThreshold) {return true}return false
}

这个函数判断是否需要切换图片,通过计算当前偏移量与最大允许偏移量的差值,并与切换阈值(窗口尺寸 * TogglePercent)进行比较。当差值大于阈值时,触发图片切换。

6. 综合约束与动画处理

export function constrainOffsetAndAnimation(info: ConstrainOffsetAndAnimationType): [boolean, boolean] {if (info.dimensionWH === ImageFitType.TYPE_DEFAULT) {return [false, false]}const WIN_SIZE = windowSizeManager.get();const IMG_SIZE = getImgSize(info.imageDefaultSize, info.rotate, info.dimensionWH);const WIN_AXIS_SIZE = WIN_SIZE[info.dimensionWH];let currentOffset = (info.imageOffsetInfo as object)[`last${info.dimensionWH === ImageFitType.TYPE_WIDTH ? 'X' : 'Y'}`];// 计算最后的图片偏移量if (info.dimensionWH === (info.listDirection === Axis.Horizontal ? ImageFitType.TYPE_WIDTH : ImageFitType.TYPE_HEIGHT)) {currentOffset += info.imageListOffset;}const CLAMPED_OFFSET = constrainOffset(currentOffset, WIN_AXIS_SIZE, IMG_SIZE, info.scaleValue);// 如果偏移量发生了变化(即需要修正)if (CLAMPED_OFFSET !== currentOffset) {let updateFn = () => {(info.imageOffsetInfo as object)[`current${info.dimensionWH == ImageFitType.TYPE_WIDTH ? 'X' : 'Y'}`] = CLAMPED_OFFSET;info.imageOffsetInfo.stash();}runWithAnimation(updateFn);// 判断是否需要切换图片let bol = isToggle(currentOffset, WIN_AXIS_SIZE, IMG_SIZE, info.scaleValue, info.TogglePercent);if (bol) {const BOL = currentOffset >= 0 ? true : falsereturn [BOL, !BOL]}}return [false, false]
}

这个函数是边界处理的核心,它综合了偏移约束和动画处理,并返回是否需要切换图片的判断结果。返回值是一个布尔数组:

  • 如果dimensionWH是"width",返回值为[左边超出,右边超出]
  • 如果dimensionWH是"height",返回值为[上边超出,下边超出]

三、FuncUtils - 功能工具

1. 动画执行函数

export function runWithAnimation(fn: Function, duration: number = 300) {animateTo({duration: duration,curve: Curve.Ease,iterations: 1,playMode: PlayMode.Normal,}, fn);
}

这个函数为其他函数执行添加动画效果,使用animateTo API实现平滑的动画过渡。参数说明:

  • fn:需要执行的函数
  • duration:动画持续时间,默认300毫秒

2. 旋转角度简化函数

export function simplestRotationQuarter(angle: number): number {// 将角度转换为0-360范围内let normalizedAngle = angle % 360;if (normalizedAngle < 0) {normalizedAngle += 360;}// 计算最接近的90度倍数let quarter = Math.round(normalizedAngle / 90) * 90;return quarter;
}

这个函数将任意角度转换为最接近的90度倍数(0°、90°、180°、270°),用于图片旋转时的角度对齐。实现步骤:

  1. 将角度归一化到0-360度范围内
  2. 计算最接近的90度倍数

四、Managers - 窗口管理器

1. 窗口尺寸管理器

class WindowSizeManager {private size: window.Size = { width: 0, height: 0 };constructor() {// 初始化窗口尺寸this.size = { width: window.getLastWindowSize().width, height: window.getLastWindowSize().height };// 监听窗口尺寸变化window.on('sizeChange', (size: window.Size) => {this.size = size;});}get(): window.Size {return this.size;}
}// 创建单例实例
export const windowSizeManager = new WindowSizeManager();

窗口尺寸管理器是一个单例类,用于获取和管理窗口尺寸信息。它的主要功能包括:

  1. 初始化时获取当前窗口尺寸
  2. 监听窗口尺寸变化事件,实时更新尺寸信息
  3. 提供get()方法获取当前窗口尺寸

五、工具类在组件中的应用

1. 约束工具在边界处理中的应用

evaluateBound(): void {const xBol = constrainOffsetAndAnimation({dimensionWH: ImageFitType.TYPE_WIDTH,imageDefaultSize: this.imageDefaultSize,imageOffsetInfo: this.imageOffsetInfo,scaleValue: this.imageScaleInfo.scaleValue,rotate: this.imageRotateInfo.lastRotate,TogglePercent: this.TogglePercent,imageListOffset: this.imageListOffset,listDirection: this.listDirection});// 根据返回结果决定是否切换图片if (this.listDirection === Axis.Horizontal) {if (xBol[0] || xBol[1]) {if (xBol[0]) {this.setListToIndex(this.imageIndex - 1);}if (xBol[1]) {this.setListToIndex(this.imageIndex + 1);}}}
}

2. 动画工具在状态重置中的应用

resetCurrentImageInfo(): void {runWithAnimation(() => {this.imageScaleInfo.reset();this.imageOffsetInfo.reset();this.imageRotateInfo.reset();this.matrix = matrix4.identity().copy();}, this.restImageAnimation);
}

3. 窗口管理器在尺寸计算中的应用

initCurrentImageInfo(event: ImageLoadResult): void {let imageW = event.width;let imageH = event.height;let windowSize = windowSizeManager.get();// 图片宽高比this.imageWHRatio = imageW / imageH;// 图片默认大小this.imageDefaultSize = this.calcImageDefaultSize(this.imageWHRatio, windowSize);
}

六、总结

图片预览组件中的工具类是组件功能实现的重要支撑,它们通过提供约束计算、动画效果、窗口管理等核心功能,确保了组件的高性能和良好用户体验。

工具类的设计遵循了功能聚焦、无状态设计、参数明确和复用性高的原则,使得代码结构清晰、易于维护。通过合理的工具类抽象,图片预览组件实现了复杂交互逻辑的模块化和可复用性。

在实际应用中,这些工具类不仅服务于图片预览组件,还可以在其他需要类似功能的组件中复用,提高了代码的复用率和开发效率。


http://www.ppmy.cn/embedded/172783.html

相关文章

使用PHP进行自动化测试:工具与策略的全面分析

使用PHP进行自动化测试&#xff1a;工具与策略的全面分析 引言 随着软件开发的复杂性不断增加&#xff0c;自动化测试已成为确保软件质量的关键环节。PHP作为一种广泛使用的服务器端脚本语言&#xff0c;拥有丰富的生态系统和工具支持&#xff0c;使其成为自动化测试的理想选…

【综述】An Introduction to Vision-Language Modeling【一】

介绍 发表在预印本上的综述&#xff0c;长达76页&#xff0c;其中正文46页。 来自Meta 在Meta工作期间完成 ‡蒙特利尔大学, Mila ♡麦吉尔大学, Mila †多伦多大学 ♠卡内基梅隆大学 ♣麻省理工学院 ∧纽约大学 △加州大学伯克利分校 ▽马里兰大学 ♢阿卜杜拉国王科技大学 •…

计算机网络OSI七层模型

目录 物理层&#xff08;Physical Layer&#xff09; 数据链路层&#xff08;Data Link Layer&#xff09; 网络层&#xff08;Network Layer&#xff09; 传输层&#xff08;Transport Layer&#xff09; 会话层&#xff08;Session Layer&#xff09; 表示层&#xff0…

《SpringBoot+MyBatis-Plus极速开发:10倍效率提升的CRUD模板》

一、为什么选择SpringBootMyBatis-Plus&#xff1f; [[2]] MyBatis-Plus&#xff08;简称MP&#xff09;是MyBatis的增强工具&#xff0c;其设计目标是简化开发、提高效率。通过以下特性实现效率提升&#xff1a; 零XML配置&#xff1a;通过注解和Java配置实现数据库操作自动…

路由器配置命令

路由器配置命令 小明啊&#xff0c;你不是学计算机的嘛&#xff0c;叔叔家的路由器坏了&#xff0c;可以过来帮叔叔看看吗 命令可以用缩写&#xff0c;造就一堆容易造成歧义的缩写&#xff0c;比如add是address的缩写&#xff0c;sh是shutdown的缩写。 视图模式介绍 普通视…

计算机操作系统(一) 什么是操作系统

计算机操作系统&#xff08;一&#xff09; 什么是操作系统 前言一、什么是操作系统二、操作系统的作用三、推动操作系统发展的主要动力总结&#xff08;核心概念速记&#xff09;&#xff1a; 前言 当你打开电脑、点击应用、播放音乐时&#xff0c;是谁在背后默默协调这一切&…

html-to-image的使用及图片变形和无图问题修复

html-to-image的使用及图片变形和无图问题修复 最近迭代的时候因为新增了一个需求&#xff0c;需要前端提供素材及样式给后端&#xff0c;后端同步渲染&#xff0c;但是因为部分样式问题后端无法实现所以决定前端将页面生成图片然后传递给后端使用&#xff0c;本文记录一下使用…

注意力机制,层归一化,RBA。KAN-ODE,小波KAN

目录 attention is all you need 翻译 多头注意力 8.6 Multi-head Self Attention 模型 模型架构 encoder安定 decode 注意力机制 位置编码 自注意力机制的优势 实验结果 结论 代码 Transformer 架构 代码实现思路 总结 编码器、解码器和位置编码的摆放顺序&…