|
@@ -1,187 +1,5 @@
|
|
|
-import { Transform } from "konva/lib/Util";
|
|
|
-import {
|
|
|
- BaseItem,
|
|
|
- generateSnapInfos,
|
|
|
- getBaseItem,
|
|
|
- getRectSnapPoints,
|
|
|
-} from "../util.ts";
|
|
|
-import { getMouseColors } from "@/utils/colors.ts";
|
|
|
-import { FixScreen } from "@/utils/bound.ts";
|
|
|
-import { InteractiveFix, InteractiveTo, MatResponseProps } from "../index.ts";
|
|
|
-import { Size } from "@/utils/math.ts";
|
|
|
-import { getSvgContent, parseSvgContent } from "@/utils/resource.ts";
|
|
|
-import { Color } from "three";
|
|
|
-
|
|
|
-export { default as Component } from "./icon.vue";
|
|
|
-export { default as TempComponent } from "./temp-icon.vue";
|
|
|
-
|
|
|
-export const shapeName = "图例";
|
|
|
-export const defaultStyle = {
|
|
|
- coverFill: '#000000',
|
|
|
- coverOpcatiy: 0,
|
|
|
- strokeScaleEnabled: false,
|
|
|
- width: 80,
|
|
|
- height: 80,
|
|
|
-};
|
|
|
-
|
|
|
- type ColorCounts = [string, number][]
|
|
|
- const colorsManage = (counts: ColorCounts, color: any) => {
|
|
|
- if (!color) {
|
|
|
- return;
|
|
|
- }
|
|
|
- const colorHex = new Color(color).getHexString()
|
|
|
- const item = counts.find(([c]) => c === colorHex)
|
|
|
- if (!item) {
|
|
|
- counts.push([colorHex, 1])
|
|
|
- } else {
|
|
|
- item[1]++
|
|
|
- }
|
|
|
-}
|
|
|
-const findColor = (counts: ColorCounts) => {
|
|
|
- let ndx = -1
|
|
|
- let max = 0
|
|
|
- for (let i = 0; i < counts.length; i++) {
|
|
|
- if (counts[i][1] >= max) {
|
|
|
- ndx = i
|
|
|
- max = counts[i][1]
|
|
|
- }
|
|
|
- }
|
|
|
- if (~ndx) {
|
|
|
- return `#${counts[ndx][0]}`
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-export const getIconStyle = async (url: string, width = defaultStyle.width, height = defaultStyle.height) => {
|
|
|
- const svgContent = parseSvgContent(await getSvgContent(url));
|
|
|
- if (width / height > svgContent.width / svgContent.height) {
|
|
|
- width = svgContent.width / svgContent.height * height
|
|
|
- } else {
|
|
|
- height = svgContent.height / svgContent.width * width
|
|
|
- }
|
|
|
- const fillColorCounts: [string, number][] = []
|
|
|
- const strokeColorCounts: [string, number][] = []
|
|
|
-
|
|
|
- for (let i = 0; i < svgContent.paths.length; i++) {
|
|
|
- colorsManage(fillColorCounts, svgContent.paths[i].fill)
|
|
|
- colorsManage(strokeColorCounts, svgContent.paths[i].stroke)
|
|
|
- }
|
|
|
-
|
|
|
- const color = {
|
|
|
- fill: findColor(fillColorCounts) || null,
|
|
|
- stroke: findColor(strokeColorCounts) || null
|
|
|
- };
|
|
|
- if (!color.fill && !color.stroke) {
|
|
|
- color.stroke = "#000000";
|
|
|
- }
|
|
|
- return {
|
|
|
- url,
|
|
|
- width,
|
|
|
- height,
|
|
|
- ...color
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-export const addMode = "dot";
|
|
|
-
|
|
|
-export const getSnapInfos = (data: IconData) => {
|
|
|
- return generateSnapInfos(getSnapPoints(data), true, false);
|
|
|
-};
|
|
|
-
|
|
|
-export const getSnapPoints = (data: IconData) => {
|
|
|
- const tf = new Transform(data.mat);
|
|
|
- const w = data.width || defaultStyle.width;
|
|
|
- const h = data.height || defaultStyle.height;
|
|
|
- const points = getRectSnapPoints(w, h);
|
|
|
- return points.map((v) => tf.point(v));
|
|
|
-};
|
|
|
-
|
|
|
-export const getMouseStyle = (data: IconData) => {
|
|
|
- const fillStatus = getMouseColors(data.coverFill || defaultStyle.coverFill);
|
|
|
- const hCoverOpcaoty = data.coverOpcatiy ? data.coverOpcatiy : 0.3;
|
|
|
-
|
|
|
- return {
|
|
|
- default: {
|
|
|
- coverFill: data.coverFill || defaultStyle.coverFill,
|
|
|
- coverOpcatiy: data.coverOpcatiy || 0,
|
|
|
- },
|
|
|
- hover: { coverFill: fillStatus.hover, coverOpcatiy: hCoverOpcaoty },
|
|
|
- select: { coverFill: fillStatus.select, coverOpcatiy: hCoverOpcaoty },
|
|
|
- focus: { coverFill: fillStatus.select, coverOpcatiy: hCoverOpcaoty },
|
|
|
- press: { coverFill: fillStatus.press, coverOpcatiy: hCoverOpcaoty },
|
|
|
- };
|
|
|
-};
|
|
|
-
|
|
|
-export type IconData = Partial<typeof defaultStyle> &
|
|
|
- BaseItem & Size & {
|
|
|
- fill?: string | null;
|
|
|
- stroke?: string | null;
|
|
|
- name?: string
|
|
|
- strokeWidth?: number;
|
|
|
- coverFill?: string;
|
|
|
- coverStroke?: string;
|
|
|
- coverStrokeWidth?: number;
|
|
|
- mat: number[];
|
|
|
- url: string;
|
|
|
- fixScreen?: FixScreen;
|
|
|
- };
|
|
|
-
|
|
|
-export const dataToConfig = (data: IconData) => {
|
|
|
- return {
|
|
|
- ...defaultStyle,
|
|
|
- ...data,
|
|
|
- };
|
|
|
-};
|
|
|
-
|
|
|
-export const interactiveToData: InteractiveTo<"icon"> = ({
|
|
|
- info,
|
|
|
- preset = {},
|
|
|
- viewTransform,
|
|
|
- ...args
|
|
|
-}) => {
|
|
|
- if (info.cur) {
|
|
|
- console.error(preset)
|
|
|
- return interactiveFixData({
|
|
|
- ...args,
|
|
|
- viewTransform,
|
|
|
- info,
|
|
|
- data: { ...getBaseItem(), ...preset } as unknown as IconData,
|
|
|
- });
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-export const interactiveFixData: InteractiveFix<"icon"> = ({
|
|
|
- data,
|
|
|
- info,
|
|
|
- viewTransform,
|
|
|
-}) => {
|
|
|
- if (data.fixScreen) {
|
|
|
- if ("x" in info.cur! && "y" in info.cur!) {
|
|
|
- // 存储屏幕坐标
|
|
|
- const screen = viewTransform.point(info.cur!);
|
|
|
- data.fixScreen = {
|
|
|
- left: screen.x,
|
|
|
- top: screen.y,
|
|
|
- };
|
|
|
- }
|
|
|
- data.mat = [1, 0, 0, 1, 0, 0];
|
|
|
- } else {
|
|
|
- const mat = new Transform().translate(info.cur!.x, info.cur!.y);
|
|
|
- data.mat = mat.m;
|
|
|
- }
|
|
|
- return data;
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-export const matResponse = ({data, mat, increment}: MatResponseProps<'icon'>) => {
|
|
|
- data.mat = increment ? mat.copy().multiply(new Transform(data.mat)).m : mat.m;
|
|
|
- return data;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-export const getPredefine = (key: keyof IconData) => {
|
|
|
- if (key === 'fill' || key === 'stroke') {
|
|
|
- return { canun: true }
|
|
|
- }
|
|
|
-}
|
|
|
+export * from './icon.ts'
|
|
|
+import TempComponent from "./temp-icon.vue";
|
|
|
+import Component from "./icon.vue";
|
|
|
+console.log(TempComponent)
|
|
|
+export { TempComponent, Component }
|