207 lines
5.1 KiB
TypeScript
207 lines
5.1 KiB
TypeScript
import { pond } from "protobuf-ts/pond";
|
|
import { Placeable } from "./Placeable";
|
|
import Fan1Icon from "assets/editor/fan1.png";
|
|
import Fan2Icon from "assets/editor/fan2.png";
|
|
import Fan3Icon from "assets/editor/fan3.png";
|
|
import { or } from "utils";
|
|
import { SnapPoint } from "./geometry";
|
|
|
|
export class Fan implements Placeable {
|
|
public angle: number = 0;
|
|
public ctrl: boolean = false;
|
|
public shift: boolean = false;
|
|
public direction = 0;
|
|
//public snapPoints = []
|
|
private mouseOffsetX = 0;
|
|
private mouseOffsetY = 0;
|
|
type: pond.PlaceableType = pond.PlaceableType.PLACEABLE_TYPE_FAN;
|
|
public subtype = 0;
|
|
|
|
magnitude(): number {
|
|
return 0;
|
|
}
|
|
|
|
radius(): number {
|
|
return this.fan_radius;
|
|
}
|
|
|
|
highlight(
|
|
context: CanvasRenderingContext2D,
|
|
offsetX?: number,
|
|
offsetY?: number,
|
|
scale = 1
|
|
): void {
|
|
offsetX = offsetX ? offsetX : 0;
|
|
offsetY = offsetY ? offsetY : 0;
|
|
|
|
let x = (this.x - offsetX) * scale;
|
|
let y = (this.y - offsetY) * scale;
|
|
|
|
context.beginPath();
|
|
context.strokeStyle = "yellow";
|
|
context.arc(x, y, this.radius() * scale, 0, 2 * Math.PI);
|
|
context.stroke();
|
|
|
|
context.strokeStyle = "white";
|
|
}
|
|
|
|
public drag = (x: number, y: number) => {
|
|
this.x = x - this.mouseOffsetX;
|
|
this.y = y - this.mouseOffsetY;
|
|
};
|
|
|
|
public getEndXAndY = (x = this.x, y = this.y, angle = this.angle, length = this.magnitude()) => {
|
|
return { x: x, y: y };
|
|
};
|
|
|
|
getSnapPoints() {
|
|
let snaps: SnapPoint[] = [];
|
|
snaps.push({
|
|
x: this.x,
|
|
y: this.y,
|
|
angle: this.angle,
|
|
startPoint: false,
|
|
occupant: undefined
|
|
} as SnapPoint);
|
|
return snaps;
|
|
}
|
|
|
|
snap(p: Placeable, d: number): void {
|
|
d = d ? d : 12;
|
|
p.getSnapPoints().forEach(point => {
|
|
if (this.distance(this.x, point.x, this.y, point.y) < d) {
|
|
this.x = point.x;
|
|
this.y = point.y;
|
|
//this.angle = point.angle;
|
|
}
|
|
});
|
|
}
|
|
|
|
private fan_radius = 1;
|
|
public x = 0;
|
|
public y = 0;
|
|
public selected = true;
|
|
public img: HTMLImageElement | undefined = undefined;
|
|
|
|
public static create(x: number, y: number, radius: number, subtype: number): Fan {
|
|
let c = new Fan();
|
|
let i = new Image();
|
|
i.src = Fan1Icon;
|
|
switch (subtype) {
|
|
case pond.FanType.FAN_TYPE_CENTRIFUGAL_INLINE:
|
|
i.src = Fan1Icon;
|
|
break;
|
|
case pond.FanType.FAN_TYPE_CENTRIFUGAL_HIGH_SPEED:
|
|
i.src = Fan2Icon;
|
|
break;
|
|
case pond.FanType.FAN_TYPE_CENTRIFUGAL_LOW_SPEED:
|
|
i.src = Fan3Icon;
|
|
break;
|
|
}
|
|
c.img = i;
|
|
c.x = x;
|
|
c.y = y;
|
|
c.fan_radius = radius;
|
|
c.subtype = subtype;
|
|
return c;
|
|
}
|
|
|
|
public static fromPond(placeable: pond.Placeable) {
|
|
let f = new Fan();
|
|
let i = new Image();
|
|
i.src = Fan1Icon;
|
|
if (placeable.subtype) {
|
|
switch (placeable.subtype) {
|
|
case pond.FanType.FAN_TYPE_CENTRIFUGAL_INLINE:
|
|
i.src = Fan1Icon;
|
|
break;
|
|
case pond.FanType.FAN_TYPE_CENTRIFUGAL_HIGH_SPEED:
|
|
i.src = Fan2Icon;
|
|
break;
|
|
case pond.FanType.FAN_TYPE_CENTRIFUGAL_LOW_SPEED:
|
|
i.src = Fan3Icon;
|
|
break;
|
|
}
|
|
}
|
|
f.img = i;
|
|
f.x = placeable.x;
|
|
f.y = placeable.y;
|
|
f.fan_radius = or(placeable.radius, placeable.width / 2);
|
|
f.subtype = placeable.subtype;
|
|
return f;
|
|
}
|
|
|
|
public draw(context: CanvasRenderingContext2D, offsetX?: number, offsetY?: number, scale = 1) {
|
|
offsetX = offsetX ? offsetX : 0;
|
|
offsetY = offsetY ? offsetY : 0;
|
|
let oldStyle = context.fillStyle;
|
|
if (this.img === undefined) {
|
|
context.beginPath();
|
|
context.arc(
|
|
(this.x + offsetX) * scale,
|
|
(this.y + offsetY) * scale,
|
|
this.radius(),
|
|
0,
|
|
2 * Math.PI
|
|
);
|
|
if (this.selected) {
|
|
context.fillStyle = "grey";
|
|
context.fill();
|
|
}
|
|
context.stroke();
|
|
context.fillStyle = oldStyle;
|
|
} else {
|
|
context.fillStyle = "rgba(255, 255, 255, 255)";
|
|
context.drawImage(
|
|
this.img,
|
|
(this.x - (offsetX ? offsetX : 0) - this.radius()) * scale,
|
|
(this.y - (offsetY ? offsetY : 0) - this.radius()) * scale,
|
|
this.radius() * 2 * scale,
|
|
this.radius() * 2 * scale
|
|
);
|
|
}
|
|
}
|
|
|
|
public distance(x1: number, x2: number, y1: number, y2: number) {
|
|
let a = x1 - x2;
|
|
let b = y1 - y2;
|
|
return Math.sqrt(a * a + b * b);
|
|
}
|
|
|
|
public clickCheck(x: number, y: number) {
|
|
let dx = Math.abs(x - this.x);
|
|
let dy = Math.abs(y - this.y);
|
|
let distance = Math.sqrt(dx * dx + dy * dy);
|
|
if (distance <= this.radius()) {
|
|
this.selected = true;
|
|
this.mouseOffsetX = x - this.x;
|
|
this.mouseOffsetY = y - this.y;
|
|
return true;
|
|
}
|
|
this.selected = false;
|
|
this.mouseOffsetX = 0;
|
|
this.mouseOffsetY = 0;
|
|
return false;
|
|
}
|
|
|
|
public clone() {
|
|
let f = new Fan();
|
|
f.img = this.img;
|
|
f.radius = this.radius;
|
|
f.selected = false;
|
|
f.x = this.x;
|
|
f.y = this.y;
|
|
return f;
|
|
}
|
|
|
|
public getEndAngle(): number {
|
|
return this.angle;
|
|
}
|
|
|
|
setDirection(direction: number): void {}
|
|
|
|
setAngle(angle: number, oldAngle?: number) {
|
|
this.angle = angle;
|
|
//if (oldAngle) this.oldAngle = oldAngle
|
|
}
|
|
}
|