ibp添加设备蜂鸣器钥匙箭头

This commit is contained in:
fan 2023-10-09 14:32:30 +08:00
parent f646bc0840
commit c9393abba8
12 changed files with 711 additions and 4 deletions

View File

@ -0,0 +1,80 @@
import { Graphics, IPointData } from 'pixi.js';
import { GraphicData, JlGraphic, JlGraphicTemplate } from 'src/jl-graphic';
import { ILineGraphic } from 'src/jl-graphic/plugins/GraphicEditPlugin';
export interface IArrowData extends GraphicData {
get code(): string; // 编号
set code(v: string);
get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]);
clone(): IArrowData;
copyFrom(data: IArrowData): void;
eq(other: IArrowData): boolean;
}
export const ArrowConsts = {
lineColor: '#0000CD',
lineWidth: 5,
};
export class Arrow extends JlGraphic implements ILineGraphic {
static Type = 'Arrow';
lineGraphic: Graphics;
arrowGraphic: Graphics;
constructor() {
super(Arrow.Type);
this.lineGraphic = new Graphics();
this.arrowGraphic = new Graphics();
this.transformSave = true;
this.addChild(this.lineGraphic);
this.addChild(this.arrowGraphic);
}
doRepaint() {
if (this.datas.points.length < 2) {
throw new Error('Arrow坐标数据异常');
}
this.lineGraphic.clear();
this.lineGraphic.lineStyle(ArrowConsts.lineWidth, ArrowConsts.lineColor);
const p1 = this.datas.points[0];
const p2 = this.datas.points[1];
this.lineGraphic.moveTo(p1.x, p1.y);
this.lineGraphic.lineTo(p2.x, p2.y);
this.arrowGraphic.clear();
this.arrowGraphic.beginFill(ArrowConsts.lineColor, 1);
if (this.arrowGraphic.drawRegularPolygon) {
this.arrowGraphic.drawRegularPolygon(
-10,
0,
10,
3,
Math.atan2(p2.y - p1.y, p2.x - p1.y)
);
}
this.arrowGraphic.endFill();
}
get datas(): IArrowData {
return this.getDatas<IArrowData>();
}
get linePoints(): IPointData[] {
return this.datas.points;
}
set linePoints(points: IPointData[]) {
const old = this.datas.clone();
old.points = points;
this.updateData(old);
}
}
export class ArrowTemplate extends JlGraphicTemplate<Arrow> {
constructor(dataTemplate: IArrowData) {
super(Arrow.Type, { dataTemplate });
}
new() {
return new Arrow();
}
}

View File

