header.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <template>
  2. <Header :action-groups="actions" title="图纸" :draw="draw">
  3. <template #saves>
  4. <el-button type="primary" @click="saveHandler">保存</el-button>
  5. </template>
  6. </Header>
  7. </template>
  8. <script lang="ts" setup>
  9. import { ElButton, ElMessage } from "element-plus";
  10. import { useDraw } from "../../../components/container/use-draw.ts";
  11. import Header from "../../../components/header/index.vue";
  12. import { getHeaderActions } from "../../../components/header/actions.ts";
  13. import { saveTabulationData } from "../../req.ts";
  14. import { Transform } from "konva/lib/Util";
  15. import { selectExposeFormat } from "@/example/dialog/expose/index.ts";
  16. import { grayscaleImage } from "@/utils/dom.ts";
  17. import saveAs from "@/utils/file-serve.ts";
  18. import { jsPDF } from "jspdf";
  19. import { getImage as getResourceImage } from "@/utils/resource.ts";
  20. import { nextTick } from "vue";
  21. import { tabulationData } from "../../store.ts";
  22. const draw = useDraw();
  23. const baseActions = getHeaderActions(draw);
  24. const actions = [
  25. [baseActions.undo, baseActions.redo],
  26. [
  27. baseActions.clear,
  28. {
  29. ...baseActions.initViewport,
  30. handler: () => {
  31. draw.viewer.setViewMat(new Transform());
  32. },
  33. },
  34. ],
  35. [
  36. {
  37. handler: async () => {
  38. const ef = await selectExposeFormat();
  39. const format = "image/jpeg";
  40. let [rect, fileBlob] = await draw.enterTemp(async () => {
  41. const oldMat = draw.viewer.viewMat;
  42. draw.viewer.setViewMat([1, 0, 0, 1, 0, 0]);
  43. await nextTick();
  44. const viewSize = draw.viewer.viewSize!;
  45. const size = {
  46. width: draw.stage!.width(),
  47. height: draw.stage!.height(),
  48. };
  49. const rect = {
  50. x: (size.width - viewSize.width) / 2,
  51. y: (size.height - viewSize.height) / 2,
  52. ...viewSize,
  53. };
  54. let fileBlob = await (draw.stage!.toBlob({
  55. pixelRatio: 4,
  56. mimeType: format,
  57. quality: 1,
  58. ...rect,
  59. }) as Promise<Blob>);
  60. draw.viewer.setViewMat(oldMat);
  61. return [rect, fileBlob] as const;
  62. });
  63. const filename = "canvas";
  64. let ext = "jpg";
  65. if (ef.color === "grayscale") {
  66. const url = URL.createObjectURL(fileBlob);
  67. const img = await getResourceImage(url);
  68. fileBlob = await grayscaleImage(img, undefined, format);
  69. URL.revokeObjectURL(url);
  70. }
  71. if (ef.format === "PDF") {
  72. const url = URL.createObjectURL(fileBlob);
  73. const img = await getResourceImage(url);
  74. const pdf = new jsPDF(rect.width > rect.height ? "l" : "p", "px", [
  75. rect.width,
  76. rect.height,
  77. ]);
  78. pdf.addImage(img, format, 0, 0, rect.width, rect.height);
  79. fileBlob = pdf.output("blob");
  80. ext = "pdf";
  81. URL.revokeObjectURL(url);
  82. }
  83. await saveAs(fileBlob, `${filename}.${ext}`);
  84. ElMessage.success("导出成功");
  85. },
  86. text: "导出",
  87. icon: "download",
  88. },
  89. ],
  90. ];
  91. const saveHandler = () => {
  92. saveTabulationData({
  93. store: draw!.getData(),
  94. viewport: draw!.viewer.transform.m,
  95. paperKey: tabulationData.value.paperKey,
  96. });
  97. };
  98. </script>