修复一些类型错误,完成布局插件

This commit is contained in:
unanmed 2023-02-20 13:09:04 +08:00
parent 565dcab6dd
commit 5087b06633
9 changed files with 389 additions and 58 deletions

View File

@ -1,3 +1,5 @@
import { has } from '../utils';
type CanvasStyle = string | CanvasPattern | CanvasGradient;
export class Layout {
@ -18,23 +20,23 @@ export class Layout {
this.ctx = canvas.getContext('2d')!;
}
image(layout: Layout | HTMLCanvasElement | Path2D, type: number): Layout;
image(layout: Layout | CanvasImageSource | Path2D, type: number): this;
image(
layout: Layout | HTMLCanvasElement | Path2D,
layout: Layout | CanvasImageSource | Path2D,
type: number,
x: number,
y: number
): Layout;
): this;
image(
layout: Layout | HTMLCanvasElement | Path2D,
layout: Layout | CanvasImageSource | Path2D,
type: number,
x: number,
y: number,
w: number,
h: number
): Layout;
): this;
image(
layout: Layout | HTMLCanvasElement | Path2D,
layout: Layout | CanvasImageSource | Path2D,
type: number,
sx: number,
sy: number,
@ -44,12 +46,12 @@ export class Layout {
dy: number,
dw: number,
dh: number
): Layout;
): this;
image(
layout: Layout | HTMLCanvasElement | Path2D,
layout: Layout | CanvasImageSource | Path2D,
type: number,
sx?: number,
sy?: number,
sx: number = 0,
sy: number = 0,
sw?: number,
sh?: number,
dx?: number,
@ -57,6 +59,40 @@ export class Layout {
dw?: number,
dh?: number
) {
const img = layout instanceof Layout ? layout.canvas : layout;
const fill = () => {
if (img instanceof Path2D) {
this.ctx.fill(img);
} else {
this.ctx.drawImage(img, sx, sy, sw!, sh!, dx!, dy!, dw!, dh!);
}
};
if (type & Layout.IMAGE) {
// 绘制图片
fill();
}
if (type & Layout.CLEAR) {
// 按照图片清除一个区域
this.ctx.save();
this.ctx.globalCompositeOperation = 'destination-out';
fill();
this.ctx.restore();
}
if (type & Layout.MASK) {
// 蒙版,只显示蒙版内的东西
this.ctx.save();
this.ctx.globalCompositeOperation = 'destination-in';
fill();
this.ctx.restore();
}
return this;
}
/**
*
*/
clear(x: number, y: number, w: number, h: number): this {
this.ctx.clearRect(x, y, w, h);
return this;
}
@ -74,7 +110,9 @@ export class Layout {
x: number,
y: number,
maxWidth?: number
): Layout {
): this {
if (type & Layout.FILL) this.ctx.fillText(str, x, y, maxWidth);
if (type & Layout.STROKE) this.ctx.strokeText(str, x, y, maxWidth);
return this;
}
@ -83,21 +121,25 @@ export class Layout {
* @param path
* @param type
*/
path(path: Path2D, type: number): Layout {
path(path: Path2D, type: number, rule?: CanvasFillRule): this {
if (type & Layout.FILL) this.ctx.fill(path, rule);
if (type & Layout.STROKE) this.ctx.stroke(path);
return this;
}
/**
*
*/
save(): Layout {
save(): this {
this.ctx.save();
return this;
}
/**
* 退
*/
restore(): Layout {
restore(): this {
this.ctx.restore();
return this;
}
@ -105,7 +147,8 @@ export class Layout {
*
* @param style
*/
fillStyle(style: CanvasStyle): Layout {
fillStyle(style: CanvasStyle): this {
this.ctx.fillStyle = style;
return this;
}
@ -113,7 +156,8 @@ export class Layout {
*
* @param style
*/
strokeStyle(style: CanvasStyle): Layout {
strokeStyle(style: CanvasStyle): this {
this.ctx.strokeStyle = style;
return this;
}
@ -121,7 +165,8 @@ export class Layout {
*
* @param align
*/
textAlign(align: CanvasTextAlign): Layout {
textAlign(align: CanvasTextAlign): this {
this.ctx.textAlign = align;
return this;
}
@ -129,7 +174,8 @@ export class Layout {
* 线
* @param align 线
*/
textBaseline(align: CanvasTextBaseline): Layout {
textBaseline(align: CanvasTextBaseline): this {
this.ctx.textBaseline = align;
return this;
}
@ -137,7 +183,8 @@ export class Layout {
*
* @param filter
*/
filter(filter: string): Layout {
filter(filter: string): this {
this.ctx.filter = filter;
return this;
}
@ -145,7 +192,11 @@ export class Layout {
*
* @param shadow
*/
shadow(shadow: Partial<CanvasShadowStyles>): Layout {
shadow(shadow: Partial<CanvasShadowStyles>): this {
for (const [p, v] of Object.entries(shadow)) {
// @ts-ignore
this.ctx[p] = v;
}
return this;
}
@ -153,7 +204,8 @@ export class Layout {
* 线
* @param width
*/
lineWidth(width: number): Layout {
lineWidth(width: number): this {
this.ctx.lineWidth = width;
return this;
}
@ -161,7 +213,8 @@ export class Layout {
* 线
* @param cap 线
*/
lineCap(cap: CanvasLineCap): Layout {
lineCap(cap: CanvasLineCap): this {
this.ctx.lineCap = cap;
return this;
}
@ -169,7 +222,8 @@ export class Layout {
* 线
* @param join 线
*/
lineJoin(join: CanvasLineJoin): Layout {
lineJoin(join: CanvasLineJoin): this {
this.ctx.lineJoin = join;
return this;
}
@ -177,7 +231,8 @@ export class Layout {
*
* @param font
*/
font(font: string): Layout {
font(font: string): this {
this.ctx.font = font;
return this;
}
@ -185,7 +240,8 @@ export class Layout {
*
* @param alpha
*/
alpha(alpha: number): Layout {
alpha(alpha: number): this {
this.ctx.globalAlpha = alpha;
return this;
}
@ -193,7 +249,8 @@ export class Layout {
* 线
* @param dash 线
*/
lineDash(dash: number[]): Layout {
lineDash(dash: number[]): this {
this.ctx.setLineDash(dash);
return this;
}
@ -202,7 +259,8 @@ export class Layout {
* @param x
* @param y
*/
scale(x: number, y: number): Layout {
scale(x: number, y: number): this {
this.ctx.scale(x, y);
return this;
}
@ -210,7 +268,8 @@ export class Layout {
*
* @param rad
*/
rotate(rad: number): Layout {
rotate(rad: number): this {
this.ctx.rotate(rad);
return this;
}
@ -219,7 +278,8 @@ export class Layout {
* @param x
* @param y
*/
translate(x: number, y: number): Layout {
translate(x: number, y: number): this {
this.ctx.translate(x, y);
return this;
}
@ -256,6 +316,8 @@ export class Layout {
e?: number,
f?: number
) {
if (!has(a)) this.ctx.resetTransform();
else this.ctx.transform(a, b!, c!, d!, e!, f!);
return this;
}
@ -263,7 +325,15 @@ export class Layout {
* image的蒙版功能与擦除功能本质上也是通过设置混合方式实现的
* @param value
*/
composite(value: GlobalCompositeOperation): Layout {
composite(value: GlobalCompositeOperation): this {
this.ctx.globalCompositeOperation = value;
return this;
}
/**
*
*/
destroy() {
this.canvas.remove();
}
}

View File

@ -0,0 +1,255 @@
import { Layout } from './layout';
export class LayoutGame extends Layout {
/** 画布id */
id: string;
constructor(
id: string,
x: number,
y: number,
w: number,
h: number,
z: number
) {
const ctx = core.createCanvas(id, x, y, w, h, z);
super(ctx.canvas);
this.id = id;
}
image2(
layout: Layout | CanvasImageSource | Path2D | ImageIds,
type: number
): LayoutGame;
image2(
layout: Layout | CanvasImageSource | Path2D | ImageIds,
type: number,
x: number,
y: number
): LayoutGame;
image2(
layout: Layout | CanvasImageSource | Path2D | ImageIds,
type: number,
x: number,
y: number,
w: number,
h: number
): LayoutGame;
image2(
layout: Layout | CanvasImageSource | Path2D | ImageIds,
type: number,
sx: number,
sy: number,
sw: number,
sh: number,
dx: number,
dy: number,
dw: number,
dh: number
): LayoutGame;
image2(
layout: Layout | CanvasImageSource | Path2D | ImageIds,
type: number,
sx?: number,
sy?: number,
sw?: number,
sh?: number,
dx?: number,
dy?: number,
dw?: number,
dh?: number
): this {
const img =
typeof layout === 'string'
? core.material.images.images[layout]
: layout;
this.image(img, type, sx!, sy!, sw!, sh!, dx!, dy!, dw!, dh!);
return this;
}
/**
*
* @param id id
* @param x
* @param y
* @param w
* @param h
* @param frame
*/
icon(
id: AllIds,
x: number,
y: number,
w?: number,
h?: number,
frame?: number
): this {
core.drawIcon(this.ctx, id, x, y, w, h, frame);
return this;
}
/**
* WindowSkin
* @param direction
*/
winskin(
background: any,
x: number,
y: number,
w: number,
h: number,
direction?: 'up' | 'down',
px?: number,
py?: number
): this {
core.drawWindowSkin(
background,
this.ctx,
x,
y,
w,
h,
direction,
px,
py
);
return this;
}
/**
*
* @param x1
* @param y1
* @param x2
* @param y2
*/
arrow(x1: number, y1: number, x2: number, y2: number): this {
core.drawArrow(this.ctx, x1, y1, x2, y2);
return this;
}
/**
* 线
*/
line(x1: number, y1: number, x2: number, y2: number): this {
this.ctx.beginPath();
this.ctx.moveTo(x1, y1);
this.ctx.lineTo(x2, y2);
this.ctx.stroke();
return this;
}
/**
*
* @param type
* @param start
* @param end
* @param anticlockwise
*/
arc(
type: number,
x: number,
y: number,
r: number,
start: number,
end: number,
anticlockwise: boolean = false
): this {
this.ctx.beginPath();
this.ctx.arc(x, y, r, start, end, anticlockwise);
this.draw(type);
return this;
}
/**
*
* @param type
*/
circle(type: number, x: number, y: number, r: number): this {
return this.arc(type, x, y, r, 0, Math.PI * 2);
}
/**
*
*/
ellipse(
type: number,
x: number,
y: number,
a: number,
b: number,
rotation: number = 0,
start: number = 0,
end: number = Math.PI * 2,
anticlockwise: boolean = false
): this {
this.ctx.beginPath();
this.ctx.ellipse(x, y, a, b, rotation, start, end, anticlockwise);
this.draw(type);
return this;
}
/**
*
* @param type
* @param nodes
* @param close
*/
polygon(type: number, nodes: LocArr[], close: boolean = true): this {
this.ctx.beginPath();
this.ctx.moveTo(nodes[0][0], nodes[0][1]);
for (let i = 1; i < nodes.length; i++) {
this.ctx.lineTo(nodes[i][0], nodes[i][1]);
}
if (close) this.ctx.closePath();
this.draw(type);
return this;
}
/**
*
*/
rect(type: number, x: number, y: number, w: number, h: number): this {
if (type & Layout.FILL) this.ctx.fillRect(x, y, w, h);
if (type & Layout.STROKE) this.ctx.strokeRect(x, y, w, h);
return this;
}
/**
*
*/
roundRect(
type: number,
x: number,
y: number,
w: number,
h: number,
r: number
) {
this.ctx.beginPath();
this.ctx.moveTo(x + r, y);
this.ctx.lineTo(x + w - r, y);
this.ctx.quadraticCurveTo(x + w, y, x + w, y + r);
this.ctx.lineTo(x + w, y + h - r);
this.ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
this.ctx.lineTo(x + r, y + h);
this.ctx.quadraticCurveTo(x, y + h, x, y + h - r);
this.ctx.lineTo(x, y + r);
this.ctx.quadraticCurveTo(x, y, x + r, y);
this.ctx.closePath();
this.draw(type);
}
/**
*
*/
destroy() {
core.deleteCanvas(this.id);
}
private draw(type: number) {
if (type & Layout.FILL) this.ctx.fill();
if (type & Layout.STROKE) this.ctx.stroke();
}
}

17
src/types/core.d.ts vendored
View File

@ -528,7 +528,7 @@ type MainDom = {
* context
*/
statusCanvasCtx: CanvasRenderingContext2D;
} & {
[key: string]: HTMLElement;
};
@ -806,7 +806,7 @@ type CoreStatusBarElements = {
*
*/
readonly image: Record<string, HTMLImageElement>;
} & {
readonly [key: string]: HTMLElement;
};
@ -1079,7 +1079,7 @@ interface Core extends Pick<Main, CoreDataFromMain> {
* @param _this
* @param params
*/
doFunc<F extends Function>(
doFunc<F extends (...args: any) => any>(
func: F,
_this: any,
...params: Parameters<F>
@ -1210,7 +1210,16 @@ interface Main extends MainData {
/**
*
*/
readonly materials: Materials;
readonly materials: [
'animates',
'enemys',
'items',
'npcs',
'terrains',
'enemy48',
'npc48',
'icons'
];
/**
* project目录下的文件

5
src/types/data.d.ts vendored
View File

@ -24,6 +24,11 @@ interface MainData {
*/
readonly bgms: BgmIds[];
/**
*
*/
readonly images: ImageIds[];
/**
*
*/

View File

@ -309,7 +309,7 @@ interface ActionStatusData {
/**
*
*/
type: EventType;
type: string;
/**
*

18
src/types/map.d.ts vendored
View File

@ -266,7 +266,7 @@ interface ResolvedFloor<T extends FloorIds = FloorIds> extends FloorBase<T> {
eachArrive?: MotaEvent;
}
interface BlockInfo<T extends AllNumbers = AllNumbers> {
interface BlockInfo<T extends keyof NumberToId = keyof NumberToId> {
/**
*
*/
@ -421,16 +421,6 @@ interface DrawThumbnailConfig {
*/
inFlyMap: boolean;
/**
*
*/
x: number;
/**
*
*/
y: number;
/**
*
*/
@ -537,7 +527,7 @@ interface Maps {
*
* @param number
*/
getBlockByNumber<T extends AllNumbers>(number: T): Block<T>;
getBlockByNumber<T extends keyof NumberToId>(number: T): Block<T>;
/**
* ID获得图块
@ -634,7 +624,7 @@ interface Maps {
* @param mapArr
* @param floorId id
*/
decompressMap(mapArr?: number[][], floorId: FloorIds): number[][];
decompressMap(mapArr?: number[][], floorId?: FloorIds): number[][];
/**
* 便
@ -1021,7 +1011,7 @@ interface Maps {
*
* @param block id
*/
getBlockInfo<T extends AllNumbers>(
getBlockInfo<T extends keyof NumberToId>(
block?: Block<T> | NumberToId[T] | T
): BlockInfo<T>;

View File

@ -207,7 +207,7 @@ interface PluginUis {
readonly shopOpened: Ref<boolean>;
/** ui栈 */
readonly uiStack: Ref<Component[]>;
readonly uiStack: Ref<any[]>;
/**
*
@ -237,7 +237,7 @@ interface PluginUse {
fn: DragFn,
ondown?: DragFn,
onUp?: (e: MouseEvent | TouchEvent) => void,
global: boolean = false
global?: boolean
): void;
/**

12
src/types/status.d.ts vendored
View File

@ -591,7 +591,7 @@ interface InitGameStatus {
/**
*
*/
played: false;
played: boolean;
/**
*
@ -648,7 +648,7 @@ interface InitGameStatus {
/**
*
*/
lockControl: false;
lockControl: boolean;
/**
* libs翻西西
@ -718,7 +718,9 @@ interface InitGameStatus {
/**
*
*/
globalAnimateObjs: Block<AllIdsOf<Exclude<AnimatableCls, 'autotile'>>>[];
globalAnimateObjs: Block<
IdToNumber[AllIdsOf<Exclude<AnimatableCls, 'autotile'>>]
>[];
/**
*
@ -733,7 +735,7 @@ interface InitGameStatus {
/**
*
*/
autotileAnimateObjs: Block<AllIdsOf<'autotile'>>[];
autotileAnimateObjs: Block<IdToNumber[AllIdsOf<'autotile'>]>[];
/**
* 便
@ -769,7 +771,7 @@ interface InitGameStatus {
*
*/
number2block: {
[P in AllNumbers]: Block<P>;
[P in keyof NumberToId]: Block<P>;
};
/**

4
src/types/util.d.ts vendored
View File

@ -843,7 +843,7 @@ type DeepRequired<T> = {
* 使
*/
type Writable<T> = {
-readonly [P in keyof T]: P[T];
-readonly [P in keyof T]: T[P];
};
/**
@ -889,4 +889,4 @@ type NonObjectOf<T> = SelectType<T, NonObject>;
*/
type EndsWith<T extends string> = `${string}${T}`;
type KeyExcludesUnderline<T> = Excluede<keyof T, `_${string}`>;
type KeyExcludesUnderline<T> = Exclude<keyof T, `_${string}`>;