wangrong
2026-08-30 4c949c0dc9bcae785c281c9d8125295f09810b15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<script setup lang="ts">
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
import { storeToRefs } from 'pinia'
 
const dvMainStore = dvMainStoreWithOut()
const { fullscreenFlag } = storeToRefs(dvMainStore)
const dePreviewRef = ref(null)
const dePreviewOuterRef = ref(null)
const dataInitState = ref(true)
const keepProportion = ref('heightFirst')
const props = defineProps({
  canvasStylePreview: {
    required: true,
    type: Object
  },
  canvasDataPreview: {
    required: true,
    type: Object
  },
  canvasViewInfoPreview: {
    required: true,
    type: Object
  },
  dvInfo: {
    required: true,
    type: Object
  },
  curPreviewGap: {
    required: false,
    type: Number,
    default: 0
  },
  // 联动按钮位置
  showLinkageButton: {
    type: Boolean,
    default: true
  },
  showPosition: {
    required: false,
    type: String,
    default: 'preview'
  },
  // 显示悬浮按钮
  showPopBar: {
    type: Boolean,
    default: false
  },
  downloadStatus: {
    required: false,
    type: Boolean,
    default: false
  }
})
 
const restore = () => {
  dePreviewRef.value.restore()
}
const contentInnerClass = computed(() => {
  //屏幕适配方式 widthFirst=宽度优先(默认) heightFirst=高度优先 full=铺满全屏 keepSize=不缩放
  if (screenAdaptor.value === 'heightFirst') {
    return 'preview-content-inner-height-first'
  } else if (screenAdaptor.value === 'full') {
    return 'preview-content-inner-full'
  } else if (screenAdaptor.value === 'keep') {
    return 'preview-content-inner-size-keep'
  } else {
    return 'preview-content-inner-width-first'
  }
})
 
const outerStyle = computed(() => {
  return {
    flexDirection: props.canvasStylePreview.screenAdaptor === 'heightFirst' ? 'row' : 'column'
  }
})
 
const screenAdaptor = computed(() => {
  if (props.canvasStylePreview.screenAdaptor === 'keepProportion') {
    return keepProportion.value
  } else {
    return props.canvasStylePreview.screenAdaptor
  }
})
 
const keepProportionCheck = outerContentRect => {
  const { width, height } = outerContentRect
  const { innerWidth, innerHeight } = dePreviewRef.value.getPreviewCanvasSize()
  if (width > innerWidth || height < innerHeight) {
    keepProportion.value = 'heightFirst'
  } else {
    keepProportion.value = 'widthFirst'
  }
}
 
onMounted(() => {
  const observer = new ResizeObserver(entries => {
    for (let entry of entries) {
      console.log('元素新尺寸:', entry.contentRect)
      // entry.contentRect 包含 width, height, top, left 等属性
      keepProportionCheck(entry.contentRect)
    }
  })
 
  if (dePreviewOuterRef.value) {
    observer.observe(dePreviewOuterRef.value)
  }
 
  // 在组件卸载时停止观察
  onBeforeUnmount(() => {
    observer.disconnect()
  })
})
 
defineExpose({
  restore
})
</script>
 
<template>
  <div
    id="de-preview-content"
    ref="dePreviewOuterRef"
    :class="{ 'de-screen-full': fullscreenFlag }"
    :style="outerStyle"
    class="content-outer"
  >
    <div class="content-inner" :class="contentInnerClass">
      <de-preview
        ref="dePreviewRef"
        v-if="canvasStylePreview && dataInitState"
        :component-data="canvasDataPreview"
        :canvas-style-data="canvasStylePreview"
        :canvas-view-info="canvasViewInfoPreview"
        :dv-info="dvInfo"
        :cur-gap="curPreviewGap"
        :show-position="showPosition"
        :download-status="downloadStatus"
        :outer-screen-adaptor="screenAdaptor"
        :show-pop-bar="showPopBar"
        :show-linkage-button="showLinkageButton"
      ></de-preview>
    </div>
  </div>
</template>
 
<style lang="less">
.content-outer {
  width: 100%;
  height: calc(100vh - 112px);
  background: #f5f6f7;
  display: flex;
  overflow-y: auto;
  align-items: center;
  flex-direction: column;
  justify-content: center; /* 上下居中 */
  ::-webkit-scrollbar {
    display: none;
  }
}
</style>