import { Pos } from "@/utils/math.ts"; import { getMouseColors } from "@/utils/colors.ts"; import { onlyId } from "@/utils/shared.ts"; import { BaseItem, generateSnapInfos, getBaseItem } from "../util.ts"; import { InteractiveFix, InteractiveTo, MatResponseProps } from "../index.ts"; import { Transform } from "konva/lib/Util"; export { default as Component } from "./rectangle.vue"; export { default as TempComponent } from "./temp-rectangle.vue"; export const shapeName = "矩形"; export const defaultStyle = { dash: [30, 0], strokeWidth: 5, stroke: "#000000", fontSize: 22, align: "center", fontStyle: "normal", fontColor: "#000000", }; export const getMouseStyle = (data: RectangleData) => { const fillStatus = data.fill && getMouseColors(data.fill); const strokeStatus = data.stroke && getMouseColors(data.stroke); const strokeWidth = data.strokeWidth; return { default: { fill: data.fill, stroke: data.stroke, strokeWidth, }, hover: { fill: fillStatus && fillStatus.hover, stroke: strokeStatus && strokeStatus.hover }, focus: { fill: fillStatus && fillStatus.hover, stroke: strokeStatus && strokeStatus.hover }, press: { fill: fillStatus && fillStatus.press, stroke: strokeStatus && strokeStatus.press }, select: { fill: fillStatus && fillStatus.select, stroke: strokeStatus && strokeStatus.select, }, }; }; export const addMode = "area"; export type RectangleData = Partial & BaseItem & { id: string; attitude: number[]; points: Pos[]; createTime: number; zIndex: number; dash?: number[]; stroke?: string; fill?: string; strokeWidth?: number; content?: string; }; export const getSnapPoints = (data: RectangleData) => { return data.points; }; export const getSnapInfos = (data: RectangleData) => generateSnapInfos(getSnapPoints(data), true, false); export const interactiveToData: InteractiveTo<"rectangle"> = ({ info, preset = {}, ...args }) => { if (info.cur) { const item = { ...getBaseItem(), ...defaultStyle, ...preset, id: onlyId(), createTime: Date.now(), zIndex: 0, } as unknown as RectangleData; return interactiveFixData({ ...args, info, data: item }); } }; export const interactiveFixData: InteractiveFix<"rectangle"> = ({ data, info, }) => { if (info.cur) { const area = info.cur!; const width = area[1].x - area[0].x; const height = area[1].y - area[0].y; data.points = [ info.cur[0], { x: info.cur[0].x + width, y: info.cur[0].y }, { x: info.cur[0].x + width, y: info.cur[0].y + height }, { x: info.cur[0].x, y: info.cur[0].y + height }, ]; data.attitude = [1, 0, 0, 1, 0, 0]; } return data; }; export const matResponse = ({ data, mat, increment, }: MatResponseProps<"rectangle">) => { let transfrom: Transform; const attitude = new Transform(data.attitude); if (!increment) { const inverMat = attitude.copy().invert(); transfrom = mat.copy().multiply(inverMat); } else { transfrom = mat; } data.points = data.points.map((v) => transfrom.point(v)); data.attitude = transfrom.copy().multiply(attitude).m; return data; }; export const getPredefine = (key: keyof RectangleData) => { if (["fill", "stroke"].includes(key)) { return { canun: true }; } else if (key === "strokeWidth") { return { proportion: true }; } };