container.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <div class="layout" :class="{ full }">
  3. <slot name="header" class="header" v-if="draw" :draw="draw" />
  4. <div class="container">
  5. <slot name="slide" class="slide" v-if="draw" :draw="draw" />
  6. <div class="content" ref="drawEle">
  7. <DrawBoard v-if="drawEle" :handler-resource="uploadResourse" ref="draw" />
  8. <slot name="cover" v-if="draw" :draw="draw" />
  9. </div>
  10. <div class="confirm-items">
  11. <ElButton
  12. @click="draw.quitDrawShape()"
  13. circle
  14. class="h-bottom"
  15. v-if="draw?.drawing"
  16. >
  17. <template #icon>
  18. <icon name="pic_yes" size="32px" color="#41c732" />
  19. </template>
  20. </ElButton>
  21. </div>
  22. </div>
  23. </div>
  24. </template>
  25. <script lang="ts" setup>
  26. import { onUnmounted, ref, watch } from "vue";
  27. import { DrawBoard } from "@/index";
  28. import { listener } from "@/utils/event.ts";
  29. import { ElMessage, ElButton } from "element-plus";
  30. import { mergeFuns, startAnimation } from "@/utils/shared";
  31. import { installDraw } from "./use-draw";
  32. const props = defineProps<{
  33. full: boolean;
  34. uploadResourse: (file: File) => Promise<string>;
  35. }>();
  36. const emit = defineEmits<{ (e: "update:full", full: boolean): void }>();
  37. const drawEle = ref<HTMLDivElement | null>(null);
  38. const draw = installDraw(ref());
  39. watch(
  40. () => props.full,
  41. (_f1, _f2, onCleanup) => {
  42. const hideMsg =
  43. props.full &&
  44. ElMessage.warning({
  45. message: "按ESC键可退出全屏模式",
  46. duration: 3000,
  47. });
  48. const stopAnimation = startAnimation(() => {
  49. draw.value?.updateSize();
  50. }, 400);
  51. onCleanup(mergeFuns([() => hideMsg && hideMsg.close(), stopAnimation]));
  52. }
  53. );
  54. onUnmounted(
  55. listener(document.documentElement, "keyup", (ev) => {
  56. if (ev.key === "Escape") {
  57. emit("update:full", false);
  58. }
  59. })
  60. );
  61. defineExpose({
  62. get draw() {
  63. return draw.value;
  64. },
  65. });
  66. </script>
  67. <style lang="scss" scoped>
  68. @use '../../styles/global';
  69. .layout {
  70. display: flex;
  71. flex-direction: column;
  72. align-items: stretch;
  73. height: 100vh;
  74. background: #f0f2f5;
  75. --top: 0px;
  76. --left: 0px;
  77. overflow: hidden;
  78. .container {
  79. height: calc(100vh - #{global.$headerSize} - var(--top));
  80. display: flex;
  81. align-items: stretch;
  82. }
  83. .content {
  84. position: relative;
  85. width: calc(100% - 70px - var(--left));
  86. }
  87. &.full {
  88. --top: calc(-1 * #{global.$headerSize});
  89. --left: calc(-1 * #{global.$slideSize});
  90. }
  91. }
  92. .confirm-items {
  93. position: absolute;
  94. bottom: #{global.$bottomSize};
  95. left: 50%;
  96. transform: translateX(-50%);
  97. }
  98. .h-bottom {
  99. width: 64px;
  100. height: 64px;
  101. box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.3);
  102. }
  103. </style>