feat: Choice 选项框

This commit is contained in:
unanmed 2025-03-01 16:35:20 +08:00
parent ee5b962743
commit 109e77d6a2
6 changed files with 598 additions and 209 deletions

View File

@ -126,7 +126,8 @@ export class Text extends RenderItem<ETextEvent> {
this.length = width;
this.descent = actualBoundingBoxAscent;
const height = actualBoundingBoxAscent + actualBoundingBoxDescent;
this.size(width, height + this.strokeWidth * 2 + SAFE_PAD * 2);
const stroke = this.strokeWidth * 2;
this.size(width + stroke, height + stroke + SAFE_PAD * 2);
}
protected handleProps(

View File

@ -562,13 +562,17 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
}
private toTagString(item: RenderItem, space: number, deep: number): string {
if (item.isComment) return '';
const name = item.constructor.name;
if (item.children.size === 0) {
return `${' '.repeat(deep * space)}<${name} id="${item.id}" uid="${item.uid}" type="${item.type}"${item.hidden ? ' hidden' : ''}></${name}>\n`;
return `${' '.repeat(deep * space)}<${name} ${item.id ? `id="${item.id}" ` : ''}uid="${item.uid}"${item.hidden ? ' hidden' : ''} />\n`;
} else {
return (
`${' '.repeat(deep * space)}<${name} id="${item.id}" uid="${item.uid}" type="${item.type}" ${item.hidden ? 'hidden' : ''}>\n` +
`${[...item.children].map(v => this.toTagString(v, space, deep + 1)).join('')}` +
`${' '.repeat(deep * space)}<${name} ${item.id ? `${item.id} ` : ''}uid="${item.uid}" ${item.hidden ? 'hidden' : ''}>\n` +
`${[...item.children]
.filter(v => !v.isComment)
.map(v => this.toTagString(v, space, deep + 1))
.join('')}` +
`${' '.repeat(deep * space)}</${name}>\n`
);
}

View File

@ -33,16 +33,22 @@ type _FontStretch =
type _FontVariant = 'normal' | 'small-caps';
export class Font implements IFontConfig {
static defaultFamily: string = 'Verdana';
static defaultSize: number = 16;
static defaultSizeUnit: string = 'px';
static defaultWeight: number = 400;
static defaultItalic: boolean = false;
private readonly fallbacks: Font[] = [];
private fontString: string = '';
constructor(
public readonly family: string = 'Verdana',
public readonly size: number = 16,
public readonly sizeUnit: string = 'px',
public readonly weight: number = 400,
public readonly italic: boolean = false
public readonly family: string = Font.defaultFamily,
public readonly size: number = Font.defaultSize,
public readonly sizeUnit: string = Font.defaultSizeUnit,
public readonly weight: number = Font.defaultWeight,
public readonly italic: boolean = Font.defaultItalic
) {
this.fontString = this.getFont();
}
@ -93,11 +99,11 @@ export class Font implements IFontConfig {
private static parseOne(str: string) {
if (!str) return new Font();
let italic = false;
let weight = 400;
let size = 16;
let unit = 'px';
let family = 'Verdana';
let italic = this.defaultItalic;
let weight = this.defaultWeight;
let size = this.defaultSize;
let unit = this.defaultSizeUnit;
let family = this.defaultFamily;
const tokens = str.split(/\s+/);
tokens.forEach(v => {
// font-italic
@ -136,6 +142,24 @@ export class Font implements IFontConfig {
}
}
/**
*
*/
static setDefaults(font: Font) {
this.defaultFamily = font.family;
this.defaultItalic = font.italic;
this.defaultSize = font.size;
this.defaultSizeUnit = font.sizeUnit;
this.defaultWeight = font.weight;
}
/**
*
*/
static defaults() {
return new Font();
}
/**
*
* @param font

View File

@ -1,15 +1,16 @@
import { DefaultProps, ElementLocator, useKey } from '@/core/render';
import { computed, defineComponent, ref } from 'vue';
import { DefaultProps, ElementLocator, Font, useKey } from '@/core/render';
import { computed, defineComponent, reactive, ref } from 'vue';
import { Background, Selection } from './misc';
import { TextContent, TextContentExpose, TextContentProps } from './textbox';
import { SetupComponentOptions } from './types';
import { TextAlign } from './textboxTyper';
import { Page, PageExpose } from './page';
export interface ConfirmBoxProps extends DefaultProps, TextContentProps {
text: string;
width: number;
loc: ElementLocator;
selFont?: string;
selFont?: Font;
selFill?: CanvasStyle;
pad?: number;
yesText?: string;
@ -47,6 +48,34 @@ const confirmBoxProps = {
keyof ConfirmBoxEmits
>;
/**
* 2.x drawConfirm
* {@link ConfirmBoxProps} {@link ConfirmBoxEmits}
* ```tsx
* const onYes = () => console.log('yes');
* const onNo = () => console.log('no');
*
* <ConfirmBox
* text="是否要返回标题界面"
* width={240}
* // 确认框会自动计算宽度和高度,因此不需要手动指定,即使手动指定也无效
* loc={[240, 240, void 0, void 0, 0.5, 0.5]}
* // 使用 winskin 图片作为背景
* winskin="winskin.png"
* // 使用颜色作为背景和边框,如果设置了 winskin那么此参数无效
* color="#333"
* border="gold"
* // 设置选项的字体
* selFont="16px Verdana"
* // 设置选项的文本颜色
* selFill="#d48"
* // 完全继承 TextContent 的参数,因此可以填写 fontFamily 参数指定文本字体
* fontFamily="Arial"
* onYes={onYes}
* onNo={onNo}
* />
* ```
*/
export const ConfirmBox = defineComponent<
ConfirmBoxProps,
ConfirmBoxEmits,
@ -132,7 +161,6 @@ export const ConfirmBox = defineComponent<
<Selection
loc={selectLoc.value}
winskin={props.winskin}
color={props.color}
border={props.border}
noevent
zIndex={10}
@ -162,3 +190,305 @@ export const ConfirmBox = defineComponent<
</container>
);
}, confirmBoxProps);
export interface ChoicesProps extends DefaultProps, TextContentProps {
choices: [key: string | number | symbol, text: string][];
loc: ElementLocator;
width: number;
maxHeight?: number;
text?: string;
title?: string;
winskin?: ImageIds;
color?: CanvasStyle;
border?: CanvasStyle;
selFont?: Font;
selFill?: CanvasStyle;
titleFont?: Font;
titleFill?: CanvasStyle;
pad?: number;
defaultChoice?: string | number | symbol;
interval?: number;
}
export type ChoicesEmits = {
choice: (key: string | number | symbol) => void;
};
const choicesProps = {
props: [
'choices',
'loc',
'width',
'maxHeight',
'text',
'title',
'winskin',
'color',
'border',
'selFont',
'selFill',
'titleFont',
'titleFill',
'pad',
'defaultChoice',
'interval'
],
emits: ['choice']
} satisfies SetupComponentOptions<
ChoicesProps,
ChoicesEmits,
keyof ChoicesEmits
>;
export const Choices = defineComponent<
ChoicesProps,
ChoicesEmits,
keyof ChoicesEmits
>((props, { emit, attrs }) => {
const titleHeight = ref(0);
const contentHeight = ref(0);
const selected = ref(0);
const pageCom = ref<PageExpose>();
const choiceSize = reactive<[number, number][]>([]);
const selFont = computed(() => props.selFont ?? new Font());
const maxHeight = computed(() => props.maxHeight ?? 360);
const pad = computed(() => props.pad ?? 28);
const choiceInterval = computed(() => props.interval ?? 16);
const hasText = computed(() => !!props.text);
const hasTitle = computed(() => !!props.title);
const contentWidth = computed(() => props.width - pad.value * 2);
const choiceHeight = computed(
() => selFont.value.size + 8 + choiceInterval.value
);
const contentY = computed(() => {
if (hasTitle.value) {
return pad.value * 2 + titleHeight.value;
} else {
return pad.value;
}
});
const choicesY = computed(() => {
const padding = pad.value;
const text = hasText.value;
let y = padding;
if (hasTitle.value) {
y += titleHeight.value;
if (text) {
y += padding / 2;
} else {
y += padding;
}
}
if (text) {
y += contentHeight.value;
y += padding / 2;
}
return y;
});
const choicesMaxHeight = computed(
() =>
maxHeight.value -
choicesY.value -
pad.value * 2 -
selFont.value.size -
8
);
const choiceCountPerPage = computed(() =>
Math.max(Math.floor(choicesMaxHeight.value / choiceHeight.value), 1)
);
const pages = computed(() =>
Math.ceil(props.choices.length / choiceCountPerPage.value)
);
const choicesHeight = computed(() => {
const padBottom = pages.value > 1 ? pad.value + selFont.value.size : 0;
if (props.choices.length > choiceCountPerPage.value) {
return choiceCountPerPage.value * choiceHeight.value + padBottom;
} else {
return props.choices.length * choiceHeight.value + padBottom;
}
});
const boxHeight = computed(() => {
if (props.choices.length > choiceCountPerPage.value) {
return (
choicesHeight.value +
choicesY.value +
// 不乘2是因为 choiceY 已经算上了顶部填充
pad.value
);
} else {
return (
choicesHeight.value +
choicesY.value +
// 不乘2是因为 choiceY 已经算上了顶部填充
pad.value
);
}
});
const boxLoc = computed<ElementLocator>(() => {
const [x = 0, y = 0, , , ax = 0, ay = 0] = props.loc;
return [x, y, props.width, boxHeight.value, ax, ay];
});
const titleLoc = computed<ElementLocator>(() => {
return [props.width / 2, pad.value, void 0, void 0, 0.5, 0];
});
const contentLoc = computed<ElementLocator>(() => {
return [
props.width / 2,
contentY.value,
contentWidth.value,
void 0,
0.5,
0
];
});
const choiceLoc = computed<ElementLocator>(() => {
return [
props.width / 2,
choicesY.value,
contentWidth.value,
choicesHeight.value,
0.5,
0
];
});
const selectionLoc = computed<ElementLocator>(() => {
const [width = 200, height = 200] = choiceSize[selected.value] ?? [];
return [
props.width / 2 - pad.value,
(selected.value + 0.5) * choiceHeight.value,
width + 8,
height + 8,
0.5,
0.5
];
});
const getPageContent = (page: number) => {
const count = choiceCountPerPage.value;
return props.choices.slice(page * count, (page + 1) * count);
};
const getChoiceLoc = (index: number): ElementLocator => {
return [
props.width / 2 - pad.value,
choiceHeight.value * (index + 0.5),
void 0,
void 0,
0.5,
0.5
];
};
const updateContentHeight = (height: number) => {
contentHeight.value = height;
};
const updateTitleHeight = (_0: string, _1: number, height: number) => {
titleHeight.value = height;
};
const updateChoiceSize = (index: number, width: number, height: number) => {
choiceSize[index] = [width, height];
};
const onPageChange = () => {
selected.value = 0;
};
const [key] = useKey();
key.realize('moveUp', () => {
if (selected.value === 0) {
if (pageCom.value?.now() !== 0) {
pageCom.value?.movePage(-1);
selected.value = choiceCountPerPage.value - 1;
}
} else {
selected.value--;
}
});
key.realize('moveDown', () => {
if (selected.value === choiceCountPerPage.value - 1) {
pageCom.value?.movePage(1);
selected.value = 0;
} else {
const page = pageCom.value?.now() ?? 1;
const index = page * choiceCountPerPage.value + selected.value;
if (index < props.choices.length - 1) {
selected.value++;
}
}
});
key.realize('moveLeft', () => pageCom.value?.movePage(-1));
key.realize('moveRight', () => pageCom.value?.movePage(1));
key.realize('confirm', () => {
const page = pageCom.value?.now() ?? 1;
const index = page * choiceCountPerPage.value + selected.value;
emit('choice', props.choices[index][0]);
});
return () => (
<container loc={boxLoc.value}>
<Background
loc={[0, 0, props.width, boxHeight.value]}
winskin={props.winskin}
color={props.color}
border={props.border}
/>
{hasTitle.value && (
<text
loc={titleLoc.value}
text={props.title}
font={props.titleFont ?? new Font(void 0, 18)}
fillStyle={props.titleFill ?? 'gold'}
zIndex={5}
onSetText={updateTitleHeight}
/>
)}
{hasText.value && (
<TextContent
{...attrs}
text={props.text}
loc={contentLoc.value}
width={contentWidth.value}
zIndex={5}
autoHeight
onUpdateHeight={updateContentHeight}
/>
)}
<Page
ref={pageCom}
loc={choiceLoc.value}
pages={pages.value}
font={props.selFont}
hideIfSingle
onPageChange={onPageChange}
>
{(page: number) => [
<Selection
loc={selectionLoc.value}
winskin={props.winskin}
color={props.color}
border={props.border}
/>,
...getPageContent(page).map((v, i) => {
return (
<text
text={v[1]}
loc={getChoiceLoc(i)}
font={props.selFont}
cursor="pointer"
zIndex={5}
onClick={() => emit('choice', v[0])}
onSetText={(_, width, height) =>
updateChoiceSize(i, width, height)
}
onEnter={() => (selected.value = i)}
/>
);
})
]}
</Page>
</container>
);
}, choicesProps);

View File

@ -26,12 +26,27 @@ export interface PageProps extends DefaultProps {
hideIfSingle?: boolean;
}
export type PageEmits = {
pageChange: (page: number) => void;
};
export interface PageExpose {
/**
*
* @param page 1
*/
changePage(page: number): void;
/**
*
* @param delta
*/
movePage(delta: number): void;
/**
*
*/
now(): number;
}
type PageSlots = SlotsType<{
@ -39,251 +54,267 @@ type PageSlots = SlotsType<{
}>;
const pageProps = {
props: ['pages', 'loc', 'font', 'hideIfSingle']
} satisfies SetupComponentOptions<PageProps, {}, string, PageSlots>;
props: ['pages', 'loc', 'font', 'hideIfSingle'],
emits: ['pageChange']
} satisfies SetupComponentOptions<
PageProps,
PageEmits,
keyof PageEmits,
PageSlots
>;
/**
* {@link PageProps} {@link PageExpose}
*
* ---
*
* page
* page 0 1
* ```tsx
* <Page maxPage={5}>
* {
* (page: number) => {
* // 页码从第一页开始,因此这里索引要减一
* return items[page - 1].map(v => <text text={v.text} />)
* return items[page].map(v => <text text={v.text} />)
* }
* }
* </Page>
* ```
*/
export const Page = defineComponent<PageProps, {}, string, PageSlots>(
(props, { slots, expose }) => {
const nowPage = ref(1);
export const Page = defineComponent<
PageProps,
PageEmits,
keyof PageEmits,
PageSlots
>((props, { slots, expose, emit }) => {
const nowPage = ref(0);
// 五个元素的位置
const leftLoc = ref<ElementLocator>([]);
const leftPageLoc = ref<ElementLocator>([]);
const nowPageLoc = ref<ElementLocator>([]);
const rightPageLoc = ref<ElementLocator>([]);
const rightLoc = ref<ElementLocator>([]);
/** 内容的位置 */
const contentLoc = ref<ElementLocator>([]);
/** 页码容器的位置 */
const pageLoc = ref<ElementLocator>([]);
/** 页码的矩形框的位置 */
const rectLoc = ref<ElementLocator>([0, 0, 0, 0]);
/** 页面文字的位置 */
const textLoc = ref<ElementLocator>([0, 0, 0, 0]);
// 五个元素的位置
const leftLoc = ref<ElementLocator>([]);
const leftPageLoc = ref<ElementLocator>([]);
const nowPageLoc = ref<ElementLocator>([]);
const rightPageLoc = ref<ElementLocator>([]);
const rightLoc = ref<ElementLocator>([]);
/** 内容的位置 */
const contentLoc = ref<ElementLocator>([]);
/** 页码容器的位置 */
const pageLoc = ref<ElementLocator>([]);
/** 页码的矩形框的位置 */
const rectLoc = ref<ElementLocator>([0, 0, 0, 0]);
/** 页面文字的位置 */
const textLoc = ref<ElementLocator>([0, 0, 0, 0]);
// 两个监听的参数
const leftArrow = ref<Path2D>();
const rightArrow = ref<Path2D>();
// 两个监听的参数
const leftArrow = ref<Path2D>();
const rightArrow = ref<Path2D>();
const font = computed(() => props.font ?? new Font());
const isFirst = computed(() => nowPage.value === 1);
const isLast = computed(() => nowPage.value === props.pages);
const width = computed(() => props.loc[2] ?? 200);
const height = computed(() => props.loc[3] ?? 200);
const round = computed(() => font.value.size / 4);
const nowPageFont = computed(() =>
Font.clone(font.value, { weight: 700 })
);
const hide = computed(() => props.hideIfSingle && props.pages === 1);
const font = computed(() => props.font ?? new Font());
const isFirst = computed(() => nowPage.value === 0);
const isLast = computed(() => nowPage.value === props.pages - 1);
const width = computed(() => props.loc[2] ?? 200);
const height = computed(() => props.loc[3] ?? 200);
const round = computed(() => font.value.size / 4);
const nowPageFont = computed(() => Font.clone(font.value, { weight: 700 }));
// 左右箭头的颜色
const leftColor = computed(() => (isFirst.value ? '#666' : '#ddd'));
const rightColor = computed(() => (isLast.value ? '#666' : '#ddd'));
// 左右箭头的颜色
const leftColor = computed(() => (isFirst.value ? '#666' : '#ddd'));
const rightColor = computed(() => (isLast.value ? '#666' : '#ddd'));
let updating = false;
const updatePagePos = () => {
if (updating) return;
updating = true;
nextTick(() => {
updating = false;
});
const pageH = font.value.size + 8;
contentLoc.value = [0, 0, width.value, height.value - pageH];
pageLoc.value = [0, height.value - pageH, width.value, pageH];
const center = width.value / 2;
const size = font.value.size * 1.5;
nowPageLoc.value = [center, 0, size, size, 0.5, 0];
leftPageLoc.value = [center - size * 1.5, 0, size, size, 0.5, 0];
leftLoc.value = [center - size * 3, 0, size, size, 0.5, 0];
rightPageLoc.value = [center + size * 1.5, 0, size, size, 0.5, 0];
rightLoc.value = [center + size * 3, 0, size, size, 0.5, 0];
};
const updateArrowPath = () => {
const rectSize = font.value.size * 1.5;
const size = font.value.size;
const pad = rectSize - size;
const left = new Path2D();
left.moveTo(size, pad);
left.lineTo(pad, rectSize / 2);
left.lineTo(size, rectSize - pad);
const right = new Path2D();
right.moveTo(pad, pad);
right.lineTo(size, rectSize / 2);
right.lineTo(pad, rectSize - pad);
leftArrow.value = left;
rightArrow.value = right;
};
const updateRectAndText = () => {
const size = font.value.size * 1.5;
const pad = RECT_PAD * size;
rectLoc.value = [pad, pad, size - pad * 2, size - pad * 2];
textLoc.value = [size / 2, size / 2, void 0, void 0, 0.5, 0.5];
};
watch(font, () => {
updatePagePos();
updateArrowPath();
updateRectAndText();
let updating = false;
const updatePagePos = () => {
if (updating) return;
updating = true;
nextTick(() => {
updating = false;
});
watch(
() => props.loc,
() => {
updatePagePos();
updateRectAndText();
}
);
const pageH = hide.value ? 0 : font.value.size + 8;
contentLoc.value = [0, 0, width.value, height.value - pageH];
pageLoc.value = [0, height.value - pageH, width.value, pageH];
const center = width.value / 2;
const size = font.value.size * 1.5;
nowPageLoc.value = [center, 0, size, size, 0.5, 0];
leftPageLoc.value = [center - size * 1.5, 0, size, size, 0.5, 0];
leftLoc.value = [center - size * 3, 0, size, size, 0.5, 0];
rightPageLoc.value = [center + size * 1.5, 0, size, size, 0.5, 0];
rightLoc.value = [center + size * 3, 0, size, size, 0.5, 0];
};
/**
*
*/
const changePage = (page: number) => {
const target = clamp(page, 1, props.pages);
const updateArrowPath = () => {
const rectSize = font.value.size * 1.5;
const size = font.value.size;
const pad = rectSize - size;
const left = new Path2D();
left.moveTo(size, pad);
left.lineTo(pad, rectSize / 2);
left.lineTo(size, rectSize - pad);
const right = new Path2D();
right.moveTo(pad, pad);
right.lineTo(size, rectSize / 2);
right.lineTo(pad, rectSize - pad);
leftArrow.value = left;
rightArrow.value = right;
};
const updateRectAndText = () => {
const size = font.value.size * 1.5;
const pad = RECT_PAD * size;
rectLoc.value = [pad, pad, size - pad * 2, size - pad * 2];
textLoc.value = [size / 2, size / 2, void 0, void 0, 0.5, 0.5];
};
watch(font, () => {
updatePagePos();
updateArrowPath();
updateRectAndText();
});
watch(
() => props.loc,
() => {
updatePagePos();
updateRectAndText();
}
);
/**
*
*/
const changePage = (page: number) => {
const target = clamp(page, 0, props.pages - 1);
if (nowPage.value !== target) {
nowPage.value = target;
};
emit('pageChange', target);
}
};
const lastPage = () => {
changePage(nowPage.value - 1);
};
const movePage = (delta: number) => {
changePage(nowPage.value + delta);
};
const nextPage = () => {
changePage(nowPage.value + 1);
};
const now = () => nowPage.value;
onMounted(() => {
updatePagePos();
updateArrowPath();
updateRectAndText();
});
const lastPage = () => {
changePage(nowPage.value - 1);
};
expose({ changePage });
const nextPage = () => {
changePage(nowPage.value + 1);
};
return () => {
return (
<container loc={props.loc}>
<container loc={contentLoc.value}>
{slots.default?.(nowPage.value)}
</container>
onMounted(() => {
updatePagePos();
updateArrowPath();
updateRectAndText();
});
expose<PageExpose>({ changePage, movePage, now });
return () => {
return (
<container loc={props.loc}>
<container loc={contentLoc.value}>
{slots.default?.(nowPage.value)}
</container>
<container loc={pageLoc.value} hidden={hide.value}>
<container
loc={pageLoc.value}
hidden={props.hideIfSingle && props.pages === 1}
key={1}
loc={leftLoc.value}
onClick={lastPage}
cursor="pointer"
>
<g-rectr
loc={rectLoc.value}
circle={[round.value]}
strokeStyle={leftColor.value}
lineWidth={1}
stroke
></g-rectr>
<g-path
path={leftArrow.value}
stroke
strokeStyle={leftColor.value}
lineWidth={1}
></g-path>
</container>
{!isFirst.value && (
<container
loc={leftLoc.value}
key={2}
loc={leftPageLoc.value}
onClick={lastPage}
cursor="pointer"
>
<g-rectr
loc={rectLoc.value}
circle={[round.value]}
strokeStyle={leftColor.value}
lineWidth={1}
stroke
></g-rectr>
<g-path
path={leftArrow.value}
stroke
strokeStyle={leftColor.value}
lineWidth={1}
></g-path>
</container>
{!isFirst.value && (
<container
loc={leftPageLoc.value}
onClick={lastPage}
cursor="pointer"
>
<g-rectr
loc={rectLoc.value}
circle={[round.value]}
strokeStyle="#ddd"
lineWidth={1}
stroke
></g-rectr>
<text
loc={textLoc.value}
text={(nowPage.value - 1).toString()}
font={font.value}
></text>
</container>
)}
<container loc={nowPageLoc.value}>
<g-rectr
loc={rectLoc.value}
circle={[round.value]}
strokeStyle="#ddd"
fillStyle="#ddd"
lineWidth={1}
fill
stroke
></g-rectr>
<text
loc={textLoc.value}
text={nowPage.value.toString()}
fillStyle="#222"
font={nowPageFont.value}
font={font.value}
></text>
</container>
{!isLast.value && (
<container
loc={rightPageLoc.value}
onClick={nextPage}
cursor="pointer"
>
<g-rectr
loc={rectLoc.value}
circle={[round.value]}
strokeStyle="#ddd"
lineWidth={1}
stroke
></g-rectr>
<text
loc={textLoc.value}
text={(nowPage.value + 1).toString()}
font={font.value}
></text>
</container>
)}
)}
<container loc={nowPageLoc.value} key={3}>
<g-rectr
loc={rectLoc.value}
circle={[round.value]}
strokeStyle="#ddd"
fillStyle="#ddd"
lineWidth={1}
fill
stroke
></g-rectr>
<text
loc={textLoc.value}
text={(nowPage.value + 1).toString()}
fillStyle="#222"
font={nowPageFont.value}
></text>
</container>
{!isLast.value && (
<container
loc={rightLoc.value}
key={4}
loc={rightPageLoc.value}
onClick={nextPage}
cursor="pointer"
>
<g-rectr
loc={rectLoc.value}
circle={[round.value]}
strokeStyle={rightColor.value}
strokeStyle="#ddd"
lineWidth={1}
stroke
></g-rectr>
<g-path
path={rightArrow.value}
stroke
strokeStyle={rightColor.value}
lineWidth={1}
></g-path>
<text
loc={textLoc.value}
text={(nowPage.value + 2).toString()}
font={font.value}
></text>
</container>
)}
<container
key={5}
loc={rightLoc.value}
onClick={nextPage}
cursor="pointer"
>
<g-rectr
loc={rectLoc.value}
circle={[round.value]}
strokeStyle={rightColor.value}
lineWidth={1}
stroke
></g-rectr>
<g-path
path={rightArrow.value}
stroke
strokeStyle={rightColor.value}
lineWidth={1}
></g-path>
</container>
</container>
);
};
},
pageProps
);
</container>
);
};
}, pageProps);

View File

@ -19,7 +19,7 @@ import { FloorItemDetail } from '@/plugin/fx/itemDetail';
import { PopText } from '@/plugin/fx/pop';
import { LayerGroupPortal } from '@/plugin/fx/portal';
import { defineComponent, onMounted, reactive, ref } from 'vue';
import { Textbox } from '../components';
import { Textbox, Tip } from '../components';
import { GameUI, UIController } from '@/core/system';
import {
MAIN_HEIGHT,
@ -35,7 +35,6 @@ import {
} from './statusBar';
import { onLoaded } from '../use';
import { ReplayingStatus } from './toolbar';
import { Tip } from '../components/tip';
const MainScene = defineComponent(() => {
const layerGroupExtends: ILayerGroupRenderExtends[] = [