温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦!
手势系统采用分层处理架构:
┌───────────────┐
│ 基础手势识别层 │(Tap/Pan/Rotation/Pinch)
├───────────────┤
│ 手势协调层 │(处理手势冲突与优先级)
├───────────────┤
│ 业务逻辑层 │(将手势转换为组件操作)
└───────────────┘
.gesture(
GestureGroup(
GestureMode.Parallel, // 并行处理手势
TapGesture(),
PanGesture()
)
)
.gesture( // 另一组独立手势
GestureGroup(
RotationGesture(),
PinchGesture()
)
)
处理原则:
TapGesture({ count: 2 })
.onAction(() => {
if (当前是放大状态) {
// 复位动画
animateTo({
duration: 300
}, () => {
this.imageScaleInfo.reset()
this.matrix = /* 重置矩阵 */
})
} else {
// 放大到适配尺寸
const ratio = this.calcFitScaleRatio(...)
animateTo({
curve: Curve.EaseOut
}, () => {
this.imageScaleInfo.scaleValue = ratio
this.matrix = /* 更新矩阵 */
})
}
})
动画曲线说明:
曲线类型 | 效果描述 |
---|---|
Linear | 匀速运动 |
EaseIn | 缓慢开始,加速结束 |
EaseOut | 快速开始,缓慢结束 |
Spring | 弹性效果 |
PanGesture({ fingers: 1 })
.onActionUpdate((event) => {
// 获取偏移量
const dx = event.offsetX - this.lastX
const dy = event.offsetY - this.lastY
// 更新矩阵
this.matrix = matrix4.translate({
x: dx,
y: dy,
z: 0
})
// 记录最后位置
this.lastX = event.offsetX
this.lastY = event.offsetY
})
边界处理算法:
function getMaxAllowedOffset(windowSize, imageSize, scale) {
return Math.max(
0,
(imageSize * scale - windowSize) / 2
)
}
RotationGesture()
.onActionUpdate((event) => {
// 计算旋转角度增量
const deltaAngle = event.angle - this.lastAngle
// 更新矩阵
this.matrix = matrix4.rotate({
z: 1,
angle: deltaAngle
})
// 记录角度
this.totalRotation += deltaAngle
this.lastAngle = event.angle
})
角度规范化处理:
function normalizeAngle(angle: number): number {
return ((angle % 360) + 360) % 360
}
PinchGesture()
.onActionUpdate((event) => {
// 计算缩放比例
const newScale = this.lastScale * event.scale
// 应用缩放限制
this.imageScaleInfo.scaleValue = Math.max(
MIN_SCALE,
Math.min(newScale, MAX_SCALE)
)
// 更新矩阵
this.matrix = matrix4.scale({
x: this.scale,
y: this.scale
})
})
缩放中心计算:
双指中点坐标计算:
centerX = (finger1.x + finger2.x) / 2
centerY = (finger1.y + finger2.y) / 2
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 动画触发条件 │ → │ 属性插值计算 │ → │ 矩阵重新计算 │
└─────────────┘ └─────────────┘ └─────────────┘
const runWithAnimation = (fn: Function) => {
animateTo({
duration: 300,
curve: Curve.EaseInOut
}, () => {
fn()
this.updateMatrix()
})
}
动画参数说明:
interface AnimateParams {
duration: number // 动画时长(ms)
delay?: number // 延迟时间
curve?: Curve // 动画曲线
iterations?: number // 重复次数
playMode?: PlayMode // 播放模式
}
// 旋转+缩放复合动画
animateTo({
duration: 500
}, () => {
// 缩放操作
this.imageScaleInfo.scaleValue = 1.2
// 旋转操作
this.imageRotateInfo.angle += 90
// 位移操作
this.imageOffsetInfo.x += 50
// 统一更新矩阵
this.updateCompositeMatrix()
})
evaluateBound() {
// 计算有效滑动距离
const threshold = window.width * this.TogglePercent
if (Math.abs(offset) > threshold) {
// 触发图片切换
this.setListToIndex(targetIndex)
// 执行切换动画
this.playSwitchAnimation()
} else {
// 回弹动画
this.playBounceAnimation()
}
}
setCrossAxis(event) {
if (this.imageListOffset > this.moveMaxOffset) {
// 锁定交叉轴移动
this.isMoveCrossAxis = false
// 显示相邻图片提示
this.showNeighborPreview()
}
}
视觉反馈设计:
updateMatrix() {
// 使用矩阵合成代替逐项计算
this.matrix = matrix4.identity()
.scale(this.scale)
.rotate(this.rotation)
.translate(this.offset)
.copy()
}
优化前/后对比:
操作 | 优化前计算量 | 优化后计算量 |
---|---|---|
缩放+旋转 | 6次矩阵乘法 | 3次矩阵合成 |
PanGesture()
.onActionUpdate((event) => {
// 50ms节流处理
if (Date.now() - this.lastUpdate > 50) {
handleUpdate(event)
this.lastUpdate = Date.now()
}
})
aboutToDisappear() {
// 释放图片资源
this.imagePixelMap = undefined
// 重置矩阵
this.matrix = matrix4.identity()
}
// 在GestureEvent处理中添加调试绘制
Line({ width: 2 })
.points(points)
.marker(MarkerStyle.Circle)
.onTouch((event) => {
this.touchPoints.push(event.touches[0])
})
const debugCurve = (curve: Curve) => {
const points = []
for (let t = 0; t <= 1; t += 0.1) {
points.push(curve.interpolate(t))
}
drawCurveGraph(points)
}
Column() {
PerformanceMonitor({
metrics: ['fps', 'memory', 'gpu'],
interval: 1000
})
Text(`当前帧率:${this.fps}`)
Text(`内存占用:${this.memory}MB`)
}
知识点 | 实现要点 | 相关代码示例 |
---|---|---|
手势冲突处理 | 分组并行处理机制 | GestureGroup模式设置 |
矩阵变换优化 | 合成顺序与性能优化 | matrix4链式调用 |
动画插值计算 | 曲线函数与时长控制 | animateTo参数配置 |
边界条件处理 | 阈值判断与视觉反馈 | evaluateBound方法 |
性能优化 | 矩阵合成/事件节流/资源释放 | updateMatrix优化实现 |