import { Path } from "konva/lib/shapes/Path"; import { CustomizeShape, WholeLinePoint, getRealAbsoluteSize, getWholeLinePolygonPoints, mergeFuns, openEntityDrag, wholeLineStyle, } from "../../board"; import { PolygonsPointAttrib } from "./type"; import { Group } from "konva/lib/Group"; import { Text } from "konva/lib/shapes/Text"; import { Circle } from "konva/lib/shapes/Circle"; import { Polygons } from "./polygons"; import { point } from "../../board/packages/whole-line/style"; import { Label, Tag } from "konva/lib/shapes/Label"; import { watch, watchEffect } from "vue"; const pointActShapeFactory = (attrib: PolygonsPointAttrib, tree: PoPoint) => { const polygons = tree.parent as unknown as Polygons; const size = { width: 43, height: 44 }; const out = new Path({ data: `M22 44C32.6667 33.891 38 25.891 38 20C38 11.1634 30.8366 4 22 4C13.1634 4 6 11.1634 6 20C6 25.891 11.3333 33.891 22 44Z`, strokeScaleEnabled: true, stroke: "#ffffff", strokeWidth: 1, }); const inner = new Path({ fill: "#fff", data: `M22 30C27.5228 30 32 25.5228 32 20C32 14.4772 27.5228 10 22 10C16.4772 10 12 14.4772 12 20C12 25.5228 16.4772 30 22 30Z`, }); const select = new Path({ fill: "#409EFF", offset: { x: -5, y: -5, }, data: `M20.5143 12.213C20.7983 12.497 20.7983 12.9575 20.5143 13.2415L15.2727 18.4831L11.8494 15.0597C11.5654 14.7757 11.5654 14.3152 11.8494 14.0312C12.1334 13.7472 12.5939 13.7472 12.8779 14.0312L15.2727 16.426L19.4857 12.213C19.7698 11.929 20.2302 11.929 20.5143 12.213Z`, }); const rectGroup = new Group({ name: "anchor-move", }); const rect = new Circle({ name: "anchor-move", radius: Math.min(size.width, size.height) / 2, fill: "rgba(0, 0, 0, 0)", offset: { x: -size.width / 2, y: -size.height / 2 }, }); const wlp = wholeLineStyle.pointShapeFactory(); point.radius = 5; point.hitStrokeWidth = point.strokeWidth = 4; wlp.shape.name("anchor-point"); const index = new Text({ name: "text", text: `1`, fontFamily: "Calibri", fontSize: 12, padding: 5, offsetY: -8, fill: "#000", }); const label = new Label({ visible: false, opacity: 1, name: "label", offsetX: -size.width / 2, offsetY: -6, }); rectGroup.add(index, label, rect); const text = new Text({ name: "text", text: attrib.title || `P${attrib.id}`, fontFamily: "Inter", fontSize: 12, padding: 8, fill: "#303133", }); label.add( new Tag({ name: "tag", fill: "rgba(255, 255, 255, 1)", pointerDirection: "down", pointerWidth: 8, pointerHeight: 8, lineJoin: "round", shadowColor: "black", cornerRadius: 2, opacity: 1, shadowBlur: 10, shadowOffsetX: 10, shadowOffsetY: 10, shadowOpacity: 0.5, }), text ); const offsetGroup = new Group(); offsetGroup.add(out, inner, select, rectGroup); offsetGroup.x(-size.width / 2); offsetGroup.y(-size.height); const group = new Group(); group.add(offsetGroup, wlp.shape); const result = { shape: group, common() { out.fill(attrib.rtk ? "rgba(230, 162, 60, 1)" : "#409EFF"); select.fill(attrib.rtk ? "rgba(230, 162, 60, 1)" : "#409EFF"); wlp.common(); label.visible(false); }, hover: () => { label.visible(true); if (!attrib.rtk) { out.fill("#409EFF"); select.fill("#409EFF"); } }, setData(data: number[]) { let [width, height] = getRealAbsoluteSize(group, [1, 1]); group.scale({ x: width, y: height }); group.x(data[0]); group.y(data[1]); text.text(tree.attrib.title || `P${attrib.id}`); if (~tree.editPolygonNdx) { index.text((tree.editPolygonNdx + 1).toString()).visible(true); index.offsetX(-rect.width() / 2 + index.width() / 2); wlp.shape.visible(true); select.visible(false); } else { index.visible(false); wlp.shape.visible(false); select.visible(polygons.status.selectPoiIds.includes(attrib.id)); } }, draging() { if (~tree.editPolygonNdx) { out.fill("#e0403c"); select.fill("#e0403c"); } }, }; return result; }; export class PoPoint extends WholeLinePoint { actShape: CustomizeShape void }> = null; get editPolygonNdx() { const polygons = this.parent as unknown as Polygons; if (polygons.status.editPolygonId) { const points = getWholeLinePolygonPoints( polygons.attrib, polygons.status.editPolygonId ).map(({ id }) => id); return points.indexOf(this.attrib.id); } return -1; } init(): void { this.actShapeFactory = pointActShapeFactory; super.init(); this.enableMouseAct(this.actShape); } protected initReactive() { const polygons = this.parent as unknown as Polygons; this.bus.on("shapeStatusChange", ({ current, type }) => { if (current === "active" && type === "click") { polygons.bus.emit("clickPoint", this.attrib); } }); return mergeFuns( super.initReactive(), watch( () => this.editPolygonNdx, (endx, _, onCleanup) => { if (!~endx || this.attrib.rtk) { return onCleanup(() => {}); } const anchor = this.shape.findOne(".anchor-move"); let clearCursor: (() => void) | null = null; anchor.on("mouseenter.anchor", () => { clearCursor && clearCursor(); clearCursor = this.container.setCursor("move"); }); anchor.on("mouseleave.anchor", () => { clearCursor && clearCursor(); clearCursor = null; }); openEntityDrag(this, { readyHandler: (attrib) => { return [attrib.x, attrib.y]; }, moveHandler: (pointAttrib, move) => { if (~this.editPolygonNdx) { pointAttrib.x = move[0]; pointAttrib.y = move[1]; } }, }); onCleanup(() => { anchor.off("mouseenter.anchor mouseleave.anchor"); clearCursor && clearCursor(); this.disableDrag(); }); }, { immediate: true } ), watchEffect( () => { if (polygons.status.lightPointId === this.attrib.id) { this.bus.emit("statusChange", { hover: true }); } else { this.bus.emit("statusChange", null); } }, { flush: "post" } ) ); } }