CatPtain commited on
Commit
08a6186
·
verified ·
1 Parent(s): 1d4c41b

Upload public.js

Browse files
Files changed (1) hide show
  1. backend/src/routes/public.js +183 -50
backend/src/routes/public.js CHANGED
@@ -19,6 +19,68 @@ const generateSlideHTML = (pptData, slideIndex, title) => {
19
  const slide = pptData.slides[slideIndex];
20
  const theme = pptData.theme || {};
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  // 渲染幻灯片元素
23
  const renderElements = (elements) => {
24
  if (!elements || elements.length === 0) return '';
@@ -76,39 +138,41 @@ const generateSlideHTML = (pptData, slideIndex, title) => {
76
  <html lang="zh-CN">
77
  <head>
78
  <meta charset="UTF-8">
79
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
80
  <title>${title} - 第${slideIndex + 1}页</title>
81
  <style>
82
  * {
83
- margin: 0;
84
- padding: 0;
85
- box-sizing: border-box;
86
  }
87
 
88
- html, body {
89
- width: 100%;
90
- height: 100%;
91
- overflow: hidden;
92
- font-family: 'Microsoft YaHei', Arial, sans-serif;
93
- background-color: #000;
94
  }
95
 
96
- .viewport-container {
97
- width: 100vw;
98
- height: 100vh;
99
- display: flex;
100
- justify-content: center;
101
- align-items: center;
102
- background-color: #000;
 
 
103
  }
104
 
105
  .slide-container {
106
- width: 1000px;
107
- height: 750px;
108
- background-color: ${slide.background?.color || theme.backgroundColor || '#ffffff'};
109
- position: relative;
110
- transform-origin: center center;
111
- overflow: hidden;
 
112
  }
113
 
114
  ${slide.background?.type === 'image' ? `
@@ -126,44 +190,113 @@ const generateSlideHTML = (pptData, slideIndex, title) => {
126
  z-index: 0;
127
  }
128
  ` : ''}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  </style>
 
 
 
 
 
 
 
 
 
 
130
  </head>
131
- <body>
132
- <div class="viewport-container">
133
- <div class="slide-container" id="slideContainer">
134
- ${renderElements(slide.elements)}
135
- </div>
136
  </div>
137
 
138
  <script>
139
- function resizeSlide() {
140
- const container = document.getElementById('slideContainer');
141
- const viewport = container.parentElement;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
- // PPT标准尺寸 (4:3 比例)
144
- const slideWidth = 1000;
145
- const slideHeight = 750;
 
 
 
 
 
 
 
 
 
 
146
 
147
- // 窗口尺寸
148
- const windowWidth = viewport.clientWidth;
149
- const windowHeight = viewport.clientHeight;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
151
- // 计算缩放比例,使PPT填满窗口
152
- const scaleX = windowWidth / slideWidth;
153
- const scaleY = windowHeight / slideHeight;
154
- const scale = Math.max(scaleX, scaleY); // 使用较大的缩放比例以填满窗口
155
 
156
- // 应用缩放
157
- container.style.transform = \`scale(\${scale})\`;
158
 
159
- console.log(\`Window: \${windowWidth}x\${windowHeight}, Scale: \${scale}\`);
 
160
  }
161
-
162
- // 页面加载时调整大小
163
- window.addEventListener('load', resizeSlide);
164
-
165
- // 窗口大小改变时重新调整
166
- window.addEventListener('resize', resizeSlide);
167
  </script>
168
  </body>
169
  </html>
 
19
  const slide = pptData.slides[slideIndex];
20
  const theme = pptData.theme || {};
21
 
22
+ // 优化的PPT尺寸计算函数 - 确保长宽比一致性
23
+ const calculatePptDimensions = (slide) => {
24
+ if (!slide.elements || slide.elements.length === 0) {
25
+ // 如果没有元素,使用标准PPT 16:9 比例
26
+ return { width: 1280, height: 720 };
27
+ }
28
+
29
+ let maxRight = 0;
30
+ let maxBottom = 0;
31
+ let minLeft = Infinity;
32
+ let minTop = Infinity;
33
+
34
+ slide.elements.forEach(element => {
35
+ const left = element.left || 0;
36
+ const top = element.top || 0;
37
+ const width = element.width || 0;
38
+ const height = element.height || 0;
39
+
40
+ // 计算元素的边界
41
+ const elementRight = left + width;
42
+ const elementBottom = top + height;
43
+
44
+ maxRight = Math.max(maxRight, elementRight);
45
+ maxBottom = Math.max(maxBottom, elementBottom);
46
+ minLeft = Math.min(minLeft, left);
47
+ minTop = Math.min(minTop, top);
48
+ });
49
+
50
+ // 确保有最小边距
51
+ const padding = 40;
52
+ const contentWidth = maxRight - Math.max(0, minLeft);
53
+ const contentHeight = maxBottom - Math.max(0, minTop);
54
+
55
+ // 计算最终尺寸,保持合理的长宽比
56
+ let finalWidth = Math.max(contentWidth + padding * 2, 800);
57
+ let finalHeight = Math.max(contentHeight + padding * 2, 600);
58
+
59
+ // 确保长宽比合理(介于4:3到16:9之间)
60
+ const aspectRatio = finalWidth / finalHeight;
61
+ const minRatio = 4/3; // 1.33
62
+ const maxRatio = 16/9; // 1.78
63
+
64
+ if (aspectRatio < minRatio) {
65
+ // 太高了,调整宽度
66
+ finalWidth = finalHeight * minRatio;
67
+ } else if (aspectRatio > maxRatio) {
68
+ // 太宽了,调整高度
69
+ finalHeight = finalWidth / maxRatio;
70
+ }
71
+
72
+ const result = {
73
+ width: Math.round(finalWidth),
74
+ height: Math.round(finalHeight)
75
+ };
76
+
77
+ console.log(`PPT dimensions calculated: ${result.width}x${result.height} (aspect ratio: ${(result.width/result.height).toFixed(2)})`);
78
+
79
+ return result;
80
+ };
81
+
82
+ const pptDimensions = calculatePptDimensions(slide);
83
+
84
  // 渲染幻灯片元素
85
  const renderElements = (elements) => {
86
  if (!elements || elements.length === 0) return '';
 
138
  <html lang="zh-CN">
139
  <head>
140
  <meta charset="UTF-8">
141
+ <meta name="viewport" content="width=${pptDimensions.width}, height=${pptDimensions.height}, initial-scale=1.0, user-scalable=no">
142
  <title>${title} - 第${slideIndex + 1}页</title>
143
  <style>
144
  * {
145
+ margin: 0 !important;
146
+ padding: 0 !important;
147
+ box-sizing: border-box !important;
148
  }
149
 
150
+ html {
151
+ width: 100vw !important;
152
+ height: 100vh !important;
153
+ overflow: hidden !important;
154
+ background-color: #000 !important;
 
155
  }
156
 
157
+ body {
158
+ width: 100vw !important;
159
+ height: 100vh !important;
160
+ overflow: hidden !important;
161
+ font-family: 'Microsoft YaHei', Arial, sans-serif !important;
162
+ background-color: #000 !important;
163
+ display: flex !important;
164
+ align-items: center !important;
165
+ justify-content: center !important;
166
  }
167
 
168
  .slide-container {
169
+ width: ${pptDimensions.width}px !important;
170
+ height: ${pptDimensions.height}px !important;
171
+ background-color: ${slide.background?.color || theme.backgroundColor || '#ffffff'} !important;
172
+ position: relative !important;
173
+ overflow: hidden !important;
174
+ box-shadow: 0 0 20px rgba(255,255,255,0.1) !important;
175
+ transform-origin: center center !important;
176
  }
177
 
178
  ${slide.background?.type === 'image' ? `
 
190
  z-index: 0;
191
  }
192
  ` : ''}
193
+
194
+ /* 隐藏滚动条 */
195
+ ::-webkit-scrollbar {
196
+ display: none;
197
+ }
198
+
199
+ /* 截图模式样式 */
200
+ .screenshot-mode {
201
+ background-color: transparent !important;
202
+ }
203
+
204
+ .screenshot-mode body {
205
+ background-color: transparent !important;
206
+ width: ${pptDimensions.width}px !important;
207
+ height: ${pptDimensions.height}px !important;
208
+ display: block !important;
209
+ }
210
+
211
+ .screenshot-mode .slide-container {
212
+ position: absolute !important;
213
+ top: 0 !important;
214
+ left: 0 !important;
215
+ transform: none !important;
216
+ box-shadow: none !important;
217
+ }
218
  </style>
219
+ <script>
220
+ // 将PPT尺寸信息传递给JavaScript,用于截图服务
221
+ window.PPT_DIMENSIONS = {
222
+ width: ${pptDimensions.width},
223
+ height: ${pptDimensions.height}
224
+ };
225
+
226
+ // 截图模式标识
227
+ window.SCREENSHOT_MODE = window.location.search.includes('screenshot=true');
228
+ </script>
229
  </head>
230
+ <body${slide.background?.type === 'image' && slide.background?.image ? '' : ''}>
231
+ <div class="slide-container" id="slideContainer">
232
+ ${renderElements(slide.elements)}
 
 
233
  </div>
234
 
235
  <script>
236
+ console.log('PPT页面加载完成');
237
+ console.log('PPT尺寸:', window.PPT_DIMENSIONS);
238
+ console.log('截图模式:', window.SCREENSHOT_MODE);
239
+
240
+ // 根据模式应用不同的样式和行为
241
+ if (window.SCREENSHOT_MODE) {
242
+ // 截图模式:固定尺寸,无缩放
243
+ document.documentElement.classList.add('screenshot-mode');
244
+ document.body.style.cssText = \`
245
+ width: ${pptDimensions.width}px !important;
246
+ height: ${pptDimensions.height}px !important;
247
+ background: transparent !important;
248
+ overflow: hidden !important;
249
+ margin: 0 !important;
250
+ padding: 0 !important;
251
+ display: block !important;
252
+ \`;
253
 
254
+ const container = document.getElementById('slideContainer');
255
+ if (container) {
256
+ container.style.cssText = \`
257
+ width: ${pptDimensions.width}px !important;
258
+ height: ${pptDimensions.height}px !important;
259
+ position: absolute !important;
260
+ top: 0 !important;
261
+ left: 0 !important;
262
+ transform: none !important;
263
+ box-shadow: none !important;
264
+ background-color: ${slide.background?.color || theme.backgroundColor || '#ffffff'} !important;
265
+ \`;
266
+ }
267
 
268
+ console.log('截图模式样式已应用');
269
+ } else {
270
+ // 网页浏览模式:响应式缩放,保持长宽比
271
+ function resizeSlide() {
272
+ const container = document.getElementById('slideContainer');
273
+ const slideWidth = window.PPT_DIMENSIONS.width;
274
+ const slideHeight = window.PPT_DIMENSIONS.height;
275
+
276
+ // 窗口尺寸
277
+ const windowWidth = window.innerWidth;
278
+ const windowHeight = window.innerHeight;
279
+
280
+ // 计算缩放比例,保持宽高比
281
+ const scaleX = (windowWidth - 40) / slideWidth; // 留20px边距
282
+ const scaleY = (windowHeight - 40) / slideHeight;
283
+ const scale = Math.min(scaleX, scaleY, 1); // 最大不超过1倍
284
+
285
+ // 应用缩放
286
+ container.style.transform = \`scale(\${scale})\`;
287
+
288
+ console.log(\`响应式缩放应用: \${scale.toFixed(3)}x (窗口: \${windowWidth}x\${windowHeight}, PPT: \${slideWidth}x\${slideHeight})\`);
289
+ }
290
 
291
+ // 页面加载时调整大小
292
+ window.addEventListener('load', resizeSlide);
 
 
293
 
294
+ // 窗口大小改变时重新调整
295
+ window.addEventListener('resize', resizeSlide);
296
 
297
+ // 立即执行一次
298
+ resizeSlide();
299
  }
 
 
 
 
 
 
300
  </script>
301
  </body>
302
  </html>