处理图形Assets加载结构
添加风机图形和绘制 初步添加动画功能(不稳定,可能会有不兼容的修改)
This commit is contained in:
parent
fbc3a70cda
commit
f649cb4a3d
@ -5,6 +5,7 @@ package graphicData;
|
||||
message RtssGraphicStorage {
|
||||
Canvas canvas = 1;
|
||||
repeated Link links = 2;
|
||||
repeated IscsFan iscsFans = 3;
|
||||
}
|
||||
|
||||
message Canvas {
|
||||
@ -61,3 +62,8 @@ message Link {
|
||||
string lineColor = 6; // 线色
|
||||
repeated Point points = 7; // 点坐标列表
|
||||
}
|
||||
|
||||
message IscsFan {
|
||||
CommonInfo common = 1;
|
||||
string code = 2;
|
||||
}
|
||||
|
87
src/examples/app/graphics/BaseGraphicData.ts
Normal file
87
src/examples/app/graphics/BaseGraphicData.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import {
|
||||
ChildTransform,
|
||||
GraphicData,
|
||||
GraphicTransform,
|
||||
IChildTransform,
|
||||
IGraphicTransform,
|
||||
} from 'src/jlgraphic';
|
||||
import { toStorageTransform } from '..';
|
||||
import { graphicData } from '../protos/draw_data_storage';
|
||||
|
||||
export interface ICommonInfo {
|
||||
id: string;
|
||||
graphicType: string;
|
||||
transform: IGraphicTransform;
|
||||
childTransforms: IChildTransform[];
|
||||
}
|
||||
|
||||
export interface IProtoGraphicData extends pb_1.Message {
|
||||
common: ICommonInfo;
|
||||
code: string;
|
||||
}
|
||||
|
||||
export abstract class BaseGraphicData implements GraphicData {
|
||||
_data: IProtoGraphicData;
|
||||
constructor(data: IProtoGraphicData) {
|
||||
this._data = data;
|
||||
}
|
||||
|
||||
getData<D extends IProtoGraphicData>(): D {
|
||||
return this._data as D;
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this._data.common.id;
|
||||
}
|
||||
set id(v: string) {
|
||||
this._data.common.id = v;
|
||||
}
|
||||
get graphicType(): string {
|
||||
return this._data.common.graphicType;
|
||||
}
|
||||
set graphicType(v: string) {
|
||||
this._data.common.graphicType = v;
|
||||
}
|
||||
get transform(): GraphicTransform {
|
||||
return GraphicTransform.from(this._data.common.transform);
|
||||
}
|
||||
set transform(v: GraphicTransform) {
|
||||
this._data.common.transform = toStorageTransform(v);
|
||||
}
|
||||
get childTransforms(): ChildTransform[] | undefined {
|
||||
const cts: ChildTransform[] = [];
|
||||
if (this._data.common.childTransforms) {
|
||||
this._data.common.childTransforms.forEach((ct) => {
|
||||
cts.push(ChildTransform.from(ct));
|
||||
});
|
||||
}
|
||||
return cts;
|
||||
}
|
||||
set childTransforms(v: ChildTransform[] | undefined) {
|
||||
if (v) {
|
||||
const cts: graphicData.ChildTransform[] = [];
|
||||
v.forEach((ct) =>
|
||||
cts.push(
|
||||
new graphicData.ChildTransform({
|
||||
...ct,
|
||||
transform: toStorageTransform(ct.transform),
|
||||
})
|
||||
)
|
||||
);
|
||||
this._data.common.childTransforms = cts;
|
||||
} else {
|
||||
this._data.common.childTransforms = [];
|
||||
}
|
||||
}
|
||||
|
||||
clone(): GraphicData {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
copyFrom(gd: BaseGraphicData): void {
|
||||
pb_1.Message.copyInto(gd._data, this._data);
|
||||
}
|
||||
eq(other: BaseGraphicData): boolean {
|
||||
return pb_1.Message.equals(this._data, other._data);
|
||||
}
|
||||
}
|
38
src/examples/app/graphics/IscsFanInteraction.ts
Normal file
38
src/examples/app/graphics/IscsFanInteraction.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { IIscsFanData } from 'src/graphics/iscs-fan/IscsFan';
|
||||
import { graphicData } from '../protos/draw_data_storage';
|
||||
import { BaseGraphicData } from './BaseGraphicData';
|
||||
|
||||
export class IscsFanData extends BaseGraphicData implements IIscsFanData {
|
||||
constructor(data?: graphicData.IscsFan) {
|
||||
let fan;
|
||||
if (data) {
|
||||
fan = data;
|
||||
} else {
|
||||
fan = new graphicData.IscsFan({
|
||||
common: new graphicData.CommonInfo(),
|
||||
});
|
||||
}
|
||||
super(fan);
|
||||
}
|
||||
|
||||
public get data(): graphicData.IscsFan {
|
||||
return this.getData<graphicData.IscsFan>();
|
||||
}
|
||||
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
clone(): IscsFanData {
|
||||
return new IscsFanData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: IscsFanData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: IscsFanData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
@ -1,21 +1,26 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { IPointData } from 'pixi.js';
|
||||
import { ILinkData } from 'src/graphics/link/Link';
|
||||
import { ChildTransform, GraphicTransform } from 'src/jlgraphic';
|
||||
import { toStorageTransform } from '..';
|
||||
import { graphicData } from '../protos/draw_data_storage';
|
||||
import { BaseGraphicData } from './BaseGraphicData';
|
||||
|
||||
export class LinkData implements ILinkData {
|
||||
data: graphicData.Link;
|
||||
export class LinkData extends BaseGraphicData implements ILinkData {
|
||||
constructor(data?: graphicData.Link) {
|
||||
if (data) {
|
||||
this.data = data;
|
||||
} else {
|
||||
this.data = new graphicData.Link({
|
||||
let link;
|
||||
if (!data) {
|
||||
link = new graphicData.Link({
|
||||
common: new graphicData.CommonInfo(),
|
||||
});
|
||||
} else {
|
||||
link = data;
|
||||
}
|
||||
super(link);
|
||||
}
|
||||
|
||||
public get data(): graphicData.Link {
|
||||
return this.getData<graphicData.Link>();
|
||||
}
|
||||
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
@ -63,47 +68,4 @@ export class LinkData implements ILinkData {
|
||||
eq(other: LinkData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
get id(): string {
|
||||
return this.data.common.id;
|
||||
}
|
||||
set id(v: string) {
|
||||
this.data.common.id = v;
|
||||
}
|
||||
get graphicType(): string {
|
||||
return this.data.common.graphicType;
|
||||
}
|
||||
set graphicType(v: string) {
|
||||
this.data.common.graphicType = v;
|
||||
}
|
||||
get transform(): GraphicTransform {
|
||||
return GraphicTransform.from(this.data.common.transform);
|
||||
}
|
||||
set transform(v: GraphicTransform) {
|
||||
this.data.common.transform = toStorageTransform(v);
|
||||
}
|
||||
get childTransforms(): ChildTransform[] | undefined {
|
||||
const cts: ChildTransform[] = [];
|
||||
if (this.data.common.childTransforms) {
|
||||
this.data.common.childTransforms.forEach((ct) => {
|
||||
cts.push(ChildTransform.from(ct));
|
||||
});
|
||||
}
|
||||
return cts;
|
||||
}
|
||||
set childTransforms(v: ChildTransform[] | undefined) {
|
||||
if (v) {
|
||||
const cts: graphicData.ChildTransform[] = [];
|
||||
v.forEach((ct) =>
|
||||
cts.push(
|
||||
new graphicData.ChildTransform({
|
||||
...ct,
|
||||
transform: toStorageTransform(ct.transform),
|
||||
})
|
||||
)
|
||||
);
|
||||
this.data.common.childTransforms = cts;
|
||||
} else {
|
||||
this.data.common.childTransforms = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,9 @@ import {
|
||||
} from 'src/jlgraphic';
|
||||
import { LinkData } from './graphics/LinkInteraction';
|
||||
import { graphicData } from './protos/draw_data_storage';
|
||||
import { IscsFanDraw } from 'src/graphics/iscs-fan/IscsFanDrawAssistant';
|
||||
import { IscsFanData } from './graphics/IscsFanInteraction';
|
||||
import { IscsFan } from 'src/graphics/iscs-fan/IscsFan';
|
||||
|
||||
export function fromStoragePoint(p: graphicData.Point): Point {
|
||||
return new Point(p.x, p.y);
|
||||
@ -46,13 +49,15 @@ export function toStorageTransform(
|
||||
export function initDrawApp(app: JlDrawApp) {
|
||||
app.setOptions({
|
||||
drawAssistants: [
|
||||
new LinkDraw(app, {
|
||||
newData: () => {
|
||||
return new LinkData();
|
||||
},
|
||||
new LinkDraw(app, () => {
|
||||
return new LinkData();
|
||||
}),
|
||||
new IscsFanDraw(app, () => {
|
||||
return new IscsFanData();
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyL',
|
||||
@ -61,6 +66,25 @@ export function initDrawApp(app: JlDrawApp) {
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyF',
|
||||
onPress: () => {
|
||||
app.interactionPlugin(IscsFan.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyR',
|
||||
onPress: () => {
|
||||
app.queryStore.queryByType<IscsFan>(IscsFan.Type).forEach((fan) => {
|
||||
fan._run = !fan._run;
|
||||
fan.repaint();
|
||||
});
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyS',
|
||||
@ -86,6 +110,9 @@ export function saveDrawDatas(app: JlDrawApp) {
|
||||
if (Link.Type === g.type) {
|
||||
const linkData = (g as Link).saveData();
|
||||
storage.links.push((linkData as LinkData).data);
|
||||
} else if (IscsFan.Type === g.type) {
|
||||
const IscsFanData = (g as IscsFan).saveData();
|
||||
storage.iscsFans.push((IscsFanData as IscsFanData).data);
|
||||
}
|
||||
});
|
||||
const base64 = fromUint8Array(storage.serialize());
|
||||
@ -96,6 +123,7 @@ export function saveDrawDatas(app: JlDrawApp) {
|
||||
export function loadDrawDatas(app: GraphicApp) {
|
||||
// localStorage.removeItem(StorageKey);
|
||||
const base64 = localStorage.getItem(StorageKey);
|
||||
// console.log('加载数据', base64);
|
||||
if (base64) {
|
||||
const storage = graphicData.RtssGraphicStorage.deserialize(
|
||||
toUint8Array(base64)
|
||||
@ -106,6 +134,9 @@ export function loadDrawDatas(app: GraphicApp) {
|
||||
storage.links.forEach((link) => {
|
||||
datas.push(new LinkData(link));
|
||||
});
|
||||
storage.iscsFans.forEach((fan) => {
|
||||
datas.push(new IscsFanData(fan));
|
||||
});
|
||||
app.loadGraphic(datas);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
91
src/graphics/iscs-fan/IscsFan.ts
Normal file
91
src/graphics/iscs-fan/IscsFan.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import {
|
||||
GraphicAnimation,
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
} from 'src/jlgraphic';
|
||||
import fanBorder from './assets/fan-border.png';
|
||||
import fanBlue from './assets/fan-blue.png';
|
||||
import fanGray from './assets/fan-gray.png';
|
||||
import fanGreen from './assets/fan-green.png';
|
||||
import fanRed from './assets/fan-red.png';
|
||||
import fanYellow from './assets/fan-yellow.png';
|
||||
import { Assets, Sprite, Texture } from 'pixi.js';
|
||||
|
||||
interface FanTextures {
|
||||
border: Texture;
|
||||
blue: Texture;
|
||||
gray: Texture;
|
||||
green: Texture;
|
||||
red: Texture;
|
||||
yellow: Texture;
|
||||
}
|
||||
|
||||
export interface IIscsFanData extends GraphicData {
|
||||
get code(): string;
|
||||
set code(v: string);
|
||||
}
|
||||
|
||||
export class IscsFan extends JlGraphic {
|
||||
static Type = 'IscsFan';
|
||||
_border: Sprite;
|
||||
_fan: Sprite;
|
||||
fanTextures: FanTextures;
|
||||
_run = false;
|
||||
|
||||
constructor(fanTextures: FanTextures) {
|
||||
super(IscsFan.Type);
|
||||
this.fanTextures = fanTextures;
|
||||
this._border = new Sprite();
|
||||
this._border.texture = this.fanTextures.border;
|
||||
this._border.anchor.set(0.5);
|
||||
this._fan = new Sprite();
|
||||
this._fan.texture = this.fanTextures.gray;
|
||||
this._fan.anchor.set(0.5);
|
||||
this.addChild(this._border);
|
||||
this.addChild(this._fan);
|
||||
}
|
||||
doRepaint(): void {
|
||||
if (this._run) {
|
||||
this._fan.texture = this.fanTextures.green;
|
||||
// 动画
|
||||
this.addAnimation(
|
||||
GraphicAnimation.init({
|
||||
name: 'fan_run',
|
||||
run: (dt: number) => {
|
||||
this._fan.angle = (this._fan.angle + dt * 3) % 360;
|
||||
},
|
||||
}).resume()
|
||||
);
|
||||
} else {
|
||||
this.removeAnimation('fan_run');
|
||||
this._fan.rotation = 0;
|
||||
this._fan.texture = this.fanTextures.gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class IscsFanTemplate extends JlGraphicTemplate<IscsFan> {
|
||||
fanTextures?: FanTextures;
|
||||
constructor() {
|
||||
super(IscsFan.Type);
|
||||
}
|
||||
new(): IscsFan {
|
||||
if (this.fanTextures) {
|
||||
return new IscsFan(this.fanTextures);
|
||||
}
|
||||
throw new Error('资源未加载/加载失败');
|
||||
}
|
||||
async loadAssets(): Promise<FanTextures> {
|
||||
Assets.addBundle('iscsFan', {
|
||||
border: fanBorder,
|
||||
blue: fanBlue,
|
||||
gray: fanGray,
|
||||
green: fanGreen,
|
||||
red: fanRed,
|
||||
yellow: fanYellow,
|
||||
});
|
||||
this.fanTextures = await Assets.loadBundle('iscsFan');
|
||||
return this.fanTextures as FanTextures;
|
||||
}
|
||||
}
|
55
src/graphics/iscs-fan/IscsFanDrawAssistant.ts
Normal file
55
src/graphics/iscs-fan/IscsFanDrawAssistant.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { FederatedMouseEvent, Point } from 'pixi.js';
|
||||
import {
|
||||
GraphicDrawAssistant,
|
||||
GraphicTransform,
|
||||
JlDrawApp,
|
||||
} from 'src/jlgraphic';
|
||||
import { IIscsFanData, IscsFan, IscsFanTemplate } from './IscsFan';
|
||||
|
||||
export class IscsFanDraw extends GraphicDrawAssistant<
|
||||
IscsFanTemplate,
|
||||
IIscsFanData
|
||||
> {
|
||||
_iscsFan: IscsFan | null = null;
|
||||
|
||||
constructor(app: JlDrawApp, createData: () => IIscsFanData) {
|
||||
const template = new IscsFanTemplate();
|
||||
super(app, template, createData, IscsFan.Type, '');
|
||||
}
|
||||
|
||||
bind(): void {
|
||||
super.bind();
|
||||
if (!this._iscsFan) {
|
||||
this._iscsFan = this.graphicTemplate.new();
|
||||
this.container.addChild(this._iscsFan);
|
||||
}
|
||||
}
|
||||
|
||||
public get iscsFan(): IscsFan {
|
||||
if (!this._iscsFan) {
|
||||
throw new Error('风机绘制逻辑异常');
|
||||
}
|
||||
return this._iscsFan;
|
||||
}
|
||||
|
||||
redraw(cp: Point): void {
|
||||
this.iscsFan.position.copyFrom(cp);
|
||||
}
|
||||
onLeftUp(e: FederatedMouseEvent): void {
|
||||
this.iscsFan.position.copyFrom(this.toCanvasCoordinates(e.global));
|
||||
this.createAndStore(false);
|
||||
}
|
||||
onRightUp(): void {
|
||||
this.finish();
|
||||
}
|
||||
prepareData(data: IIscsFanData): boolean {
|
||||
// 变换设置必须新建变换赋值,不能直接修改变换数据
|
||||
const transfrom = GraphicTransform.default();
|
||||
transfrom.position = this.iscsFan.position.clone();
|
||||
data.transform = transfrom;
|
||||
return true;
|
||||
}
|
||||
onEsc(): void {
|
||||
this.finish();
|
||||
}
|
||||
}
|
BIN
src/graphics/iscs-fan/assets/fan-blue.png
Normal file
BIN
src/graphics/iscs-fan/assets/fan-blue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
BIN
src/graphics/iscs-fan/assets/fan-border.png
Normal file
BIN
src/graphics/iscs-fan/assets/fan-border.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
src/graphics/iscs-fan/assets/fan-gray.png
Normal file
BIN
src/graphics/iscs-fan/assets/fan-gray.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
BIN
src/graphics/iscs-fan/assets/fan-green.png
Normal file
BIN
src/graphics/iscs-fan/assets/fan-green.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
src/graphics/iscs-fan/assets/fan-red.png
Normal file
BIN
src/graphics/iscs-fan/assets/fan-red.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
BIN
src/graphics/iscs-fan/assets/fan-yellow.png
Normal file
BIN
src/graphics/iscs-fan/assets/fan-yellow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
@ -34,8 +34,7 @@ export interface ILinkDrawOptions {
|
||||
newData: () => ILinkData;
|
||||
}
|
||||
|
||||
export class LinkDraw extends GraphicDrawAssistant<LinkTemplate> {
|
||||
_options: ILinkDrawOptions;
|
||||
export class LinkDraw extends GraphicDrawAssistant<LinkTemplate, ILinkData> {
|
||||
points: Point[] = [];
|
||||
graphic: Graphics = new Graphics();
|
||||
|
||||
@ -60,18 +59,14 @@ export class LinkDraw extends GraphicDrawAssistant<LinkTemplate> {
|
||||
},
|
||||
});
|
||||
|
||||
constructor(app: JlDrawApp, options: ILinkDrawOptions) {
|
||||
super(app, new LinkTemplate(), Link.Type, '轨道Link');
|
||||
constructor(app: JlDrawApp, createData: () => ILinkData) {
|
||||
super(app, new LinkTemplate(), createData, Link.Type, '轨道Link');
|
||||
this.container.addChild(this.graphic);
|
||||
this._options = options;
|
||||
this.graphicTemplate.curve = true;
|
||||
|
||||
new LinkPointsEditPlugin(app);
|
||||
}
|
||||
|
||||
newLinkData(): ILinkData {
|
||||
return this._options.newData();
|
||||
}
|
||||
bind(): void {
|
||||
super.bind();
|
||||
this.app.addKeyboardListener(this.keyqListener, this.keyzListener);
|
||||
@ -158,28 +153,25 @@ export class LinkDraw extends GraphicDrawAssistant<LinkTemplate> {
|
||||
}
|
||||
}
|
||||
}
|
||||
prepareData(): ILinkData | null {
|
||||
prepareData(data: ILinkData): boolean {
|
||||
const template = this.graphicTemplate;
|
||||
if (
|
||||
(!template.curve && this.points.length < 2) ||
|
||||
(template.curve && this.points.length < 4)
|
||||
) {
|
||||
console.log('Link绘制因点不够取消绘制');
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
if (template.curve) {
|
||||
this.points.pop();
|
||||
}
|
||||
const data = this.newLinkData();
|
||||
data.id = this.nextId();
|
||||
data.graphicType = Link.Type;
|
||||
data.curve = template.curve;
|
||||
data.segmentsCount = template.segmentsCount;
|
||||
data.points = this.points;
|
||||
data.lineWidth = template.lineWidth;
|
||||
data.lineColor = template.lineColor;
|
||||
data.segmentsCount = template.segmentsCount;
|
||||
return data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
0
src/graphics/signal/Signal.ts
Normal file
0
src/graphics/signal/Signal.ts
Normal file
@ -10,7 +10,7 @@ import {
|
||||
Point,
|
||||
} from 'pixi.js';
|
||||
import { GraphicIdGenerator } from '../core/IdGenerator';
|
||||
import { JlGraphic, GraphicData, GraphicTemplate } from '../core/JlGraphic';
|
||||
import { GraphicData, GraphicTemplate, JlGraphic } from '../core/JlGraphic';
|
||||
import { BoundsGraphic, TransformPoints } from '../graphic';
|
||||
import { JlOperation } from '../operation/JlOperation';
|
||||
import {
|
||||
@ -35,33 +35,40 @@ import {
|
||||
* 图形绘制助手
|
||||
*/
|
||||
export abstract class GraphicDrawAssistant<
|
||||
GT extends GraphicTemplate
|
||||
GT extends GraphicTemplate,
|
||||
GD extends GraphicData
|
||||
> extends AppInteractionPlugin {
|
||||
_isDrawAssistant = true;
|
||||
app: JlDrawApp;
|
||||
type: string; // 图形对象类型
|
||||
description?: string; // 描述
|
||||
icon: string; // 界面显示的图标
|
||||
container: Container = new Container();
|
||||
graphicTemplate: GT;
|
||||
createGraphicData: () => GD;
|
||||
|
||||
escListener: KeyListener = new KeyListener({
|
||||
value: 'Escape',
|
||||
onPress: () => {
|
||||
this.createAndStore(true);
|
||||
onRelease: () => {
|
||||
this.onEsc();
|
||||
},
|
||||
});
|
||||
|
||||
onEsc() {
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
constructor(
|
||||
graphicApp: JlDrawApp,
|
||||
graphicTemplate: GT,
|
||||
createGraphicData: () => GD,
|
||||
icon: string,
|
||||
description?: string
|
||||
) {
|
||||
super(graphicTemplate.type, graphicApp);
|
||||
this.app = graphicApp;
|
||||
this.graphicTemplate = graphicTemplate;
|
||||
this.type = graphicTemplate.type;
|
||||
this.graphicTemplate = graphicTemplate;
|
||||
this.createGraphicData = createGraphicData;
|
||||
this.icon = icon;
|
||||
this.description = description;
|
||||
this.app.registerGraphicTemplates(this.graphicTemplate);
|
||||
@ -131,7 +138,7 @@ export abstract class GraphicDrawAssistant<
|
||||
*/
|
||||
abstract redraw(cp: Point): void;
|
||||
|
||||
abstract prepareData(): GraphicData | null;
|
||||
abstract prepareData(data: GD): boolean;
|
||||
|
||||
toCanvasCoordinates(p: Point): Point {
|
||||
return this.app.toCanvasCoordinates(p);
|
||||
@ -148,8 +155,10 @@ export abstract class GraphicDrawAssistant<
|
||||
* 创建并添加到图形App
|
||||
*/
|
||||
createAndStore(finish: boolean): JlGraphic | null {
|
||||
const data = this.prepareData();
|
||||
if (!data) {
|
||||
const data = this.createGraphicData();
|
||||
data.id = this.nextId();
|
||||
data.graphicType = this.graphicTemplate.type;
|
||||
if (!this.prepareData(data)) {
|
||||
if (finish) {
|
||||
this.finish();
|
||||
}
|
||||
@ -158,7 +167,6 @@ export abstract class GraphicDrawAssistant<
|
||||
const template = this.graphicTemplate;
|
||||
const g = template.new();
|
||||
g.loadData(data);
|
||||
g.id = this.nextId();
|
||||
this.storeGraphic(g);
|
||||
if (finish) {
|
||||
this.finish(g);
|
||||
@ -183,11 +191,13 @@ export enum DrawAppEvent {
|
||||
propertiesupdate = 'propertiesupdate', // 图形对象数据变更
|
||||
}
|
||||
|
||||
export type DrawAssistant = GraphicDrawAssistant<GraphicTemplate, GraphicData>;
|
||||
|
||||
export interface IDrawAppOptions {
|
||||
/**
|
||||
* 绘制辅助交互插件
|
||||
*/
|
||||
drawAssistants: GraphicDrawAssistant<GraphicTemplate>[];
|
||||
drawAssistants: DrawAssistant[];
|
||||
}
|
||||
|
||||
export type DrawAppOptions = GraphicAppOptions & IDrawAppOptions;
|
||||
@ -212,7 +222,7 @@ export class JlDrawApp extends GraphicApp {
|
||||
fontName: 'coordinates',
|
||||
});
|
||||
|
||||
drawAssistants: GraphicDrawAssistant<GraphicTemplate>[] = [];
|
||||
drawAssistants: DrawAssistant[] = [];
|
||||
|
||||
selectedData: GraphicData | ICanvasProperties | null;
|
||||
|
||||
@ -244,14 +254,14 @@ export class JlDrawApp extends GraphicApp {
|
||||
});
|
||||
}
|
||||
|
||||
getDrawAssistant(graphicType: string): GraphicDrawAssistant<GraphicTemplate> {
|
||||
getDrawAssistant<DA extends DrawAssistant>(graphicType: string): DA {
|
||||
const sda = this.drawAssistants
|
||||
.filter((da) => da.type === graphicType)
|
||||
.pop();
|
||||
if (!sda) {
|
||||
throw new Error(`未找到图形绘制助手: ${graphicType}`);
|
||||
}
|
||||
return sda;
|
||||
return sda as DA;
|
||||
}
|
||||
|
||||
private appDragRecord() {
|
||||
|
@ -432,6 +432,16 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
|
||||
tool.resume();
|
||||
// 视口移动插件
|
||||
ViewportMovePlugin.new(this);
|
||||
|
||||
this.app.ticker.add((dt: number) => {
|
||||
this.queryStore.getAllGraphics().forEach((g) => {
|
||||
g.animationMap.forEach((animation) => {
|
||||
if (animation.running) {
|
||||
animation.run(dt);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setOptions(options: GraphicAppOptions) {
|
||||
@ -458,8 +468,6 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
|
||||
registerGraphicTemplates(...graphicTemplates: GraphicTemplate[]) {
|
||||
graphicTemplates.forEach((graphicTemplate) => {
|
||||
this.graphicTemplateMap.set(graphicTemplate.type, graphicTemplate);
|
||||
// 加载资源
|
||||
graphicTemplate.loadAsserts();
|
||||
});
|
||||
}
|
||||
|
||||
@ -597,8 +605,11 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
|
||||
* @param protos
|
||||
* @param options 添加到可交互/不可交互容器选项配置
|
||||
*/
|
||||
loadGraphic(protos: GraphicData[]) {
|
||||
// console.log('开始加载proto数据', protos);
|
||||
async loadGraphic(protos: GraphicData[]) {
|
||||
for (const item of this.graphicTemplateMap) {
|
||||
await item[1].loadAssets();
|
||||
}
|
||||
console.log('开始加载proto数据', protos);
|
||||
// 加载数据到图形存储
|
||||
protos.forEach((proto) => {
|
||||
const template = this.getGraphicTemplatesByType(proto.graphicType);
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import { Viewport } from 'pixi-viewport';
|
||||
@ -451,9 +452,9 @@ export interface GraphicData {
|
||||
copyFrom(data: GraphicData): void;
|
||||
/**
|
||||
* 是否相等
|
||||
* @param data
|
||||
* @param other
|
||||
*/
|
||||
eq(data: GraphicData): boolean;
|
||||
eq(other: GraphicData): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -478,6 +479,63 @@ export interface GraphicState {
|
||||
eq(data: GraphicState): boolean;
|
||||
}
|
||||
|
||||
export interface GraphicAnimationOptions {
|
||||
name: string;
|
||||
/**
|
||||
* 位移路径
|
||||
*/
|
||||
path?: IPointData[];
|
||||
/**
|
||||
* 是否循环运动(运动到终点后重新从开始运动),与moveToAndFro互斥
|
||||
*/
|
||||
cycleMove?: boolean;
|
||||
/**
|
||||
* 是否往复运动(运动到终点后从终点往回运动),与cycleMove互斥
|
||||
*/
|
||||
moveToAndFro?: boolean;
|
||||
|
||||
run?: (dt: number) => void;
|
||||
}
|
||||
|
||||
export class GraphicAnimation {
|
||||
options: GraphicAnimationOptions;
|
||||
_running: boolean;
|
||||
_finish: boolean;
|
||||
constructor(options: GraphicAnimationOptions) {
|
||||
this.options = options;
|
||||
this._running = false;
|
||||
this._finish = false;
|
||||
}
|
||||
|
||||
static init(options: GraphicAnimationOptions) {
|
||||
return new GraphicAnimation(options);
|
||||
}
|
||||
|
||||
pause(): GraphicAnimation {
|
||||
this._running = false;
|
||||
return this;
|
||||
}
|
||||
resume(): GraphicAnimation {
|
||||
this._running = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public get name(): string {
|
||||
return this.options.name;
|
||||
}
|
||||
|
||||
public get running(): boolean {
|
||||
return this._running;
|
||||
}
|
||||
|
||||
run(dt: number): GraphicAnimation {
|
||||
if (this.options.run) {
|
||||
this.options.run(dt);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 图形对象基类
|
||||
*/
|
||||
@ -488,6 +546,7 @@ export abstract class JlGraphic extends Container {
|
||||
private _code = ''; // 业务编号/名称,用于标识图形对象,具有业务意义
|
||||
_datas?: GraphicData; // 图形数据
|
||||
_states?: GraphicState; // 图形状态数据
|
||||
animationMap: Map<string, GraphicAnimation> = new Map();
|
||||
private _relationManage?: RelationManage; // 图形关系管理
|
||||
private _queryStore?: GraphicQueryStore; // 图形对象查询仓库
|
||||
|
||||
@ -498,6 +557,13 @@ export abstract class JlGraphic extends Container {
|
||||
this.filters;
|
||||
}
|
||||
|
||||
addAnimation(animation: GraphicAnimation): void {
|
||||
this.animationMap.set(animation.name, animation);
|
||||
}
|
||||
removeAnimation(name: string): void {
|
||||
this.animationMap.delete(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新选中状态
|
||||
* @param selected
|
||||
@ -803,6 +869,7 @@ export abstract class JlGraphic extends Container {
|
||||
* 处理重绘逻辑
|
||||
*/
|
||||
abstract doRepaint(): void;
|
||||
|
||||
/**
|
||||
* 处理删除逻辑
|
||||
*/
|
||||
@ -838,7 +905,7 @@ export abstract class JlGraphicTemplate<G extends JlGraphic> {
|
||||
/**
|
||||
* 加载图形对象需要用到的资源
|
||||
*/
|
||||
loadAsserts(): void {}
|
||||
async loadAssets(): Promise<any> {}
|
||||
|
||||
/**
|
||||
* 克隆图形对象
|
||||
|
@ -153,6 +153,7 @@ export class JlGraphicAppKeyboardPlugin {
|
||||
* @param keyListener
|
||||
*/
|
||||
removeKeyListener(keyListener: KeyListener) {
|
||||
keyListener.onRemove();
|
||||
const map = this.getOrInit(keyListener.value);
|
||||
const old = map.get(keyListener.identifier);
|
||||
map.delete(keyListener.identifier);
|
||||
@ -343,4 +344,8 @@ export class KeyListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
onRemove(): void {
|
||||
// 重置按下状态
|
||||
this.isPress = false;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
/**
|
||||
* 判定是否代理对象
|
||||
* @param obj
|
||||
* @returns
|
||||
*/
|
||||
export function isProxy(obj: any): boolean {
|
||||
return !!(obj && obj['__Proxy']);
|
||||
}
|
@ -2,7 +2,6 @@ import { Point, Rectangle } from 'pixi.js';
|
||||
|
||||
export * from './GraphicUtils';
|
||||
export * from './IntersectUtils';
|
||||
export * from './ObjectUtils';
|
||||
|
||||
export const UP: Point = new Point(0, -1);
|
||||
export const DOWN: Point = new Point(0, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user