@ -0,0 +1,201 @@
import {
DraggablePoint,
IGraphicApp,
GraphicDrawAssistant,
GraphicInteractionPlugin,
GraphicTransformEvent,
IDrawApp,
JlGraphic,
linePoint,
AbsorbablePosition,
AbsorbableLine,
} from 'src/jl-graphic';
import { IArrowData, Arrow, ArrowConsts, ArrowTemplate } from './Arrow';
import {
DisplayObject,
FederatedMouseEvent,
Graphics,
IHitArea,
Point,
} from 'pixi.js';
import {
ILineGraphic,
PolylineEditPlugin,
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
export class ArrowDraw extends GraphicDrawAssistant<ArrowTemplate, IArrowData> {
points: Point[] = [];
lineGraphic = new Graphics();
arrowGraphic = new Graphics();
constructor(app: IDrawApp, template: ArrowTemplate) {
super(app, template, 'call_made', '箭头Arrow');
this.container.addChild(this.lineGraphic);
this.container.addChild(this.arrowGraphic);
}
bind(): void {
super.bind();
}
unbind(): void {
super.unbind();
}
onLeftDown(e: FederatedMouseEvent): void {
const { x, y } = this.toCanvasCoordinates(e.global);
const p = new Point(x, y);
this.points.push(p);
if (this.points.length === 2) {
this.createAndStore;
}
}
onRightClick(): void {
this.finish();
return;
}
onEsc(): void {
this.finish();
return;
}
redraw(p: Point): void {
if (this.points.length < 1) return;
const p1 = this.points[0];
this.lineGraphic.clear();
this.lineGraphic.lineStyle(ArrowConsts.lineWidth, ArrowConsts.lineColor);
this.lineGraphic.moveTo(p1.x, p1.y);
this.lineGraphic.lineTo(p.x, p.y);
this.arrowGraphic.clear();
this.arrowGraphic.beginFill(ArrowConsts.lineColor, 1);
if (this.arrowGraphic.drawRegularPolygon) {
this.arrowGraphic.drawRegularPolygon(
-10,
0,
10,
3,
Math.atan2(p.y - p1.y, p.x - p1.y)
);
}
this.arrowGraphic.endFill();
}
prepareData(data: IArrowData): boolean {
if (this.points.length < 2) {
console.log('Arrow绘制因点不够取消绘制');
return false;
}
data.points = this.points;
return true;
}
clearCache(): void {
this.points = [];
this.lineGraphic.clear();
this.arrowGraphic.clear();
}
}
export class ArrowGraphicHitArea implements IHitArea {
arrow: Arrow;
constructor(arrow: Arrow) {
this.arrow = arrow;
}
contains(x: number, y: number): boolean {
const p1 = this.arrow.datas.points[0];
const p2 = this.arrow.datas.points[1];
if (linePoint(p1, p2, { x, y }, ArrowConsts.lineWidth)) {
return true;
}
return false;
}
}
function buildAbsorbablePositions(arrow: Arrow): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const arrows = arrow.queryStore.queryByType<Arrow>(Arrow.Type);
const canvas = arrow.getCanvas();
arrows.forEach((other) => {
if (other.id === arrow.id) {
return;
}
const [p1, p2] = [
other.localToCanvasPoint(other.datas.points[0]),
other.localToCanvasPoint(other.datas.points[1]),
];
const ala = new AbsorbableLine(
new Point(p1.x, 0),
new Point(p1.x, canvas.height)
);
aps.push(ala);
const alb = new AbsorbableLine(
new Point(p2.x, 0),
new Point(p2.x, canvas.height)
);
aps.push(alb);
});
return aps;
}
function onEditPointCreate(g: ILineGraphic, dp: DraggablePoint): void {
const arrow = g as Arrow;
dp.on('transformstart', (e: GraphicTransformEvent) => {
if (e.isShift()) {
arrow.getGraphicApp().setOptions({
absorbablePositions: buildAbsorbablePositions(arrow),
});
}
});
}
export class ArrowPointEditPlugin extends GraphicInteractionPlugin<Arrow> {
static Name = 'SectionPointDrag';
drawAssistant: ArrowDraw;
constructor(app: IGraphicApp, da: ArrowDraw) {
super(ArrowPointEditPlugin.Name, app);
this.drawAssistant = da;
}
static init(app: IGraphicApp, da: ArrowDraw) {
return new ArrowPointEditPlugin(app, da);
}
filter(...grahpics: JlGraphic[]): Arrow[] | undefined {
return grahpics.filter((g) => g.type == Arrow.Type) as Arrow[];
}
bind(g: Arrow): void {
g.lineGraphic.eventMode = 'static';
g.lineGraphic.cursor = 'pointer';
g.hitArea = new ArrowGraphicHitArea(g);
g.transformSave = true;
g.on('selected', this.onSelected, this);
g.on('unselected', this.onUnselected, this);
}
unbind(g: Arrow): void {
g.off('selected', this.onSelected, this);
g.off('unselected', this.onUnselected, this);
}
onContextMenu(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const arrow = target.getGraphic() as Arrow;
this.app.updateSelected(arrow);
}
onSelected(g: DisplayObject): void {
const arrow = g as Arrow;
const lep = new PolylineEditPlugin(arrow, { onEditPointCreate });
arrow.addAssistantAppend(lep);
lep.showAll();
}
onUnselected(g: DisplayObject): void {
const arrow = g as Arrow;
const lep = arrow.getAssistantAppend<PolylineEditPlugin>(
PolylineEditPlugin.Name
);
if (lep) {
lep.hideAll();
}
}
}

View File

