mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-04-11 15:47:06 +08:00
feat: 页码 & chore: 暂时移除 cursor 属性
This commit is contained in:
parent
9588340b11
commit
06abef2595
@ -271,9 +271,6 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
/** 不透明度 */
|
||||
alpha: number = 1;
|
||||
|
||||
/** 鼠标覆盖在此元素上时的光标样式 */
|
||||
cursor: string = 'auto';
|
||||
|
||||
get x() {
|
||||
return this._transform.x;
|
||||
}
|
||||
@ -1152,11 +1149,6 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
this.setAnchor(nextValue[0] as number, nextValue[1] as number);
|
||||
return;
|
||||
}
|
||||
case 'cursor': {
|
||||
if (!this.assertType(nextValue, 'string', key)) return;
|
||||
this.cursor = nextValue;
|
||||
return;
|
||||
}
|
||||
case 'scale': {
|
||||
if (!this.assertType(nextValue, Array, key)) return;
|
||||
this._transform.setScale(
|
||||
|
@ -5,6 +5,57 @@ import { ElementNamespace, ComponentInternalInstance } from 'vue';
|
||||
import { clamp, isNil } from 'lodash-es';
|
||||
import { logger } from '@/core/common/logger';
|
||||
|
||||
export type CircleParams = [
|
||||
cx?: number,
|
||||
cy?: number,
|
||||
radius?: number,
|
||||
start?: number,
|
||||
end?: number
|
||||
];
|
||||
export type EllipseParams = [
|
||||
cx?: number,
|
||||
cy?: number,
|
||||
radiusX?: number,
|
||||
radiusY?: number,
|
||||
start?: number,
|
||||
end?: number
|
||||
];
|
||||
export type LineParams = [x1: number, y1: number, x2: number, y2: number];
|
||||
export type BezierParams = [
|
||||
sx: number,
|
||||
sy: number,
|
||||
cp1x: number,
|
||||
cp1y: number,
|
||||
cp2x: number,
|
||||
cp2y: number,
|
||||
ex: number,
|
||||
ey: number
|
||||
];
|
||||
export type QuadParams = [
|
||||
sx: number,
|
||||
sy: number,
|
||||
cpx: number,
|
||||
cpy: number,
|
||||
ex: number,
|
||||
ey: number
|
||||
];
|
||||
export type RectRCircleParams = [
|
||||
r1: number,
|
||||
r2?: number,
|
||||
r3?: number,
|
||||
r4?: number
|
||||
];
|
||||
export type RectREllipseParams = [
|
||||
rx1: number,
|
||||
ry1: number,
|
||||
rx2?: number,
|
||||
ry2?: number,
|
||||
rx3?: number,
|
||||
ry3?: number,
|
||||
rx4?: number,
|
||||
ry4?: number
|
||||
];
|
||||
|
||||
export interface ILineProperty {
|
||||
/** 线宽 */
|
||||
lineWidth: number;
|
||||
@ -376,18 +427,21 @@ export class Circle extends GraphicItemBase {
|
||||
if (!this.assertType(nextValue, 'number', key)) return;
|
||||
this.setAngle(this.start, nextValue);
|
||||
return;
|
||||
case 'circle':
|
||||
if (!this.assertType(nextValue, Array, key)) return;
|
||||
if (!isNil(nextValue[0])) {
|
||||
this.setRadius(nextValue[0] as number);
|
||||
case 'circle': {
|
||||
const value = nextValue as CircleParams;
|
||||
if (!this.assertType(value, Array, key)) return;
|
||||
const [cx, cy, radius, start, end] = value;
|
||||
if (!isNil(cx) && !isNil(cy)) {
|
||||
this.pos(cx, cy);
|
||||
}
|
||||
if (!isNil(nextValue[1]) && !isNil(nextValue[2])) {
|
||||
this.setAngle(
|
||||
nextValue[1] as number,
|
||||
nextValue[2] as number
|
||||
);
|
||||
if (!isNil(radius)) {
|
||||
this.setRadius(radius);
|
||||
}
|
||||
if (!isNil(start) && !isNil(end)) {
|
||||
this.setAngle(start, end);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.patchProp(key, prevValue, nextValue, namespace, parentComponent);
|
||||
}
|
||||
@ -464,21 +518,21 @@ export class Ellipse extends GraphicItemBase {
|
||||
if (!this.assertType(nextValue, 'number', key)) return;
|
||||
this.setAngle(this.start, nextValue);
|
||||
return;
|
||||
case 'ellipse':
|
||||
if (!this.assertType(nextValue, Array, key)) return;
|
||||
if (!isNil(nextValue[0]) && !isNil(nextValue[1])) {
|
||||
this.setRadius(
|
||||
nextValue[0] as number,
|
||||
nextValue[1] as number
|
||||
);
|
||||
case 'ellipse': {
|
||||
const value = nextValue as EllipseParams;
|
||||
if (!this.assertType(value, Array, key)) return;
|
||||
const [cx, cy, radiusX, radiusY, start, end] = value;
|
||||
if (!isNil(cx) && !isNil(cy)) {
|
||||
this.pos(cx, cy);
|
||||
}
|
||||
if (!isNil(nextValue[2]) && !isNil(nextValue[3])) {
|
||||
this.setAngle(
|
||||
nextValue[2] as number,
|
||||
nextValue[3] as number
|
||||
);
|
||||
if (!isNil(radiusX) && !isNil(radiusY)) {
|
||||
this.setRadius(radiusX, radiusY);
|
||||
}
|
||||
if (!isNil(start) && !isNil(end)) {
|
||||
this.setAngle(start, end);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.patchProp(key, prevValue, nextValue, namespace, parentComponent);
|
||||
}
|
||||
@ -858,23 +912,6 @@ export const enum RectRCorner {
|
||||
BottomLeft
|
||||
}
|
||||
|
||||
export type RectRCircleParams = [
|
||||
r1: number,
|
||||
r2?: number,
|
||||
r3?: number,
|
||||
r4?: number
|
||||
];
|
||||
export type RectREllipseParams = [
|
||||
rx1: number,
|
||||
ry1: number,
|
||||
rx2?: number,
|
||||
ry2?: number,
|
||||
rx3?: number,
|
||||
ry3?: number,
|
||||
rx4?: number,
|
||||
ry4?: number
|
||||
];
|
||||
|
||||
export class RectR extends GraphicItemBase {
|
||||
/** 圆角属性,四元素数组,每个元素是一个二元素数组,表示这个角的半径,顺序为 左上,右上,右下,左下 */
|
||||
readonly corner: [radiusX: number, radiusY: number][] = [
|
||||
|
@ -107,10 +107,11 @@ export class Text extends RenderItem<ETextEvent> {
|
||||
* 计算字体所占空间,从而确定这个元素的大小
|
||||
*/
|
||||
calBox() {
|
||||
const { width, fontBoundingBoxAscent } = this.measure();
|
||||
const { width, actualBoundingBoxAscent, actualBoundingBoxDescent } =
|
||||
this.measure();
|
||||
this.length = width;
|
||||
this.descent = fontBoundingBoxAscent;
|
||||
this.size(width, fontBoundingBoxAscent);
|
||||
this.descent = actualBoundingBoxAscent;
|
||||
this.size(width, actualBoundingBoxAscent + actualBoundingBoxDescent);
|
||||
}
|
||||
|
||||
patchProp(
|
||||
|
@ -450,9 +450,7 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
||||
return this.target.canvas;
|
||||
}
|
||||
|
||||
hoverElement(element: RenderItem): void {
|
||||
this.target.canvas.style.cursor = element.cursor;
|
||||
}
|
||||
hoverElement(_element: RenderItem): void {}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
|
@ -7,7 +7,12 @@ import {
|
||||
} from '../preset/layer';
|
||||
import type { EnemyCollection } from '@/game/enemy/damage';
|
||||
import {
|
||||
BezierParams,
|
||||
CircleParams,
|
||||
EllipseParams,
|
||||
ILineProperty,
|
||||
LineParams,
|
||||
QuadParams,
|
||||
RectRCircleParams,
|
||||
RectREllipseParams
|
||||
} from '../preset/graphics';
|
||||
@ -40,7 +45,6 @@ export interface BaseProps {
|
||||
id?: string;
|
||||
alpha?: number;
|
||||
composite?: GlobalCompositeOperation;
|
||||
cursor?: string;
|
||||
/**
|
||||
* 定位属性,可以填 `[横坐标,纵坐标,宽度,高度,x锚点,y锚点]`,
|
||||
* 对于横坐标与纵坐标、宽度与高度、x锚点与y锚点,两两一组要么都填,要么都不填
|
||||
@ -132,33 +136,6 @@ export interface GraphicPropsBase extends BaseProps, Partial<ILineProperty> {
|
||||
strokeStyle?: CanvasStyle;
|
||||
}
|
||||
|
||||
export type CircleParams = [radius?: number, start?: number, end?: number];
|
||||
export type EllipseParams = [
|
||||
radiusX?: number,
|
||||
radiusY?: number,
|
||||
start?: number,
|
||||
end?: number
|
||||
];
|
||||
export type LineParams = [x1: number, y1: number, x2: number, y2: number];
|
||||
export type BezierParams = [
|
||||
sx: number,
|
||||
sy: number,
|
||||
cp1x: number,
|
||||
cp1y: number,
|
||||
cp2x: number,
|
||||
cp2y: number,
|
||||
ex: number,
|
||||
ey: number
|
||||
];
|
||||
export type QuadParams = [
|
||||
sx: number,
|
||||
sy: number,
|
||||
cpx: number,
|
||||
cpy: number,
|
||||
ex: number,
|
||||
ey: number
|
||||
];
|
||||
|
||||
export interface RectProps extends GraphicPropsBase {}
|
||||
|
||||
export interface CirclesProps extends GraphicPropsBase {
|
||||
|
255
src/module/render/components/page.tsx
Normal file
255
src/module/render/components/page.tsx
Normal file
@ -0,0 +1,255 @@
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
nextTick,
|
||||
onMounted,
|
||||
ref,
|
||||
SlotsType,
|
||||
VNode,
|
||||
watch
|
||||
} from 'vue';
|
||||
import { SetupComponentOptions } from './types';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { ElementLocator } from '@/core/render';
|
||||
|
||||
/** 圆角矩形页码距离容器的边框大小,与 pageSize 相乘 */
|
||||
const RECT_PAD = 0.1;
|
||||
|
||||
export interface PageProps {
|
||||
/** 共有多少页 */
|
||||
pages: number;
|
||||
/** 页码组件的定位 */
|
||||
loc: ElementLocator;
|
||||
/** 页码的字体大小,默认为 14 */
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
export interface PageExpose {
|
||||
/**
|
||||
* 切换页码
|
||||
* @param page 要切换至的页码数,1 表示第一页
|
||||
*/
|
||||
changePage(page: number): void;
|
||||
}
|
||||
|
||||
type PageSlots = SlotsType<{
|
||||
default: (page: number) => VNode | VNode[];
|
||||
}>;
|
||||
|
||||
const pageProps = {
|
||||
props: ['pages', 'loc', 'pageSize']
|
||||
} satisfies SetupComponentOptions<PageProps, {}, string, PageSlots>;
|
||||
|
||||
export const Page = defineComponent<PageProps, {}, string, PageSlots>(
|
||||
(props, { slots, expose }) => {
|
||||
const nowPage = ref(1);
|
||||
|
||||
// 五个元素的位置
|
||||
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>(new Path2D());
|
||||
const rightArrow = ref<Path2D>(new Path2D());
|
||||
|
||||
const isFirst = computed(() => nowPage.value === 1);
|
||||
const isLast = computed(() => nowPage.value === props.pages);
|
||||
const pageSize = computed(() => props.pageSize ?? 14);
|
||||
const width = computed(() => props.loc[2] ?? 200);
|
||||
const height = computed(() => props.loc[3] ?? 200);
|
||||
const round = computed(() => pageSize.value / 4);
|
||||
const pageFont = computed(() => `${pageSize.value}px normal`);
|
||||
|
||||
// 左右箭头的颜色
|
||||
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 = pageSize.value + 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 = pageSize.value * 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 = pageSize.value * 1.5;
|
||||
const size = pageSize.value;
|
||||
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 = pageSize.value * 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(pageSize, () => {
|
||||
updatePagePos();
|
||||
updateArrowPath();
|
||||
updateRectAndText();
|
||||
});
|
||||
watch(
|
||||
() => props.loc,
|
||||
() => {
|
||||
updatePagePos();
|
||||
updateRectAndText();
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 切换页码
|
||||
*/
|
||||
const changePage = (page: number) => {
|
||||
const target = clamp(page, 1, props.pages);
|
||||
nowPage.value = target;
|
||||
};
|
||||
|
||||
const lastPage = () => {
|
||||
changePage(nowPage.value - 1);
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
changePage(nowPage.value + 1);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
updatePagePos();
|
||||
updateArrowPath();
|
||||
updateRectAndText();
|
||||
});
|
||||
|
||||
expose({ changePage });
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<container loc={props.loc}>
|
||||
<container loc={contentLoc.value}>
|
||||
{slots.default?.(nowPage.value)}
|
||||
</container>
|
||||
<container loc={pageLoc.value}>
|
||||
<container loc={leftLoc.value} onClick={lastPage}>
|
||||
<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}
|
||||
>
|
||||
<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={pageFont.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={pageFont.value}
|
||||
></text>
|
||||
</container>
|
||||
{!isLast.value && (
|
||||
<container
|
||||
loc={rightPageLoc.value}
|
||||
onClick={nextPage}
|
||||
>
|
||||
<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={pageFont.value}
|
||||
></text>
|
||||
</container>
|
||||
)}
|
||||
<container loc={rightLoc.value} onClick={nextPage}>
|
||||
<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>
|
||||
</container>
|
||||
);
|
||||
};
|
||||
},
|
||||
pageProps
|
||||
);
|
@ -3,6 +3,7 @@ import { defineComponent } from 'vue';
|
||||
import { SetupComponentOptions } from '../components';
|
||||
import { ElementLocator } from '@/core/render';
|
||||
import { Scroll } from '../components/scroll';
|
||||
import { Page } from '../components/page';
|
||||
|
||||
export interface ILeftHeroStatus {
|
||||
hp: number;
|
||||
@ -91,7 +92,6 @@ export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>(
|
||||
text={floorName}
|
||||
loc={central(24)}
|
||||
font={font1}
|
||||
cursor="pointer"
|
||||
></text>
|
||||
<text text={s.lv} loc={central(54)} font={font1}></text>
|
||||
<image image={hpIcon} loc={iconLoc(0)}></image>
|
||||
@ -144,17 +144,11 @@ export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>(
|
||||
font={font2}
|
||||
fillStyle="#f88"
|
||||
></text>
|
||||
<text
|
||||
text="技能树"
|
||||
loc={central(396)}
|
||||
font={font1}
|
||||
cursor="pointer"
|
||||
></text>
|
||||
<text text="技能树" loc={central(396)} font={font1}></text>
|
||||
<text
|
||||
text="查看技能"
|
||||
loc={central(428)}
|
||||
font={font1}
|
||||
cursor="pointer"
|
||||
></text>
|
||||
</container>
|
||||
);
|
||||
@ -170,6 +164,21 @@ export const RightStatusBar = defineComponent<StatusBarProps<IRightHeroStatus>>(
|
||||
<container loc={p.loc}>
|
||||
<g-rect loc={[0, 0, p.loc[2], p.loc[3]]} stroke></g-rect>
|
||||
<Scroll loc={[0, 0, 180, 100]}></Scroll>
|
||||
<Page loc={[0, 200, 180, 100]} pages={3}>
|
||||
{(page: number) => {
|
||||
switch (page) {
|
||||
case 1: {
|
||||
return <text text="测试"></text>;
|
||||
}
|
||||
case 2: {
|
||||
return <text text="测试2"></text>;
|
||||
}
|
||||
case 3: {
|
||||
return <text text="测试3"></text>;
|
||||
}
|
||||
}
|
||||
}}
|
||||
</Page>
|
||||
</container>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user