SmartParks_visitore/uni_modules/lime-shared/getRect/index.ts

138 lines
3.9 KiB
TypeScript
Raw Permalink Normal View History

2025-08-21 11:23:54 +08:00
// @ts-nocheck
// #ifdef UNI-APP-X && APP
// export * from './uvue.uts'
export { getRect, getAllRect } from './uvue.uts'
// #endif
// #ifndef UNI-APP-X && APP
// export * from './vue.ts'
export { getRect, getAllRect } from './vue.ts'
// #endif
/**
*
*/
export function getViewportScrollInfo() : Promise<any> {
return new Promise(resolve => {
uni.createSelectorQuery()
.selectViewport()
.scrollOffset((res) => {
resolve(res);
}).exec();
})
}
/**
```
page
viewport
element
```
#
- viewportHeight: viewport
- viewportScrollTop: viewport
- elementHeight: element
- elementOffsetTop: element
#
- position: element (start, center, end, nearest)
- startOffset: element
- endOffset: element
#
- viewportScrollTop: viewport
*/
export type ScrollIntoViewOptions = {
/** 元素顶部需要保留的缓冲距离(默认 0 */
startOffset ?: number;
/** 元素底部需要保留的缓冲距离(默认 0 */
endOffset ?: number;
/** 滚动对齐方式start/center/end/nearest默认 nearest */
position ?: 'start' | 'center' | 'end' | 'nearest';
}
/**
*
* @param viewportHeight
* @param viewportScrollTop
* @param elementHeight
* @param elementOffsetTop
* @param options
* @returns
*
* @example
* // 示例:将元素滚动到视口顶部对齐
* const scrollTop = getScrollIntoViewValue(
* 500, // 视口高度
* 200, // 当前滚动位置
* 100, // 元素高度
* 300, // 元素偏移量
* { position: 'start' }
* );
*/
export function getScrollIntoViewValue(
viewportHeight : number,
viewportScrollTop : number,
elementHeight : number,
elementOffsetTop : number,
options : ScrollIntoViewOptions = {}
) : number {
let { startOffset = 0, endOffset = 0, position = 'nearest'} = options;
// 计算元素相对于视口的上下偏移量
const elementToViewportTopOffset = elementOffsetTop - viewportScrollTop - startOffset;
const elementToViewportBottomOffset =
elementOffsetTop +
elementHeight -
viewportScrollTop -
viewportHeight +
endOffset;
// 处理 nearest 模式,自动选择最近边缘
if (position == 'nearest') {
if (elementToViewportTopOffset >= 0 && elementToViewportBottomOffset <= 0) {
return viewportScrollTop;
}
position =
Math.abs(elementToViewportTopOffset) > Math.abs(elementToViewportBottomOffset)
? 'end'
: 'start';
}
// 根据不同的对齐位置计算目标滚动位置
let nextScrollTop = 0;
switch (position) {
case 'start':
// 顶部对齐:元素顶部对齐视口顶部(考虑顶部缓冲)
nextScrollTop = elementOffsetTop - startOffset;
break;
case 'center':
// 居中对齐:元素中心对齐视口中心(考虑上下缓冲)
nextScrollTop =
elementOffsetTop -
(viewportHeight - elementHeight - endOffset - startOffset) / 2 +
startOffset;
break;
case 'end':
// 底部对齐:元素底部对齐视口底部(考虑底部缓冲)
nextScrollTop =
elementOffsetTop + elementHeight - viewportHeight + endOffset;
break;
}
return nextScrollTop;
}