HarmonyOS鸿蒙Next中结合Navigation的共享元素转场的demo的计算问题
HarmonyOS鸿蒙Next中结合Navigation的共享元素转场的demo的计算问题 首先,文档链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-shared-element-transition#%E7%BB%93%E5%90%88navigation%E4%BD%BF%E7%94%A8
疑问代码:
// 首先计算卡片的宽高与窗口宽高的比例
let widthScaleRatio = cardItemInfo_px.width / WindowUtils.windowWidth_px;
let heightScaleRatio = cardItemInfo_px.height / WindowUtils.windowHeight_px;
let isUseWidthScale = widthScaleRatio > heightScaleRatio;
let initScale: number = isUseWidthScale ? widthScaleRatio : heightScaleRatio;
let initTranslateX: number = 0;
let initTranslateY: number = 0;
let initClipWidth: Dimension = 0;
let initClipHeight: Dimension = 0;
// 使得PageTwo卡片向上扩到状态栏
let initPositionValue: number = -(WindowUtils.topAvoidAreaHeight_px + extraTranslateValue);
if (isUseWidthScale) {
initTranslateX = px2vp(cardItemInfo_px.left - (WindowUtils.windowWidth_px - cardItemInfo_px.width) / 2);
initClipWidth = '100%';
initClipHeight = px2vp((cardItemInfo_px.height) / initScale);
initTranslateY = px2vp(cardItemInfo_px.top - ((vp2px(initClipHeight) - vp2px(initClipHeight) * initScale) / 2));
} else {
initTranslateY = px2vp(cardItemInfo_px.top - (WindowUtils.windowHeight_px - cardItemInfo_px.height) / 2);
initClipHeight = '100%';
initClipWidth = px2vp((cardItemInfo_px.width) / initScale);
initTranslateX = px2vp(cardItemInfo_px.left - (WindowUtils.windowWidth_px / 2 - cardItemInfo_px.width / 2));
}
主要疑问在:initTranslateY = px2vp(cardItemInfo_px.top - ((vp2px(initClipHeight) - vp2px(initClipHeight) * initScale) / 2));
首先 cardItemInfo_px.top
是 PageOne
元素的 top
值,initClipHeight
是 PageTwo
动画后的元素高度,由于等比缩放,所以 vp2px(initClipHeight) * initScale
这部分的值应该是 PageOne
中元素的高度(后续日志已经证明)
所以 ((vp2px(initClipHeight) - vp2px(initClipHeight) * initScale)
这部分是 PageTwo
元素与 PageOne
元素的高度差
PageTwo
渲染时要做动画,所以 PageTwo
元素初始的位置应该与 PageOne
元素的位置相同,所以 PageTwo
元素的 initTranslateY
不应该直接是 PageOne
中元素距离顶部的距离吗(因为 PageTwo
元素的 Y
是 0
)?为什么要做高度差除以 2
?
更多关于HarmonyOS鸿蒙Next中结合Navigation的共享元素转场的demo的计算问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你好,问题内部处理中,请耐心等待。
更多关于HarmonyOS鸿蒙Next中结合Navigation的共享元素转场的demo的计算问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
嗷,我懂了,initTranslateY = cardItemInfo_px.top
时 PageTwo
和 PageOne
的元素的 Y 轴是一样的,当这个值再向上也就是减去高度差的一半,就让两个元素的中心点在同一个位置,然后 PageTwo
中的元素设置 scale 值使新元素与老元素在相同的位置上开始做动画,形成一镜到底的效果
你可以尝试下,将initTranslateY
的公式改成下方你说的,直接设置成cardItemInfo
的高度。
initTranslateY = px2vp(cardItemInfo_px.top);
你测试下会发现,图片转场动画变得就不会那么流程,因为直接设置高度,没有考虑到图片变大后,实际高度就会变小的情况。
我知道我说的这个不对,但是我不知道这个为什么不对,为什么 Y轴的偏移位置等于 原本上边距 - 高度差的一半,我不知道这个公式怎么推理出来的,所以我不理解,
在HarmonyOS鸿蒙Next中,结合Navigation实现共享元素转场时,计算问题主要涉及动画的起始和结束位置。通过SharedElementTransition
组件,可以定义共享元素的动画效果。关键步骤包括:
- 获取元素位置:使用
getBoundingClientRect
获取共享元素在源页面和目标页面的位置信息。 - 计算偏移量:根据获取的位置信息,计算元素在转场过程中的偏移量。
- 应用动画:将计算出的偏移量应用到
SharedElementTransition
的动画属性中,实现平滑转场。
示例代码:
const startRect = startElement.getBoundingClientRect();
const endRect = endElement.getBoundingClientRect();
const offsetX = endRect.left - startRect.left;
const offsetY = endRect.top - startRect.top;
SharedElementTransition({
startElement,
endElement,
duration: 300,
curve: Curve.EaseInOut,
translate: { x: offsetX, y: offsetY }
});
通过精确计算,确保共享元素在转场过程中的位置和大小变化自然流畅。