@ -0,0 +1,73 @@
import {
GraphicData,
GraphicState,
JlGraphic,
JlGraphicTemplate,
} from 'src/jl-graphic';
import Ibp_Alarm_Assets from './ibp-alarm-spritesheet.png';
import Ibp_Alarm_JSON from './ibp-alarm-data.json';
import { Assets, Sprite, Spritesheet, Texture } from 'pixi.js';
interface IbpAlarmTextures {
ibpAlarm: Texture;
}
export interface IIbpAlarmData extends GraphicData {
get code(): string;
set code(v: string);
}
export interface IIbpAlarmState extends GraphicState {
get state(): number;
set state(v: number);
}
export class IbpAlarm extends JlGraphic {
static Type = 'IbpAlarm';
_ibpAlarm: Sprite;
ibpAlarmTextures: IbpAlarmTextures;
__state = 0;
constructor(ibpAlarmTextures: IbpAlarmTextures) {
super(IbpAlarm.Type);
this.ibpAlarmTextures = ibpAlarmTextures;
this._ibpAlarm = new Sprite();
this._ibpAlarm.texture = this.ibpAlarmTextures.ibpAlarm;
this._ibpAlarm.anchor.set(0.5);
this.addChild(this._ibpAlarm);
}
get datas(): IIbpAlarmData {
return this.getDatas<IIbpAlarmData>();
}
doRepaint(): void {
this._ibpAlarm.rotation = 0;
this._ibpAlarm.texture = this.ibpAlarmTextures.ibpAlarm;
}
}
export class IbpAlarmTemplate extends JlGraphicTemplate<IbpAlarm> {
ibpAlarmTextures?: IbpAlarmTextures;
constructor(dataTemplate: IIbpAlarmData) {
super(IbpAlarm.Type, { dataTemplate });
this.loadAssets();
}
new(): IbpAlarm {
if (this.ibpAlarmTextures) {
const g = new IbpAlarm(this.ibpAlarmTextures);
g.loadData(this.datas);
// g.loadState(this.states);
return g;
}
throw new Error('资源未加载/加载失败');
}
async loadAssets(): Promise<IbpAlarmTextures> {
const texture = await Assets.load(Ibp_Alarm_Assets);
const ibpAlarmSheet = new Spritesheet(texture, Ibp_Alarm_JSON);
const result = await ibpAlarmSheet.parse();
this.ibpAlarmTextures = {
ibpAlarm: result['ibp-alarm.png'],
};
return this.ibpAlarmTextures as IbpAlarmTextures;
}
}

View File

@ -0,0 +1,114 @@
import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js';
import {
AbsorbableLine,
AbsorbablePosition,
GraphicDrawAssistant,
GraphicInteractionPlugin,
GraphicTransformEvent,
IDrawApp,
JlGraphic,
} from 'src/jl-graphic';
import { IIbpAlarmData, IbpAlarm, IbpAlarmTemplate } from './IbpAlarm';
export class IbpAlarmDraw extends GraphicDrawAssistant<
IbpAlarmTemplate,
IIbpAlarmData
> {
_ibpAlarm: IbpAlarm | null = null;
constructor(app: IDrawApp, template: IbpAlarmTemplate) {
super(app, template, 'notifications_active', 'Ibp蜂鸣器');
IbpAlarmInteraction.init(app);
}
bind(): void {
super.bind();
if (!this._ibpAlarm) {
this._ibpAlarm = this.graphicTemplate.new();
this.container.addChild(this._ibpAlarm);
}
}
public get ibpAlarm(): IbpAlarm {
if (!this._ibpAlarm) {
this._ibpAlarm = this.graphicTemplate.new();
this.container.addChild(this._ibpAlarm);
}
return this._ibpAlarm;
}
redraw(cp: Point): void {
this.ibpAlarm.position.copyFrom(cp);
}
onLeftUp(e: FederatedMouseEvent): void {
this.ibpAlarm.position.copyFrom(this.toCanvasCoordinates(e.global));
this.createAndStore(true);
}
prepareData(data: IIbpAlarmData): boolean {
data.transform = this.ibpAlarm.saveTransform();
return true;
}
onEsc(): void {
this.finish();
}
}
/**
* 线
* @param ibpAlarm
*/
function buildAbsorbablePositions(ibpAlarm: IbpAlarm): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const ibpAlarms = ibpAlarm.queryStore.queryByType<IbpAlarm>(IbpAlarm.Type);
const canvas = ibpAlarm.getCanvas();
ibpAlarms.forEach((item) => {
if (item.id === ibpAlarm.id) {
return;
}
const ala = new AbsorbableLine(
new Point(item.x, 0),
new Point(item.x, canvas.height)
);
const alb = new AbsorbableLine(
new Point(0, item.y),
new Point(canvas.width, item.y)
);
aps.push(ala);
aps.push(alb);
});
return aps;
}
export class IbpAlarmInteraction extends GraphicInteractionPlugin<IbpAlarm> {
static Name = 'ibp_alarm_transform';
constructor(app: IDrawApp) {
super(IbpAlarmInteraction.Name, app);
}
static init(app: IDrawApp) {
return new IbpAlarmInteraction(app);
}
filter(...grahpics: JlGraphic[]): IbpAlarm[] | undefined {
return grahpics
.filter((g) => g.type === IbpAlarm.Type)
.map((g) => g as IbpAlarm);
}
bind(g: IbpAlarm): void {
g.eventMode = 'static';
g.cursor = 'pointer';
g.scalable = true;
g.rotatable = true;
g.on('transformstart', this.transformstart, this);
}
unbind(g: IbpAlarm): void {
g.eventMode = 'none';
g.scalable = false;
g.rotatable = false;
g.off('transformstart', this.transformstart, this);
}
transformstart(e: GraphicTransformEvent) {
const target = e.target as DisplayObject;
const ibpAlarm = target.getGraphic() as IbpAlarm;
ibpAlarm.getGraphicApp().setOptions({
absorbablePositions: buildAbsorbablePositions(ibpAlarm),
});
}
}

