|
|
@@ -1,24 +1,27 @@
|
|
|
<template>
|
|
|
- <div style="height: 100vh">
|
|
|
+ <div ref="previewRootRef" class="mt-preview-root">
|
|
|
<el-scrollbar
|
|
|
ref="elScrollbarRef"
|
|
|
class="w-1/1 h-1/1"
|
|
|
- :max-height="canvas_cfg.height"
|
|
|
+ max-height="100vh"
|
|
|
@scroll="onScroll">
|
|
|
<div
|
|
|
- ref="canvasAreaRef"
|
|
|
- :class="`canvasArea ${mtPreviewProps.canDrag ? 'cursor-grab' : ''} `"
|
|
|
- @mousedown="onMouseDown"
|
|
|
- @wheel="onMouseWheel">
|
|
|
- <render-core
|
|
|
- v-model:done-json="done_json"
|
|
|
- :canvas-cfg="canvas_cfg"
|
|
|
- :grid-cfg="grid_cfg"
|
|
|
- :show-ghost-dom="false"
|
|
|
- :canvas-dom="canvasAreaRef"
|
|
|
- :global-lock="false"
|
|
|
- :preivew-mode="true"
|
|
|
- :show-popover="mtPreviewProps.showPopover" />
|
|
|
+ class="canvasStage">
|
|
|
+ <div
|
|
|
+ ref="canvasAreaRef"
|
|
|
+ :class="`canvasArea ${mtPreviewProps.canDrag ? 'cursor-grab' : ''} `"
|
|
|
+ @mousedown="onMouseDown"
|
|
|
+ @wheel="onMouseWheel">
|
|
|
+ <render-core
|
|
|
+ v-model:done-json="done_json"
|
|
|
+ :canvas-cfg="canvas_cfg"
|
|
|
+ :grid-cfg="grid_cfg"
|
|
|
+ :show-ghost-dom="false"
|
|
|
+ :canvas-dom="canvasAreaRef"
|
|
|
+ :global-lock="false"
|
|
|
+ :preivew-mode="true"
|
|
|
+ :show-popover="mtPreviewProps.showPopover" />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<drag-canvas
|
|
|
ref="dragCanvasRef"
|
|
|
@@ -30,7 +33,7 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, reactive, onMounted } from 'vue'
|
|
|
+import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
|
|
import RenderCore from '@/components/mt-edit/components/render-core/index.vue'
|
|
|
import type { IExportJson } from '../mt-edit/components/types'
|
|
|
import { useExportJsonToDoneJson } from '../mt-edit/composables'
|
|
|
@@ -43,13 +46,16 @@ type MtPreviewProps = {
|
|
|
canZoom?: boolean
|
|
|
canDrag?: boolean
|
|
|
showPopover?: boolean
|
|
|
+ fitScreen?: boolean
|
|
|
}
|
|
|
const mtPreviewProps = withDefaults(defineProps<MtPreviewProps>(), {
|
|
|
canDrag: true,
|
|
|
canZoom: true,
|
|
|
- showPopover: false
|
|
|
+ showPopover: false,
|
|
|
+ fitScreen: true
|
|
|
})
|
|
|
const emits = defineEmits(['onEventCallBack'])
|
|
|
+const previewRootRef = ref<HTMLElement>()
|
|
|
const canvasAreaRef = ref()
|
|
|
const canvas_cfg = ref({
|
|
|
width: 1920,
|
|
|
@@ -77,6 +83,9 @@ const grid_cfg = ref({
|
|
|
const done_json = ref<IDoneJson[]>([])
|
|
|
const elScrollbarRef = ref<InstanceType<typeof ElScrollbar>>()
|
|
|
const dragCanvasRef = ref<InstanceType<typeof DragCanvas>>()
|
|
|
+let resizeObserver: ResizeObserver | undefined
|
|
|
+const canvas_stage_width = computed(() => canvas_cfg.value.width * canvas_cfg.value.scale)
|
|
|
+const canvas_stage_height = computed(() => canvas_cfg.value.height * canvas_cfg.value.scale)
|
|
|
const scroll_info = reactive({
|
|
|
begin_left: 0,
|
|
|
begin_top: 0,
|
|
|
@@ -106,6 +115,23 @@ const dragCanvasMouseMove = (move_x: number, move_y: number) => {
|
|
|
* 画布拖动结束事件
|
|
|
*/
|
|
|
const dragCanvasMouseUp = () => {}
|
|
|
+const fitCanvasToScreen = () => {
|
|
|
+ if (!mtPreviewProps.fitScreen) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const rootRect = previewRootRef.value?.getBoundingClientRect()
|
|
|
+ if (!rootRect?.width || !rootRect?.height || !canvas_cfg.value.width || !canvas_cfg.value.height) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const scale = Math.min(rootRect.width / canvas_cfg.value.width, rootRect.height / canvas_cfg.value.height)
|
|
|
+ canvas_cfg.value.scale = Number(Math.max(scale, 0.01).toFixed(4))
|
|
|
+}
|
|
|
+const fitCanvasToScreenAfterRender = async () => {
|
|
|
+ await nextTick()
|
|
|
+ fitCanvasToScreen()
|
|
|
+}
|
|
|
const setItemAttrByID = (id: string, key: string, val: any) => {
|
|
|
return setItemAttr(id, key, val, done_json.value)
|
|
|
}
|
|
|
@@ -150,13 +176,24 @@ onMounted(() => {
|
|
|
canvas_cfg.value = canvasCfg
|
|
|
grid_cfg.value = gridCfg
|
|
|
done_json.value = importDoneJson
|
|
|
+ fitCanvasToScreenAfterRender()
|
|
|
+ }
|
|
|
+ if (previewRootRef.value) {
|
|
|
+ resizeObserver = new ResizeObserver(() => {
|
|
|
+ fitCanvasToScreen()
|
|
|
+ })
|
|
|
+ resizeObserver.observe(previewRootRef.value)
|
|
|
}
|
|
|
})
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ resizeObserver?.disconnect()
|
|
|
+})
|
|
|
const setImportJson = (exportJson: IExportJson) => {
|
|
|
const { canvasCfg, gridCfg, importDoneJson } = useExportJsonToDoneJson(exportJson)
|
|
|
canvas_cfg.value = canvasCfg
|
|
|
grid_cfg.value = gridCfg
|
|
|
done_json.value = importDoneJson
|
|
|
+ fitCanvasToScreenAfterRender()
|
|
|
return true
|
|
|
}
|
|
|
defineExpose({
|
|
|
@@ -166,8 +203,32 @@ defineExpose({
|
|
|
})
|
|
|
</script>
|
|
|
<style scoped>
|
|
|
-.canvasArea {
|
|
|
+.mt-preview-root {
|
|
|
+ width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+ overflow: hidden;
|
|
|
+ background-color: v-bind('canvas_cfg.color || "#fff"');
|
|
|
+}
|
|
|
+
|
|
|
+.mt-preview-root :deep(.el-scrollbar__view) {
|
|
|
+ min-width: 100%;
|
|
|
+ min-height: 100vh;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.canvasStage {
|
|
|
position: relative;
|
|
|
+ width: v-bind('canvas_stage_width + "px"');
|
|
|
+ height: v-bind('canvas_stage_height + "px"');
|
|
|
+ flex: 0 0 auto;
|
|
|
+}
|
|
|
+
|
|
|
+.canvasArea {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
width: v-bind('canvas_cfg.width + "px"');
|
|
|
height: v-bind('canvas_cfg.height + "px"');
|
|
|
background-color: v-bind('canvas_cfg.color');
|