index.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { Pos } from "@/utils/math.ts";
  2. import { getMouseColors } from "@/utils/colors.ts";
  3. import { onlyId } from "@/utils/shared.ts";
  4. import { BaseItem, generateSnapInfos, getBaseItem } from "../util.ts";
  5. import { InteractiveFix, InteractiveTo, MatResponseProps } from "../index.ts";
  6. import { Transform } from "konva/lib/Util";
  7. export { default as Component } from "./rectangle.vue";
  8. export { default as TempComponent } from "./temp-rectangle.vue";
  9. export const shapeName = "矩形";
  10. export const defaultStyle = {
  11. dash: [30, 0],
  12. strokeWidth: 5,
  13. stroke: "#000000",
  14. fontSize: 22,
  15. align: "center",
  16. fontStyle: "normal",
  17. fontColor: "#000000",
  18. };
  19. export const getMouseStyle = (data: RectangleData) => {
  20. const fillStatus = data.fill && getMouseColors(data.fill);
  21. const strokeStatus = data.stroke && getMouseColors(data.stroke);
  22. const strokeWidth = data.strokeWidth;
  23. return {
  24. default: {
  25. fill: data.fill,
  26. stroke: data.stroke,
  27. strokeWidth,
  28. },
  29. hover: { fill: fillStatus && fillStatus.hover, stroke: strokeStatus && strokeStatus.hover },
  30. focus: { fill: fillStatus && fillStatus.hover, stroke: strokeStatus && strokeStatus.hover },
  31. press: { fill: fillStatus && fillStatus.press, stroke: strokeStatus && strokeStatus.press },
  32. select: {
  33. fill: fillStatus && fillStatus.select,
  34. stroke: strokeStatus && strokeStatus.select,
  35. },
  36. };
  37. };
  38. export const addMode = "area";
  39. export type RectangleData = Partial<typeof defaultStyle> &
  40. BaseItem & {
  41. id: string;
  42. attitude: number[];
  43. points: Pos[];
  44. createTime: number;
  45. zIndex: number;
  46. dash?: number[];
  47. stroke?: string;
  48. fill?: string;
  49. strokeWidth?: number;
  50. content?: string;
  51. };
  52. export const getSnapPoints = (data: RectangleData) => {
  53. return data.points;
  54. };
  55. export const getSnapInfos = (data: RectangleData) =>
  56. generateSnapInfos(getSnapPoints(data), true, false);
  57. export const interactiveToData: InteractiveTo<"rectangle"> = ({
  58. info,
  59. preset = {},
  60. ...args
  61. }) => {
  62. if (info.cur) {
  63. const item = {
  64. ...getBaseItem(),
  65. ...defaultStyle,
  66. ...preset,
  67. id: onlyId(),
  68. createTime: Date.now(),
  69. zIndex: 0,
  70. } as unknown as RectangleData;
  71. return interactiveFixData({ ...args, info, data: item });
  72. }
  73. };
  74. export const interactiveFixData: InteractiveFix<"rectangle"> = ({
  75. data,
  76. info,
  77. }) => {
  78. if (info.cur) {
  79. const area = info.cur!;
  80. const width = area[1].x - area[0].x;
  81. const height = area[1].y - area[0].y;
  82. data.points = [
  83. info.cur[0],
  84. { x: info.cur[0].x + width, y: info.cur[0].y },
  85. { x: info.cur[0].x + width, y: info.cur[0].y + height },
  86. { x: info.cur[0].x, y: info.cur[0].y + height },
  87. ];
  88. data.attitude = [1, 0, 0, 1, 0, 0];
  89. }
  90. return data;
  91. };
  92. export const matResponse = ({
  93. data,
  94. mat,
  95. increment,
  96. }: MatResponseProps<"rectangle">) => {
  97. let transfrom: Transform;
  98. const attitude = new Transform(data.attitude);
  99. if (!increment) {
  100. const inverMat = attitude.copy().invert();
  101. transfrom = mat.copy().multiply(inverMat);
  102. } else {
  103. transfrom = mat;
  104. }
  105. data.points = data.points.map((v) => transfrom.point(v));
  106. data.attitude = transfrom.copy().multiply(attitude).m;
  107. return data;
  108. };
  109. export const getPredefine = (key: keyof RectangleData) => {
  110. if (["fill", "stroke"].includes(key)) {
  111. return { canun: true };
  112. } else if (key === "strokeWidth") {
  113. return { proportion: true };
  114. }
  115. };