95.HarmonyOS NEXT 图片约束处理教程:深入理解Constrain
2025-03-16 23:35:45
143次阅读
0个评论
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦!
HarmonyOS NEXT 图片约束处理教程:深入理解Constrain
1. 图片约束基础
1.1 核心概念
概念 | 说明 | 应用场景 |
---|---|---|
图片适配类型 | 定义图片如何适应容器 | 图片展示方式 |
偏移约束 | 限制图片移动范围 | 拖拽和缩放 |
边界检测 | 判断是否超出显示范围 | 图片浏览 |
1.2 图片适配类型定义
export enum ImageFitType {
TYPE_WIDTH = 'width',
TYPE_HEIGHT = 'height',
TYPE_DEFAULT = 'default'
}
2. 偏移计算实现
2.1 最大偏移量计算
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;
}
2.2 偏移约束实现
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);
}
3. 图片切换判断
3.1 切换条件判断
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;
return deviation > switchThreshold;
}
3.2 参数说明
参数 | 说明 | 用途 |
---|---|---|
offset | 当前偏移量 | 记录当前位置 |
winSize | 窗口大小 | 确定显示范围 |
imageSize | 图片大小 | 计算实际尺寸 |
scale | 缩放比例 | 处理缩放效果 |
TogglePercent | 切换阈值 | 控制切换灵敏度 |
4. 图片尺寸处理
4.1 尺寸获取函数
export function getImgSize(
imageSize: image.Size,
rotate: number,
dimensionWH: ImageFitType.TYPE_WIDTH | ImageFitType.TYPE_HEIGHT
): number {
const isStandardRotation = [90, 270].includes(Math.abs(rotate % 360));
const Key = isStandardRotation ?
(dimensionWH == ImageFitType.TYPE_WIDTH ?
ImageFitType.TYPE_HEIGHT :
ImageFitType.TYPE_WIDTH) :
dimensionWH;
return imageSize[Key];
}
4.2 旋转处理
- 标准旋转判断
const isStandardRotation = [90, 270].includes(Math.abs(rotate % 360));
- 维度切换
const Key = isStandardRotation ?
(dimensionWH == ImageFitType.TYPE_WIDTH ?
ImageFitType.TYPE_HEIGHT :
ImageFitType.TYPE_WIDTH) :
dimensionWH;
5. 约束动画实现
5.1 约束和动画函数
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
);
// 获取当前偏移量
let currentOffset = info.imageOffsetInfo[
`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_SIZE[info.dimensionWH],
IMG_SIZE,
info.scaleValue
);
// 处理偏移量变化
if (CLAMPED_OFFSET !== currentOffset) {
let updateFn = () => {
info.imageOffsetInfo[
`current${info.dimensionWH == ImageFitType.TYPE_WIDTH ? 'X' : 'Y'}`
] = CLAMPED_OFFSET;
info.imageOffsetInfo.stash();
};
runWithAnimation(updateFn);
// 检查是否需要切换图片
if (isToggle(
currentOffset,
WIN_SIZE[info.dimensionWH],
IMG_SIZE,
info.scaleValue,
info.TogglePercent
)) {
const BOL = currentOffset >= 0;
return [BOL, !BOL];
}
}
return [false, false];
}
5.2 使用示例
// 处理图片约束和动画
const [leftExceeded, rightExceeded] = constrainOffsetAndAnimation({
dimensionWH: ImageFitType.TYPE_WIDTH,
imageDefaultSize: imageSize,
imageOffsetInfo: offsetModel,
scaleValue: scale,
rotate: rotation,
TogglePercent: 0.2,
imageListOffset: listOffset,
listDirection: Axis.Horizontal
});
// 根据结果处理图片切换
if (leftExceeded) {
// 切换到上一张
switchToPrevious();
} else if (rightExceeded) {
// 切换到下一张
switchToNext();
}
6. 最佳实践
6.1 性能优化
- 缓存计算结果
const maxOffset = getMaxAllowedOffset(winSize, imageSize, scale);
// 多次使用maxOffset而不是重复计算
- 避免频繁更新
// 使用防抖处理频繁的约束计算
const debouncedConstrain = debounce((info) => {
constrainOffsetAndAnimation(info);
}, 16);
6.2 错误处理
function safeConstrainOffset(info: ConstrainOffsetAndAnimationType) {
try {
return constrainOffsetAndAnimation(info);
} catch (error) {
console.error('Constrain calculation failed:', error);
return [false, false];
}
}
通过合理使用图片约束处理,可以实现流畅的图片浏览体验。在实际开发中,要注意性能优化和边界情况处理,确保图片操作的准确性和流畅性。
00
- 0回答
- 3粉丝
- 0关注
相关话题
- 94.HarmonyOS NEXT动画系统实现教程:深入理解FuncUtils
- 93.HarmonyOS NEXT窗口管理基础教程:深入理解WindowSizeManager
- 「Mac玩转仓颉内测版23」基础篇3 - 深入理解整数类型
- 60.Harmonyos NEXT 图片预览组件之边界处理与图片切换
- 63.Harmonyos NEXT 图片预览组件之手势处理实现
- 64.Harmonyos NEXT 图片预览组件之手势处理实现(二)
- 65.Harmonyos NEXT 图片预览组件之手势处理实现(三)
- 【HarmonyOS Next】图片选择方案
- 215.HarmonyOS NEXT系列教程之 CircleClass基础类与圆形效果实现原理解析
- 206.HarmonyOS NEXT系列教程之 TabsConcaveCircle组件交互处理与事件响应
- 192.HarmonyOS NEXT系列教程之图案锁事件处理机制详解
- 216.HarmonyOS NEXT系列教程之 TabBar凸起效果与图片偏移实现解析
- 193.HarmonyOS NEXT系列教程之图案锁错误处理机制详解
- 202.HarmonyOS NEXT系列教程之图案锁错误处理机制详解
- 鸿蒙特效教程09-深入学习animateTo动画