View File

@ -0,0 +1,21 @@
{
"frames": {
"ibp-alarm.png": {
"frame": { "x": 0, "y": 0, "w": 71, "h": 74 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 71, "h": 74 },
"sourceSize": { "w": 71, "h": 74 },
"anchor": { "x": 0.5, "y": 0.5 }
}
},
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "1.1",
"image": "ibp-alarm.png",
"format": "RGBA8888",
"size": { "w": 71, "h": 74 },
"scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,75 @@
import {
GraphicData,
GraphicState,
JlGraphic,
JlGraphicTemplate,
} from 'src/jl-graphic';
import Ibp_Key_Assets from './ibp-key-spritesheet.png';
import Ibp_Key_JSON from './ibp-key-data.json';
import { Assets, Sprite, Spritesheet, Texture } from 'pixi.js';
interface IbpKeyTextures {
ibpKeyOn: Texture;
ibpKeyOff: Texture;
}
export interface IIbpKeyData extends GraphicData {
get code(): string;
set code(v: string);
}
export interface IIbpKeyState extends GraphicState {
get state(): number;
set state(v: number);
}
export class IbpKey extends JlGraphic {
static Type = 'IbpKey';
_ibpKey: Sprite;
ibpKeyTextures: IbpKeyTextures;
__state = 0;
constructor(ibpKeyTextures: IbpKeyTextures) {
super(IbpKey.Type);
this.ibpKeyTextures = ibpKeyTextures;
this._ibpKey = new Sprite();
this._ibpKey.texture = this.ibpKeyTextures.ibpKeyOn;
this._ibpKey.anchor.set(0.5);
this.addChild(this._ibpKey);
}
get datas(): IIbpKeyData {
return this.getDatas<IIbpKeyData>();
}
doRepaint(): void {
this._ibpKey.rotation = 0;
this._ibpKey.texture = this.ibpKeyTextures.ibpKeyOn;
}
}
export class IbpKeyTemplate extends JlGraphicTemplate<IbpKey> {
ibpKeyTextures?: IbpKeyTextures;
constructor(dataTemplate: IIbpKeyData) {
super(IbpKey.Type, { dataTemplate });
this.loadAssets();
}
new(): IbpKey {
if (this.ibpKeyTextures) {
const g = new IbpKey(this.ibpKeyTextures);
g.loadData(this.datas);
// g.loadState(this.states);
return g;
}
throw new Error('资源未加载/加载失败');
}
async loadAssets(): Promise<IbpKeyTextures> {
const texture = await Assets.load(Ibp_Key_Assets);
const ibpKeySheet = new Spritesheet(texture, Ibp_Key_JSON);
const result = await ibpKeySheet.parse();
this.ibpKeyTextures = {
ibpKeyOn: result['ibp-key-on.png'],
ibpKeyOff: result['ibp-key-off.png'],
};
return this.ibpKeyTextures as IbpKeyTextures;
}
}

View File

@ -0,0 +1,114 @@
import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js';
import {
AbsorbableLine,
AbsorbablePosition,
GraphicDrawAssistant,
GraphicInteractionPlugin,
GraphicTransformEvent,
IDrawApp,
JlGraphic,
} from 'src/jl-graphic';
import { IIbpKeyData, IbpKey, IbpKeyTemplate } from './IbpKey';
export class IbpKeyDraw extends GraphicDrawAssistant<
IbpKeyTemplate,
IIbpKeyData
> {
_ibpKey: IbpKey | null = null;
constructor(app: IDrawApp, template: IbpKeyTemplate) {
super(app, template, 'svguse:../../drawIcon.svg#icon-psl-key', 'Ibp钥匙');
IbpKeyInteraction.init(app);
}
bind(): void {
super.bind();
if (!this._ibpKey) {
this._ibpKey = this.graphicTemplate.new();
this.container.addChild(this._ibpKey);
}
}
public get ibpKey(): IbpKey {
if (!this._ibpKey) {
this._ibpKey = this.graphicTemplate.new();
this.container.addChild(this._ibpKey);
}
return this._ibpKey;
}
redraw(cp: Point): void {
this.ibpKey.position.copyFrom(cp);
}
onLeftUp(e: FederatedMouseEvent): void {
this.ibpKey.position.copyFrom(this.toCanvasCoordinates(e.global));
this.createAndStore(true);
}
prepareData(data: IIbpKeyData): boolean {
data.transform = this.ibpKey.saveTransform();
return true;
}
onEsc(): void {
this.finish();
}
}
/**
* 线
* @param ibpKey
*/
function buildAbsorbablePositions(ibpKey: IbpKey): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const ibpKeys = ibpKey.queryStore.queryByType<IbpKey>(IbpKey.Type);
const canvas = ibpKey.getCanvas();
ibpKeys.forEach((item) => {
if (item.id === ibpKey.id) {
return;
}
const ala = new AbsorbableLine(
new Point(item.x, 0),
new Point(item.x, canvas.height)
);
const alb = new AbsorbableLine(
new Point(0, item.y),
new Point(canvas.width, item.y)
);
aps.push(ala);
aps.push(alb);
});
return aps;
}
export class IbpKeyInteraction extends GraphicInteractionPlugin<IbpKey> {
static Name = 'ibp_key_transform';
constructor(app: IDrawApp) {
super(IbpKeyInteraction.Name, app);
}
static init(app: IDrawApp) {
return new IbpKeyInteraction(app);
}
filter(...grahpics: JlGraphic[]): IbpKey[] | undefined {
return grahpics
.filter((g) => g.type === IbpKey.Type)
.map((g) => g as IbpKey);
}
bind(g: IbpKey): void {
g.eventMode = 'static';
g.cursor = 'pointer';
g.scalable = true;
g.rotatable = true;
g.on('transformstart', this.transformstart, this);
}
unbind(g: IbpKey): void {
g.eventMode = 'none';
g.scalable = false;
g.rotatable = false;
g.off('transformstart', this.transformstart, this);
}
transformstart(e: GraphicTransformEvent) {
const target = e.target as DisplayObject;
const ibpKey = target.getGraphic() as IbpKey;
ibpKey.getGraphicApp().setOptions({
absorbablePositions: buildAbsorbablePositions(ibpKey),
});
}
}

