template/packages-user/client-base/src/layout/layout.ts
unanmed 0b93426d47 refactor(04-11): 渲染端结构性移植——通用渲染资产下沉 @user/client-base(D-58..D-68)
- MOVE:39 个文件由 client-modules/src/render/ 移入 client-base/src/{components,elements,map,layout}/,删除原件
- D-58:新建 client-base/src/shared/(10 常量纯摘取)+ 被移 map 文件 shared 说明符改指 4 处
- D-63:client-base/src/index.ts 新增 5 条桶导出;14 个实现层消费者改指 @user/client-base
- D-66:client-base/package.json 新增 5 条 workspace:* 依赖 + 根 pnpm i(lockfile importer 同步)
- D-59 / D-60 / D-68:10 处架构耦合以带原因 // @ts-expect-error 暂记,不反向引用、不解耦
- D-62:命名一律不变;D-64 ?raw 不处理;D-65 legacy 一律不管
2026-09-24 17:14:43 +08:00

87 lines
2.5 KiB
TypeScript

import { ElementLocator } from '@motajs/render';
export interface IGridLayoutData {
/** 有多少列 */
readonly cols: number;
/** 有多少行 */
readonly rows: number;
/** 去除余留部分后的宽度 */
readonly width: number;
/** 去除预留部分后的高度 */
readonly height: number;
/** 元素总数量 */
readonly count: number;
/** 每个元素的定位,按照从左到右,从左上下的顺序排列,包含所有六个元素 */
readonly locs: readonly ElementLocator[];
}
/**
* 网格布局
* @param width 总宽度
* @param height 总高度
* @param itemWidth 每个元素的宽度
* @param itemHeight 每个元素的高度
* @param intervalX 元素的横向间隔
* @param intervalY 元素的纵向间隔,不填时等于横向间隔
* @returns 网格布局信息
*/
export function adjustGrid(
width: number,
height: number,
itemWidth: number,
itemHeight: number,
intervalX: number,
intervalY: number = intervalX
): IGridLayoutData {
const cols = Math.floor((width + intervalX) / (itemWidth + intervalX));
const rows = Math.floor((height + intervalY) / (itemHeight + intervalY));
const rawWidth = (itemWidth + intervalX) * cols - intervalX;
const rawHeight = (itemHeight + intervalY) * rows - intervalY;
const locs: ElementLocator[] = [];
for (let y = 0; y < rows; y++) {
const iy = (intervalY + itemHeight) * y;
for (let x = 0; x < cols; x++) {
const ix = (intervalX + itemWidth) * x;
locs.push([ix, iy, itemWidth, itemHeight, 0, 0]);
}
}
return {
cols,
rows,
count: cols * rows,
width: rawWidth,
height: rawHeight,
locs
};
}
/**
* 适配为覆盖模式,类似于 `object-fit: cover`
* @param itemWidth 元素宽度
* @param itemHeight 元素高度
* @param targetWidth 目标宽度
* @param targetHeight 目标高度
* @returns 适配为覆盖模式后元素的宽高
*/
export function adjustCover(
itemWidth: number,
itemHeight: number,
targetWidth: number,
targetHeight: number
): Readonly<LocArr> {
const aspect = itemWidth / itemHeight;
const canvasAspect = targetWidth / targetHeight;
if (canvasAspect > aspect) {
const width = targetWidth;
const height = width / aspect;
return [width, height];
} else {
const height = targetHeight;
const width = height * aspect;
return [width, height];
}
}