temp-icon.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <template>
  2. <v-group :config="groupConfig" v-if="groupConfig && svg" ref="shape">
  3. <v-group :config="initDecMat" name="rep-position">
  4. <v-rect :config="rectConfig" name="repShape" />
  5. <Path
  6. v-for="config in pathConfigs"
  7. :config="(config as any)"
  8. :svg="svg"
  9. :mat="mat"
  10. />
  11. <!-- <v-path v-for="config in pathConfigs" :config="config" name="icon-path" /> -->
  12. </v-group>
  13. </v-group>
  14. </template>
  15. <script lang="ts" setup>
  16. import { defaultStyle, IconData } from "./icon.ts";
  17. import { computed, ref, watch } from "vue";
  18. import { getSvgContent, parseSvgContent, SVGParseResult } from "@/utils/resource.ts";
  19. import { Group } from "konva/lib/Group";
  20. import { DC } from "@/deconstruction.js";
  21. import { Transform } from "konva/lib/Util";
  22. import { useStore } from "@/core/store/index.ts";
  23. import { useHistory } from "@/core/hook/use-history.ts";
  24. import Path from "./temp-path.vue";
  25. const props = defineProps<{ data: IconData; addMode?: boolean }>();
  26. const svg = ref<SVGParseResult | null>(null);
  27. const shape = ref<DC<Group>>();
  28. const data = computed(() => ({ ...defaultStyle, ...props.data }));
  29. defineExpose({
  30. get shape() {
  31. return shape.value;
  32. },
  33. });
  34. const store = useStore();
  35. const history = useHistory();
  36. watch(
  37. () => data.value.url,
  38. async (url) => {
  39. svg.value = null;
  40. const svgContent = await getSvgContent(url);
  41. const content = parseSvgContent(svgContent);
  42. if (content.paths.length === 0) {
  43. svg.value = null;
  44. history.preventTrack(() => store.delItem("icon", props.data.id));
  45. } else {
  46. svg.value = content;
  47. }
  48. },
  49. { immediate: true }
  50. );
  51. const scale = computed(() => {
  52. if (!svg.value) return null;
  53. let w = data.value.width;
  54. let h = data.value.height;
  55. w = w || svg.value.width || 0;
  56. h = h || svg.value.height || 0;
  57. const scale = {
  58. x: w / svg.value.width,
  59. y: h / svg.value.height,
  60. };
  61. return scale;
  62. });
  63. const pathConfigs = computed(() => {
  64. if (!svg.value) return [];
  65. return svg.value.paths.map((path) => ({
  66. ...path,
  67. ...data.value,
  68. id: undefined,
  69. zIndex: undefined,
  70. offset: { x: svg.value!.x, y: svg.value!.y },
  71. }));
  72. });
  73. const initDecMat = computed(() => {
  74. if (!svg.value || !scale.value) return;
  75. return new Transform()
  76. .scale(scale.value.x, scale.value.y)
  77. .multiply(new Transform().translate(-svg.value.width / 2, -svg.value.height / 2))
  78. .decompose();
  79. });
  80. const mat = computed(() => new Transform(data.value.mat));
  81. const groupConfig = computed(() => {
  82. return {
  83. ...mat.value.decompose(),
  84. zIndex: undefined,
  85. listening: data.value.listening,
  86. id: data.value.id,
  87. opacity: props.addMode ? 0.3 : 1,
  88. };
  89. });
  90. const rectConfig = computed(() => {
  91. if (!svg.value) return null;
  92. return {
  93. fill: data.value.coverFill,
  94. id: "rep",
  95. stroke: data.value.coverStroke,
  96. opacity: data.value.coverOpcatiy,
  97. strokeWidth: data.value.coverStrokeWidth,
  98. width: svg.value.width,
  99. height: svg.value.height,
  100. };
  101. });
  102. </script>