View File

@ -0,0 +1,29 @@
{
"frames": {
"ibp-key-on.png": {
"frame": { "x": 0, "y": 0, "w": 377, "h": 1032 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 377, "h": 1032 },
"sourceSize": { "w": 377, "h": 1032 },
"anchor": { "x": 0.5, "y": 0.5 }
},
"ibp-key-off.png": {
"frame": { "x": 378, "y": 0, "w": 377, "h": 1032 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 378, "y": 0, "w": 377, "h": 1032 },
"sourceSize": { "w": 377, "h": 1032 },
"anchor": { "x": 0.5, "y": 0.5 }
}
},
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "1.1",
"image": "ibp-key.png",
"format": "RGBA8888",
"size": { "w": 755, "h": 1032 },
"scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

View File

@ -20,9 +20,9 @@
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.codeandweb.com/texturepacker",
"version": "1.1", "version": "1.1",
"image": "psl-light.png", "image": "psl-button.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "w": 384, "h": 64 }, "size": { "w": 128, "h": 64 },
"scale": "1", "scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$" "smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$"
} }

View File

@ -12,9 +12,9 @@
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.codeandweb.com/texturepacker",
"version": "1.1", "version": "1.1",
"image": "psl-light.png", "image": "psl-key.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "w": 384, "h": 64 }, "size": { "w": 64, "h": 64 },
"scale": "1", "scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$" "smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$"
} }