UNPKG

gtht-miniapp-sdk

Version:

gtht-miniapp-sdk 是一套基于 Uniapp + Vue3 框架开发的兼容多端的 UI 组件库

154 lines (153 loc) 5.78 kB
/** * 根据最后位置计算 page 滚动到顶部的值。 * * 也可计算水平方向的滚动值。 * * page * ╱ * ╭───────────────╮ viewport * ╭─│─ ─ ─ ─ ─ ─ ─ ─│─╮ ╱ * │ │ ╭───────────╮ │ │ * │ │ │ element │ │ │ * │ │ ╰───────────╯ │ │ * ╰─│─ ─ ─ ─ ─ ─ ─ ─│─╯ * │ │ * │ │ * ╰───────────────╯ * * @param {number} viewportHeight viewport 高度 * @param {number} viewportScrollTop viewport 垂直滚动值 * @param {number} elementHeight element 高度 * @param {number} elementOffsetTop element 距离页面顶部距离 * @param {string} options.position element 在 viewport 中的位置,可选:'start' | 'center' | 'end' | 'nearest' * @param {number} options.startOffset element 距离视窗顶部的偏移量 * @param {number} options.endOffset element 距离视窗底部的偏移量 * @return {number} viewport 新的垂直滚动值 */ export function getScrollIntoViewValue(viewportHeight, viewportScrollTop, elementHeight, elementOffsetTop, options = {}) { const { startOffset = 0, endOffset = 0 } = options; let position = options.position || 'nearest'; const elementToViewportTopOffset = elementOffsetTop - viewportScrollTop - startOffset; const elementToViewportBottomOffset = elementOffsetTop + elementHeight - viewportScrollTop - viewportHeight + endOffset; if (position === 'nearest') { if (elementToViewportTopOffset >= 0 && elementToViewportBottomOffset <= 0) { return viewportScrollTop; } else { 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; } /** * 匹配元素列表中第一个位于滚动盒子可视区域的元素 * * @param {array} rects NodeRect 类型数组 * @param {function} callback 匹配成功时调用,会接收匹配的元素的下标 * @param {number} options.offset 偏移量 * @param {number} options.errorValue 容错值 */ export async function matchScrollVisible(rects, callback, options = {}) { const { offset: optionOffset = 0, errorValue = 3 } = options; const offset = optionOffset + errorValue; const convertedRect = rects.map((rect, i) => { return { top: rect.top, bottom: i < rects.length - 1 ? rects[i + 1].top : 0, }; }); for (let i = 0, l = convertedRect.length; i < l; i++) { const rect = convertedRect[i]; if (i === 0 && rect.top > offset) { return callback(0); } if (rect.top <= offset && rect.bottom > offset) { return callback(i); } if (i === l - 1 && rect.bottom <= offset) { return callback(i); } } } /** * 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 */ export function getAspectFillSize(origWidth, origHeight, containerWidth, containerHeight) { let width = 0; let height = 0; if (origWidth > 0 && origHeight > 0) { if (origWidth / origHeight > containerWidth / containerHeight) { height = containerHeight; width = (origWidth / origHeight) * containerHeight; } else { width = containerWidth; height = (origHeight / origWidth) * containerWidth; } } return [width, height]; } /** * 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。 */ export function getAspectFitSize(origWidth, origHeight, containerWidth, containerHeight) { let width = 0; let height = 0; if (origWidth > 0 && origHeight > 0) { if (origWidth / origHeight > containerWidth / containerHeight) { width = containerWidth; height = (origHeight / origWidth) * containerWidth; } else { height = containerHeight; width = (origWidth / origHeight) * containerHeight; } } return [width, height]; } /** * 获取两点间的距离 */ export function getTwoPointsDistance(p1, p2) { return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)); } /** * @description: 根据原始坐标尺寸和缩放后的坐标尺寸算出转换的原点 * @param {Rect} rect * @param {Rect} scaleRect * @return {[number, number]} */ export function getTransformOrigin(rect, scaleRect) { const ratio = scaleRect.width / rect.width; const originX = (rect.x + rect.width / 2 - scaleRect.x - scaleRect.width / 2) / (ratio - 1) + rect.width / 2; const originY = (rect.y + rect.height / 2 - scaleRect.y - scaleRect.height / 2) / (ratio - 1) + rect.height / 2; return [originX, originY]; }