import { CircleConfig } from "konva/lib/shapes/Circle"; import { themeColor, themeMouseColors } from "@/constant/help-style.ts"; import { BaseItem, generateSnapInfos, getBaseItem, getRectSnapPoints, } from "../util.ts"; import { getMouseColors } from "@/utils/colors.ts"; import { lineCenter, Pos } from "@/utils/math.ts"; import { Transform } from "konva/lib/Util"; import { InteractiveFix, InteractiveTo, MatResponseProps } from "../index.ts"; import { MathUtils } from "three"; export { default as Component } from "./circle.vue"; export { default as TempComponent } from "./temp-circle.vue"; export const shapeName = "圆形"; export const defaultStyle = { dash: [30, 0], stroke: '#000000', strokeWidth: 2, fontSize: 16, align: "center", fontStyle: "normal", fontColor: '#000000', padding: 8 }; export const addMode = "area"; export const getMouseStyle = (data: CircleData) => { const fillStatus = data.fill && getMouseColors(data.fill); const strokeStatus = getMouseColors(data.stroke || defaultStyle.stroke); const strokeWidth = data.strokeWidth || defaultStyle.strokeWidth; return { default: { stroke: data.stroke || defaultStyle.stroke, strokeWidth }, hover: { fill: fillStatus && fillStatus.hover, stroke: strokeStatus.hover }, select: { fill: fillStatus && fillStatus.select, stroke: strokeStatus.select }, focus: { fill: fillStatus && fillStatus.hover, stroke: strokeStatus.hover }, press: { fill: fillStatus && fillStatus.press, stroke: strokeStatus.press }, }; }; export const getSnapInfos = (data: CircleData) => { return generateSnapInfos(getSnapPoints(data), true, false); }; export const getSnapPoints = (data: CircleData) => { const dec = new Transform(data.mat).decompose() const points = getRectSnapPoints(data.radiusX * 2, data.radiusY * 2).map((v) => ({ x: v.x + dec.x, y: v.y + dec.y, })); // const size = data.radius * 2; return points } export type CircleData = Partial & BaseItem & { opacity?: number, fill?: string mat: number[]; radiusX: number radiusY: number content?: string; padding?: number }; export const dataToConfig = (data: CircleData): CircleConfig => ({ ...defaultStyle, ...data, }); export const interactiveToData: InteractiveTo<'circle'> = ({ info, preset = {}, ...args }) => { if (info.cur) { const item = { ...defaultStyle, ...getBaseItem(), ...preset, } as unknown as CircleData; return interactiveFixData({ ...args, info, data: item }); } }; export const interactiveFixData: InteractiveFix<'circle'> = ({ data, info, }) => { const area = info.cur!; const sx = Math.abs((area[1].x - area[0].x)) / 2 const sy = Math.abs((area[1].y - area[0].y)) / 2 const center = lineCenter(area) data.mat = new Transform().translate(center.x, center.y).m data.radiusX = sx data.radiusY = sy return data; }; export const matResponse = ({data, mat, increment}: MatResponseProps<'circle'>, initRadius?: Pos) => { if (!initRadius) { initRadius = { x: data.radiusX, y: data.radiusY, }; } if (increment) { mat = mat.copy().multiply(new Transform(data.mat)) } const dec = mat.decompose(); data.radiusY = dec.scaleY * initRadius.y; data.radiusX = dec.scaleX * initRadius.x; data.mat = new Transform() .translate(dec.x, dec.y) .rotate(MathUtils.degToRad(dec.rotation)).m; return data; } export const getPredefine = (key: keyof CircleData) => { if (key === 'fill') { return { canun: true } } }