mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-06-28 05:07:59 +08:00
feat: 存档自适应数量
This commit is contained in:
parent
98a0e13aee
commit
2d301cf0d0
@ -20,6 +20,8 @@ export interface PageProps extends DefaultProps {
|
||||
pages: number;
|
||||
/** 页码组件的定位 */
|
||||
loc: ElementLocator;
|
||||
/** 当前页码 */
|
||||
page?: number;
|
||||
/** 页码的字体 */
|
||||
font?: Font;
|
||||
/** 只有一页的时候,是否隐藏页码 */
|
||||
@ -28,6 +30,8 @@ export interface PageProps extends DefaultProps {
|
||||
|
||||
export type PageEmits = {
|
||||
pageChange: (page: number) => void;
|
||||
|
||||
'update:page': (page: number) => void;
|
||||
};
|
||||
|
||||
export interface PageExpose {
|
||||
@ -54,8 +58,8 @@ type PageSlots = SlotsType<{
|
||||
}>;
|
||||
|
||||
const pageProps = {
|
||||
props: ['pages', 'loc', 'font', 'hideIfSingle'],
|
||||
emits: ['pageChange']
|
||||
props: ['pages', 'loc', 'page', 'font', 'hideIfSingle'],
|
||||
emits: ['pageChange', 'update:page']
|
||||
} satisfies SetupComponentOptions<
|
||||
PageProps,
|
||||
PageEmits,
|
||||
@ -85,7 +89,7 @@ export const Page = defineComponent<
|
||||
keyof PageEmits,
|
||||
PageSlots
|
||||
>((props, { slots, expose, emit }) => {
|
||||
const nowPage = ref(0);
|
||||
const nowPage = ref(props.page ?? 0);
|
||||
|
||||
// 五个元素的位置
|
||||
const leftLoc = ref<ElementLocator>([]);
|
||||
@ -182,6 +186,7 @@ export const Page = defineComponent<
|
||||
if (nowPage.value !== target) {
|
||||
nowPage.value = target;
|
||||
emit('pageChange', target);
|
||||
emit('update:page', target);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -74,6 +74,6 @@ export const Thumbnail = defineComponent<ThumbnailProps>(props => {
|
||||
watch(props, update);
|
||||
|
||||
return () => (
|
||||
<sprite ref={spriteRef} loc={props.loc} render={drawThumbnail} />
|
||||
<sprite noanti ref={spriteRef} loc={props.loc} render={drawThumbnail} />
|
||||
);
|
||||
}, thumbnailProps);
|
||||
|
@ -7,22 +7,29 @@ import {
|
||||
SetupComponentOptions,
|
||||
UIComponentProps
|
||||
} from '@motajs/system-ui';
|
||||
import { defineComponent, ref, computed, onMounted } from 'vue';
|
||||
import {
|
||||
defineComponent,
|
||||
ref,
|
||||
computed,
|
||||
onMounted,
|
||||
shallowReactive
|
||||
} from 'vue';
|
||||
import { Page, PageExpose } from '../components';
|
||||
import { useKey } from '../use';
|
||||
import { MAP_WIDTH, MAP_HEIGHT } from '../shared';
|
||||
import { MAP_WIDTH } from '../shared';
|
||||
import { getSave, SaveData } from '../utils';
|
||||
import { Thumbnail } from '../components/thumbnail';
|
||||
import { adjustGrid, IGridLayoutData } from '../utils/layout';
|
||||
|
||||
export interface SaveProps extends UIComponentProps, DefaultProps {
|
||||
loc: ElementLocator;
|
||||
}
|
||||
|
||||
export interface SaveBtnProps extends DefaultProps {
|
||||
export interface SaveItemProps extends DefaultProps {
|
||||
loc: ElementLocator;
|
||||
index: number;
|
||||
isSelected: boolean;
|
||||
isDelete: boolean;
|
||||
selected: boolean;
|
||||
inDelete: boolean;
|
||||
data: SaveData | null;
|
||||
}
|
||||
|
||||
@ -35,26 +42,45 @@ export type SaveEmits = {
|
||||
exit: () => void;
|
||||
};
|
||||
|
||||
export type SaveBtnEmits = {
|
||||
/** 读取数据 */
|
||||
updateData: (isValid: boolean) => void;
|
||||
};
|
||||
|
||||
const saveProps = {
|
||||
props: ['loc', 'controller', 'instance'],
|
||||
emits: ['delete', 'emit', 'exit']
|
||||
} satisfies SetupComponentOptions<SaveProps, SaveEmits, keyof SaveEmits>;
|
||||
|
||||
const saveBtnProps = {
|
||||
props: ['loc', 'index', 'isSelected', 'isDelete', 'data']
|
||||
} satisfies SetupComponentOptions<SaveBtnProps>;
|
||||
props: ['loc', 'index', 'selected', 'inDelete', 'data']
|
||||
} satisfies SetupComponentOptions<SaveItemProps>;
|
||||
|
||||
export const SaveBtn = defineComponent<SaveBtnProps>(props => {
|
||||
const w = props.loc[2] ?? 200;
|
||||
export const SaveItem = defineComponent<SaveItemProps>(props => {
|
||||
const font = new Font('normal', 18);
|
||||
const statusFont = new Font('normal', 14);
|
||||
|
||||
const w = computed(() => props.loc[2] ?? 200);
|
||||
const lineWidth = computed(() => (props.selected ? 4 : 2));
|
||||
const imgLoc = computed<ElementLocator>(() => {
|
||||
const size = w.value - 4;
|
||||
return [2, 24, size, size];
|
||||
});
|
||||
|
||||
const name = computed(() => {
|
||||
return props.index === -1 ? '自动存档' : `存档${props.index}`;
|
||||
});
|
||||
const statusText = computed(() => {
|
||||
if (!props.data) return '';
|
||||
else {
|
||||
const hero = props.data.data.hero;
|
||||
return `${hero.hp}/${hero.atk}/${hero.def}`;
|
||||
}
|
||||
});
|
||||
|
||||
const strokeStyle = computed(() => {
|
||||
if (props.selected) return props.inDelete ? 'red' : 'gold';
|
||||
else return 'white';
|
||||
});
|
||||
|
||||
const floorId = computed(() => props.data?.data.floorId ?? 'empty');
|
||||
const mapBlocks = computed(() => {
|
||||
if (props.data === null || props.data === undefined) return void 0;
|
||||
if (!props.data) return [];
|
||||
else {
|
||||
const currData = props.data.data;
|
||||
const map = core.maps.loadMap(currData.maps, currData.floorId);
|
||||
@ -62,54 +88,42 @@ export const SaveBtn = defineComponent<SaveBtnProps>(props => {
|
||||
return map.blocks;
|
||||
}
|
||||
});
|
||||
const name = computed(() =>
|
||||
props.index === -1 ? '自动存档' : `存档${props.index + 1}`
|
||||
);
|
||||
const statusText = computed(() => {
|
||||
if (props.data === null || props.data === undefined) return '';
|
||||
else {
|
||||
const hero = props.data.data.hero;
|
||||
return `${hero.hp}/${hero.atk}/${hero.def}`;
|
||||
}
|
||||
});
|
||||
const strokeStyle = computed(() => {
|
||||
if (props.isSelected) return props.isDelete ? 'red' : 'gold';
|
||||
else return 'white';
|
||||
});
|
||||
const lineWidth = computed(() => (props.isSelected ? 2 : 1));
|
||||
|
||||
return () => (
|
||||
<container loc={props.loc}>
|
||||
<text
|
||||
text={name.value}
|
||||
font={font}
|
||||
loc={[w / 2, 20, void 0, void 0, 0.5, 1]}
|
||||
loc={[w.value / 2, 20]}
|
||||
anc={[0.5, 1]}
|
||||
/>
|
||||
<g-rect
|
||||
loc={[lineWidth.value, 24, w - 2 * lineWidth.value, w]}
|
||||
fill
|
||||
stroke
|
||||
loc={imgLoc.value}
|
||||
strokeAndFill
|
||||
fillStyle="gray"
|
||||
strokeStyle={strokeStyle.value}
|
||||
lineWidth={lineWidth.value}
|
||||
lineJoin="miter"
|
||||
cursor="pointer"
|
||||
/>
|
||||
<Thumbnail
|
||||
hidden={props.data === null}
|
||||
loc={[3, 26, w - 6, w - 4]}
|
||||
hidden={!props.data}
|
||||
loc={imgLoc.value}
|
||||
padStyle="gray"
|
||||
floorId={props.data?.data.floorId || 'MT0'}
|
||||
floorId={floorId.value}
|
||||
map={mapBlocks.value}
|
||||
hero={props.data?.data.hero as HeroStatus}
|
||||
hero={props.data?.data.hero}
|
||||
all
|
||||
noHD
|
||||
size={w / MAP_WIDTH}
|
||||
size={(w.value - 4) / MAP_WIDTH}
|
||||
noevent
|
||||
/>
|
||||
<text
|
||||
text={statusText.value}
|
||||
fillStyle="yellow"
|
||||
font={statusFont}
|
||||
loc={[w / 2, w + 28, void 0, void 0, 0.5, 0]}
|
||||
loc={[w.value / 2, w.value + 28]}
|
||||
anc={[0.5, 0]}
|
||||
/>
|
||||
</container>
|
||||
);
|
||||
@ -117,62 +131,108 @@ export const SaveBtn = defineComponent<SaveBtnProps>(props => {
|
||||
|
||||
export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||
(props, { emit }) => {
|
||||
const row = 2;
|
||||
const column = 3;
|
||||
/** 除自动存档外,每一页容纳的存档数量 */
|
||||
const pageCap = row * column - 1;
|
||||
const itemSize = 150;
|
||||
const itemHeight = itemSize + 40;
|
||||
const interval = 30;
|
||||
|
||||
const font = new Font('normal', 18);
|
||||
const pageFont = new Font('normal', 14);
|
||||
|
||||
const isDelete = ref(false);
|
||||
/** 当前页上被选中的存档的posIndex */
|
||||
const selected = ref(0);
|
||||
const now = ref(0);
|
||||
const inDelete = ref(false);
|
||||
const pageRef = ref<PageExpose>();
|
||||
|
||||
/** posIndex 存档在当前页的序号 范围为0到pageCap-1 */
|
||||
const saveData: Record<number, SaveData | null> = shallowReactive({});
|
||||
|
||||
const width = computed(() => props.loc[2] ?? 200);
|
||||
const height = computed(() => props.loc[3] ?? 200);
|
||||
|
||||
const grid = computed<IGridLayoutData>(() =>
|
||||
adjustGrid(
|
||||
width.value,
|
||||
height.value - 30,
|
||||
itemSize,
|
||||
itemHeight,
|
||||
interval
|
||||
)
|
||||
);
|
||||
|
||||
const contentLoc = computed<ElementLocator>(() => {
|
||||
const cx = width.value / 2;
|
||||
const cy = (height.value - 30) / 2;
|
||||
return [cx, cy, grid.value.width, grid.value.height, 0.5, 0.5];
|
||||
});
|
||||
|
||||
const deleteLoc = computed<ElementLocator>(() => {
|
||||
const pad = (width.value - grid.value.width) / 2;
|
||||
return [pad, height.value - 13, void 0, void 0, 0, 1];
|
||||
});
|
||||
|
||||
const exitLoc = computed<ElementLocator>(() => {
|
||||
const pad = (width.value - grid.value.width) / 2;
|
||||
const right = width.value - pad;
|
||||
return [right, height.value - 13, void 0, void 0, 1, 1];
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取存档在当前页的序号,范围为 0 到 pageCap-1。
|
||||
*/
|
||||
const getPosIndex = (index: number) => {
|
||||
if (index === -1) return 0;
|
||||
return index - pageCap * (pageRef.value?.now() || 0) + 1;
|
||||
};
|
||||
/** index 存档的总序号 从0开始 用于数据交互 */
|
||||
const getIndex = (posIndex: number, page: number) => {
|
||||
return page * pageCap + posIndex - 1;
|
||||
return index % (grid.value.count - 1);
|
||||
};
|
||||
|
||||
/** 存档数据的列表 */
|
||||
const dataList = ref<(SaveData | null)[]>(
|
||||
Array(pageCap + 1).fill(null)
|
||||
);
|
||||
const updateDataList = (page: number) => {
|
||||
dataList.value.forEach((_ele, i) => {
|
||||
getSave(getIndex(i, page)).then(saveValue => {
|
||||
dataList.value[i] = saveValue;
|
||||
});
|
||||
/**
|
||||
* 获取存档的总序号,从 0 开始,用于数据交互。
|
||||
*/
|
||||
const getIndex = (posIndex: number, page: number) => {
|
||||
return page * grid.value.count + posIndex - 1;
|
||||
};
|
||||
|
||||
const updateDataList = async (page: number) => {
|
||||
const promises: Promise<SaveData | null>[] = [];
|
||||
for (let i = 0; i < grid.value.count; i++) {
|
||||
const index = getIndex(i, page);
|
||||
promises.push(getSave(index));
|
||||
}
|
||||
const data = await Promise.all(promises);
|
||||
|
||||
data.forEach((v, i) => {
|
||||
if (v) {
|
||||
saveData[i] = v;
|
||||
} else {
|
||||
saveData[i] = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
const hasData = (posIndex: number) => {
|
||||
return dataList.value[posIndex] !== null;
|
||||
|
||||
const exist = (index: number) => {
|
||||
return saveData[index] !== null;
|
||||
};
|
||||
const getData = (posIndex: number) => dataList.value[posIndex];
|
||||
const deleteData = (posIndex: number) => {
|
||||
dataList.value[posIndex] = null;
|
||||
|
||||
const deleteData = (index: number) => {
|
||||
saveData[index] = null;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const currPage = pageRef.value?.now() || 0;
|
||||
updateDataList(currPage);
|
||||
updateDataList(now.value);
|
||||
});
|
||||
|
||||
/** 当前页上被选中的存档的posIndex */
|
||||
const pickIndex = ref(1);
|
||||
|
||||
const emitSave = (index: number) => {
|
||||
const posIndex = getPosIndex(index);
|
||||
if (isDelete.value) {
|
||||
emit('delete', index, hasData(posIndex));
|
||||
if (inDelete.value) {
|
||||
emit('delete', index, exist(posIndex));
|
||||
deleteData(posIndex);
|
||||
} else {
|
||||
emit('emit', index, hasData(posIndex));
|
||||
emit('emit', index, exist(posIndex));
|
||||
}
|
||||
if (index === -1) {
|
||||
selected.value = 0;
|
||||
} else {
|
||||
selected.value = (index % (grid.value.count - 1)) + 1;
|
||||
}
|
||||
pickIndex.value = (index % pageCap) + 1;
|
||||
};
|
||||
|
||||
const wheel = (ev: IWheelEvent) => {
|
||||
@ -185,7 +245,7 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||
};
|
||||
|
||||
const toggleDelete = () => {
|
||||
isDelete.value = !isDelete.value;
|
||||
inDelete.value = !inDelete.value;
|
||||
};
|
||||
|
||||
const exit = () => {
|
||||
@ -194,11 +254,14 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||
};
|
||||
|
||||
// #region 按键实现
|
||||
|
||||
const [key] = useKey();
|
||||
key.realize('confirm', () => {
|
||||
const currPage = pageRef.value?.now();
|
||||
if (currPage === void 0) return;
|
||||
emitSave(pageCap * currPage + pickIndex.value);
|
||||
if (selected.value === 0) {
|
||||
emitSave(-1);
|
||||
} else {
|
||||
emitSave((grid.value.count - 1) * now.value + selected.value);
|
||||
}
|
||||
})
|
||||
.realize('exit', exit)
|
||||
.realize('@save_exit', exit)
|
||||
@ -220,14 +283,16 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||
'@save_up',
|
||||
() => {
|
||||
if (!pageRef.value) return;
|
||||
const now = pageRef.value.now();
|
||||
if (pickIndex.value >= row) {
|
||||
pickIndex.value -= column;
|
||||
const cols = grid.value.cols;
|
||||
const count = grid.value.count;
|
||||
if (selected.value >= cols) {
|
||||
selected.value -= cols;
|
||||
} else {
|
||||
if (now === 0) {
|
||||
pickIndex.value = 0;
|
||||
if (now.value === 0) {
|
||||
selected.value = 0;
|
||||
} else {
|
||||
pickIndex.value += pageCap + 1 - column;
|
||||
const selectedCol = selected.value % cols;
|
||||
selected.value = count - (cols - selectedCol);
|
||||
pageRef.value?.movePage(-1);
|
||||
}
|
||||
}
|
||||
@ -237,10 +302,13 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||
.realize(
|
||||
'@save_down',
|
||||
() => {
|
||||
if (pickIndex.value <= pageCap - row) {
|
||||
pickIndex.value += column;
|
||||
const cols = grid.value.cols;
|
||||
const count = grid.value.count;
|
||||
if (selected.value < count - cols) {
|
||||
selected.value += cols;
|
||||
} else {
|
||||
pickIndex.value += column - pageCap - 1;
|
||||
const selectedCol = selected.value % cols;
|
||||
selected.value = selectedCol;
|
||||
pageRef.value?.movePage(1);
|
||||
}
|
||||
},
|
||||
@ -250,12 +318,12 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||
'@save_left',
|
||||
() => {
|
||||
if (!pageRef.value) return;
|
||||
const now = pageRef.value.now();
|
||||
if (pickIndex.value > 0) {
|
||||
pickIndex.value--;
|
||||
const count = grid.value.count;
|
||||
if (selected.value > 0) {
|
||||
selected.value--;
|
||||
} else {
|
||||
if (now > 0) {
|
||||
pickIndex.value = pageCap;
|
||||
if (now.value > 0) {
|
||||
selected.value = count;
|
||||
pageRef.value?.movePage(-1);
|
||||
}
|
||||
}
|
||||
@ -265,99 +333,62 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||
.realize(
|
||||
'@save_right',
|
||||
() => {
|
||||
if (pickIndex.value < pageCap) {
|
||||
pickIndex.value++;
|
||||
const count = grid.value.count;
|
||||
if (selected.value < count) {
|
||||
selected.value++;
|
||||
} else {
|
||||
pickIndex.value = 0;
|
||||
selected.value = 0;
|
||||
pageRef.value?.movePage(1);
|
||||
}
|
||||
},
|
||||
{ type: 'down-repeat' }
|
||||
);
|
||||
// #endregion
|
||||
|
||||
return () => (
|
||||
<container loc={props.loc} zIndex={10}>
|
||||
<Page
|
||||
loc={[0, 0, MAP_WIDTH, MAP_HEIGHT - 10]}
|
||||
ref={pageRef}
|
||||
loc={[0, 0, width.value, height.value - 10]}
|
||||
pages={1000}
|
||||
font={pageFont}
|
||||
v-model:page={now.value}
|
||||
onWheel={wheel}
|
||||
onPageChange={updateDataList}
|
||||
ref={pageRef}
|
||||
font={pageFont}
|
||||
>
|
||||
{(page: number) => (
|
||||
<container loc={[0, 0, MAP_WIDTH, MAP_HEIGHT]}>
|
||||
<SaveBtn
|
||||
loc={[30, 50, 120, 170]}
|
||||
index={-1}
|
||||
isSelected={pickIndex.value === 0}
|
||||
isDelete={isDelete.value}
|
||||
onClick={() => emitSave(-1)}
|
||||
cursor="pointer"
|
||||
data={getData(0)}
|
||||
/>
|
||||
<SaveBtn
|
||||
loc={[180, 50, 120, 170]}
|
||||
index={page * pageCap}
|
||||
isSelected={pickIndex.value === 1}
|
||||
isDelete={isDelete.value}
|
||||
onClick={() => emitSave(page * pageCap)}
|
||||
cursor="pointer"
|
||||
data={getData(1)}
|
||||
/>
|
||||
<SaveBtn
|
||||
loc={[330, 50, 120, 170]}
|
||||
index={page * pageCap + 1}
|
||||
isSelected={pickIndex.value === 2}
|
||||
isDelete={isDelete.value}
|
||||
onClick={() => emitSave(page * pageCap + 1)}
|
||||
cursor="pointer"
|
||||
data={getData(2)}
|
||||
/>
|
||||
<SaveBtn
|
||||
loc={[30, 230, 120, 170]}
|
||||
index={page * pageCap + 2}
|
||||
isSelected={pickIndex.value === 3}
|
||||
isDelete={isDelete.value}
|
||||
onClick={() => emitSave(page * pageCap + 2)}
|
||||
cursor="pointer"
|
||||
data={getData(3)}
|
||||
/>
|
||||
<SaveBtn
|
||||
loc={[180, 230, 120, 170]}
|
||||
index={page * pageCap + 3}
|
||||
isSelected={pickIndex.value === 4}
|
||||
isDelete={isDelete.value}
|
||||
onClick={() => emitSave(page * pageCap + 3)}
|
||||
cursor="pointer"
|
||||
data={getData(4)}
|
||||
/>
|
||||
<SaveBtn
|
||||
loc={[330, 230, 120, 170]}
|
||||
index={page * pageCap + 4}
|
||||
isSelected={pickIndex.value === 5}
|
||||
isDelete={isDelete.value}
|
||||
onClick={() => emitSave(page * pageCap + 4)}
|
||||
cursor="pointer"
|
||||
data={getData(5)}
|
||||
/>
|
||||
<container loc={contentLoc.value}>
|
||||
{grid.value.locs.map((v, i) => {
|
||||
const count = grid.value.count;
|
||||
const rawIndex = (count - 1) * page + i;
|
||||
const index = i === 0 ? -1 : rawIndex;
|
||||
return (
|
||||
<SaveItem
|
||||
loc={v}
|
||||
index={index}
|
||||
selected={selected.value === i}
|
||||
inDelete={inDelete.value}
|
||||
data={saveData[i]}
|
||||
onClick={() => emitSave(index)}
|
||||
onEnter={() => (selected.value = i)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</container>
|
||||
)}
|
||||
</Page>
|
||||
<text
|
||||
text="删除模式"
|
||||
loc={deleteLoc.value}
|
||||
font={font}
|
||||
loc={[30, 450, void 0, void 0, 0, 0]}
|
||||
zIndex={10}
|
||||
fillStyle={isDelete.value ? 'red' : 'white'}
|
||||
fillStyle={inDelete.value ? 'red' : 'white'}
|
||||
onClick={toggleDelete}
|
||||
cursor="pointer"
|
||||
/>
|
||||
<text
|
||||
text="返回游戏"
|
||||
loc={exitLoc.value}
|
||||
font={font}
|
||||
loc={[450, 450, void 0, void 0, 1, 0]}
|
||||
zIndex={10}
|
||||
onClick={exit}
|
||||
cursor="pointer"
|
||||
@ -387,9 +418,9 @@ export type SaveValidationFunction = (
|
||||
* 使用示例:
|
||||
* ```ts
|
||||
* const index = await selectSave(props.controller, [0, 0, 416, 416]);
|
||||
* if (index === -2) {
|
||||
* if (index === -1) {
|
||||
* // 如果用户未选择存档,而是关闭了存档。
|
||||
* } else if (index === -1) {
|
||||
* } else if (index === 0) {
|
||||
* // 用户选择了自动存档。
|
||||
* } else {
|
||||
* // 用户选择了一个存档。
|
||||
@ -462,7 +493,6 @@ export async function saveSave(
|
||||
};
|
||||
const index = await selectSave(controller, loc, validate, props);
|
||||
if (index === -2) return false;
|
||||
// 由于样板存档编号从1开始,这里需要+1
|
||||
core.doSL(index + 1, 'save');
|
||||
return true;
|
||||
}
|
||||
|
59
packages-user/client-modules/src/render/utils/layout.ts
Normal file
59
packages-user/client-modules/src/render/utils/layout.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { ElementLocator } from '@motajs/render-core';
|
||||
|
||||
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
|
||||
};
|
||||
}
|
@ -25,7 +25,7 @@ export function getSave(index: number) {
|
||||
const content = {
|
||||
name: core.firstData.name,
|
||||
version: core.firstData.version,
|
||||
data: data
|
||||
data: data instanceof Array ? data[0] : data
|
||||
};
|
||||
res(content);
|
||||
});
|
||||
|
4
src/types/declaration/util.d.ts
vendored
4
src/types/declaration/util.d.ts
vendored
@ -821,7 +821,7 @@ interface Animate {
|
||||
pitch: any;
|
||||
}
|
||||
|
||||
type Save = DeepReadonly<{
|
||||
type Save = {
|
||||
/**
|
||||
* 存档所在的楼层id
|
||||
*/
|
||||
@ -866,7 +866,7 @@ type Save = DeepReadonly<{
|
||||
* 存档时间
|
||||
*/
|
||||
time: number;
|
||||
}>;
|
||||
};
|
||||
|
||||
/**
|
||||
* 深度只读一个对象,使其所有属性都只读
|
||||
|
Loading…
Reference in New Issue
Block a user