mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-18 11:59:26 +08:00
feat: Icon\winskin完成
This commit is contained in:
parent
d61beada0b
commit
dbe633290e
@ -1,9 +1,18 @@
|
||||
import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
|
||||
import { Sprite } from '../sprite';
|
||||
import { ERenderItemEvent, RenderItem, RenderItemPosition } from '../item';
|
||||
import {
|
||||
ERenderItemEvent,
|
||||
IAnimateFrame,
|
||||
renderEmits,
|
||||
RenderItem,
|
||||
RenderItemPosition
|
||||
} from '../item';
|
||||
import { Transform } from '../transform';
|
||||
import { ElementNamespace, ComponentInternalInstance } from 'vue';
|
||||
import { AutotileRenderable, RenderableData } from '../cache';
|
||||
import { texture } from '../cache';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { logger } from '@/core/common/logger';
|
||||
|
||||
type CanvasStyle = string | CanvasGradient | CanvasPattern;
|
||||
|
||||
@ -207,7 +216,7 @@ export class Comment extends RenderItem {
|
||||
|
||||
export interface EIconEvent extends ERenderItemEvent {}
|
||||
|
||||
export class Icon extends RenderItem<EIconEvent> {
|
||||
export class Icon extends RenderItem<EIconEvent> implements IAnimateFrame {
|
||||
/** 图标id */
|
||||
icon: AllNumbers = 0;
|
||||
/** 帧数 */
|
||||
@ -220,13 +229,69 @@ export class Icon extends RenderItem<EIconEvent> {
|
||||
protected render(
|
||||
canvas: MotaOffscreenCanvas2D,
|
||||
transform: Transform
|
||||
): void {}
|
||||
): void {
|
||||
const ctx = canvas.ctx;
|
||||
const renderable = this.renderable;
|
||||
if (!renderable) return;
|
||||
const [x, y, w, h] = renderable.render[0];
|
||||
const cw = canvas.width;
|
||||
const ch = canvas.height;
|
||||
const frame = this.animate
|
||||
? RenderItem.animatedFrame % renderable.frame
|
||||
: 0;
|
||||
if (this.animate) {
|
||||
if (renderable.autotile) {
|
||||
ctx.drawImage(renderable.image[0], x, y, w, h, 0, 0, cw, ch);
|
||||
} else {
|
||||
ctx.drawImage(renderable.image, x, y, w, h, 0, 0, cw, ch);
|
||||
}
|
||||
} else {
|
||||
const [x1, y1, w1, h1] = renderable.render[frame];
|
||||
if (renderable.autotile) {
|
||||
ctx.drawImage(
|
||||
renderable.image[0],
|
||||
x1,
|
||||
y1,
|
||||
w1,
|
||||
h1,
|
||||
0,
|
||||
0,
|
||||
cw,
|
||||
ch
|
||||
);
|
||||
} else {
|
||||
ctx.drawImage(renderable.image, x1, y1, w1, h1, 0, 0, cw, ch);
|
||||
}
|
||||
this.update(this), renderEmits.addFramer(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置图标
|
||||
* @param id 图标id
|
||||
*/
|
||||
setIcon(id: AllIds | AllNumbers) {}
|
||||
setIcon(id: AllIds | AllNumbers) {
|
||||
const num = typeof id === 'number' ? id : texture.idNumberMap[id];
|
||||
const renderable = texture.getRenderable(num);
|
||||
|
||||
if (!renderable) {
|
||||
//todo: logger.warn()
|
||||
return;
|
||||
} else {
|
||||
this.icon = num;
|
||||
renderable.animate = 0;
|
||||
this.renderable = renderable;
|
||||
this.frame = renderable.frame;
|
||||
}
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新动画帧
|
||||
*/
|
||||
updateFrameAnimate(): void {
|
||||
this.update(this);
|
||||
}
|
||||
|
||||
patchProp(
|
||||
key: string,
|
||||
@ -242,10 +307,12 @@ export class Icon extends RenderItem<EIconEvent> {
|
||||
case 'animate':
|
||||
if (!this.assertType(nextValue, 'boolean', key)) return;
|
||||
this.animate = nextValue;
|
||||
this.update();
|
||||
return;
|
||||
case 'frame':
|
||||
if (!this.assertType(nextValue, 'number', key)) return;
|
||||
this.frame = nextValue;
|
||||
this.update();
|
||||
return;
|
||||
}
|
||||
super.patchProp(key, prevValue, nextValue, namespace, parentComponent);
|
||||
@ -270,19 +337,162 @@ export class Winskin extends RenderItem<EWinskinEvent> {
|
||||
protected render(
|
||||
canvas: MotaOffscreenCanvas2D,
|
||||
transform: Transform
|
||||
): void {}
|
||||
): void {
|
||||
const ctx = canvas.ctx;
|
||||
const img = this.image;
|
||||
const x = 0;
|
||||
const y = 0;
|
||||
const w = canvas.width;
|
||||
const h = canvas.height;
|
||||
const sz = this.borderSize / 32;
|
||||
ctx.drawImage(img, 128, 0, 16, 16, x, y, 16 * sz, 16 * sz);
|
||||
for (var dx = 0; dx < w - 64 * sz; dx += 32 * sz) {
|
||||
ctx.drawImage(
|
||||
img,
|
||||
144,
|
||||
0,
|
||||
32,
|
||||
16,
|
||||
x + dx + 16,
|
||||
y,
|
||||
32 * sz,
|
||||
16 * sz
|
||||
);
|
||||
ctx.drawImage(
|
||||
img,
|
||||
144,
|
||||
48,
|
||||
32,
|
||||
16,
|
||||
x + dx + 16,
|
||||
y + h - 16 * sz,
|
||||
32 * sz,
|
||||
16 * sz
|
||||
);
|
||||
}
|
||||
ctx.drawImage(
|
||||
img,
|
||||
144,
|
||||
0,
|
||||
w - dx - 32,
|
||||
16,
|
||||
x + dx + 16 * sz,
|
||||
y,
|
||||
w - dx - 32 * sz,
|
||||
16 * sz
|
||||
);
|
||||
ctx.drawImage(
|
||||
img,
|
||||
144,
|
||||
48,
|
||||
w - dx - 32,
|
||||
16,
|
||||
x + dx + 16 * sz,
|
||||
y + h - 16 * sz,
|
||||
w - dx - 32 * sz,
|
||||
16 * sz
|
||||
);
|
||||
ctx.drawImage(
|
||||
img,
|
||||
176,
|
||||
0,
|
||||
16,
|
||||
16,
|
||||
x + w - 16 * sz,
|
||||
y,
|
||||
16 * sz,
|
||||
16 * sz
|
||||
);
|
||||
// 左右
|
||||
for (var dy = 0; dy < h - 64 * sz; dy += 32 * sz) {
|
||||
ctx.drawImage(
|
||||
img,
|
||||
128,
|
||||
16,
|
||||
16,
|
||||
32,
|
||||
x,
|
||||
y + dy + 16 * sz,
|
||||
16 * sz,
|
||||
32 * sz
|
||||
);
|
||||
ctx.drawImage(
|
||||
img,
|
||||
176,
|
||||
16,
|
||||
16,
|
||||
32,
|
||||
x + w - 16 * sz,
|
||||
y + dy + 16 * sz,
|
||||
16 * sz,
|
||||
32 * sz
|
||||
);
|
||||
}
|
||||
ctx.drawImage(
|
||||
img,
|
||||
128,
|
||||
16,
|
||||
16,
|
||||
h - dy - 32,
|
||||
x,
|
||||
y + dy + 16 * sz,
|
||||
16 * sz,
|
||||
h - dy - 32 * sz
|
||||
);
|
||||
ctx.drawImage(
|
||||
img,
|
||||
176,
|
||||
16,
|
||||
16,
|
||||
h - dy - 32,
|
||||
x + w - 16 * sz,
|
||||
y + dy + 16 * sz,
|
||||
16 * sz,
|
||||
h - dy - 32 * sz
|
||||
);
|
||||
// 下方
|
||||
ctx.drawImage(
|
||||
img,
|
||||
128,
|
||||
48,
|
||||
16,
|
||||
16,
|
||||
x,
|
||||
y + h - 16 * sz,
|
||||
16 * sz,
|
||||
16 * sz
|
||||
);
|
||||
ctx.drawImage(
|
||||
img,
|
||||
176,
|
||||
48,
|
||||
16,
|
||||
16,
|
||||
x + w - 16 * sz,
|
||||
y + h - 16 * sz,
|
||||
16 * sz,
|
||||
16 * sz
|
||||
);
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置winskin图片
|
||||
* @param image winskin图片
|
||||
*/
|
||||
setImage(image: SizedCanvasImageSource) {}
|
||||
setImage(image: SizedCanvasImageSource) {
|
||||
this.image = image;
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置边框大小
|
||||
* @param size 边框大小
|
||||
*/
|
||||
setBorderSize(size: number) {}
|
||||
setBorderSize(size: number) {
|
||||
this.borderSize = size;
|
||||
this.update();
|
||||
}
|
||||
|
||||
patchProp(
|
||||
key: string,
|
||||
@ -292,6 +502,13 @@ export class Winskin extends RenderItem<EWinskinEvent> {
|
||||
parentComponent?: ComponentInternalInstance | null
|
||||
): void {
|
||||
switch (key) {
|
||||
case 'image':
|
||||
this.setImage(nextValue);
|
||||
return;
|
||||
case 'borderSize':
|
||||
if (!this.assertType(nextValue, 'number', key)) return;
|
||||
this.setBorderSize(nextValue);
|
||||
return;
|
||||
}
|
||||
super.patchProp(key, prevValue, nextValue, namespace, parentComponent);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
} from '../preset/layer';
|
||||
import type { EnemyCollection } from '@/game/enemy/damage';
|
||||
import { ILineProperty } from '../preset/graphics';
|
||||
import { SizedCanvasImageSource } from '../preset';
|
||||
|
||||
export interface CustomProps {
|
||||
_item: (props: BaseProps) => RenderItem;
|
||||
@ -152,6 +153,13 @@ export interface PathProps extends GraphicPropsBase {
|
||||
path?: Path2D;
|
||||
}
|
||||
|
||||
export interface IconProps extends BaseProps {}
|
||||
export interface IconProps extends BaseProps {
|
||||
icon: AllNumbers;
|
||||
frame: number;
|
||||
animate: boolean;
|
||||
}
|
||||
|
||||
export interface WinskinProps extends BaseProps {}
|
||||
export interface WinskinProps extends BaseProps {
|
||||
image: SizedCanvasImageSource;
|
||||
borderSize: number;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user