CatPtain commited on
Commit
1bff263
·
verified ·
1 Parent(s): 10b14be

Upload public.js

Browse files
Files changed (1) hide show
  1. backend/src/routes/public.js +117 -56
backend/src/routes/public.js CHANGED
@@ -19,8 +19,10 @@ const generateSlideHTML = (pptData, slideIndex, title) => {
19
  const slide = pptData.slides[slideIndex];
20
  const theme = pptData.theme || {};
21
 
22
- // 精确计算PPT内容的真实尺寸 - 使用编辑器的实际尺寸数据
23
  const calculatePptDimensions = (slide) => {
 
 
24
  // 1. 优先使用PPT数据中的viewportSize和viewportRatio(编辑器的真实尺寸)
25
  if (pptData.viewportSize && pptData.viewportRatio) {
26
  const result = {
@@ -61,65 +63,124 @@ const generateSlideHTML = (pptData, slideIndex, title) => {
61
  return result;
62
  }
63
 
64
- // 5. 根据元素分布计算合适的尺寸
65
- if (!slide.elements || slide.elements.length === 0) {
66
- // 如果没有元素,使用标准PPT尺寸 - 使用PPTist默认尺寸
67
- const result = { width: 900, height: 506 }; // 16:9标准比例 (viewportSize: 900, viewportRatio: 0.5625)
68
- console.log(`使用默认尺寸: ${result.width}x${result.height} (16:9比例)`);
69
- return result;
70
- }
71
-
72
- let maxRight = 0;
73
- let maxBottom = 0;
74
- let minLeft = Infinity;
75
- let minTop = Infinity;
76
-
77
- // 计算所有元素的实际边界
78
- slide.elements.forEach(element => {
79
- const left = element.left || 0;
80
- const top = element.top || 0;
81
- const width = element.width || 0;
82
- const height = element.height || 0;
83
 
84
- const elementRight = left + width;
85
- const elementBottom = top + height;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
- maxRight = Math.max(maxRight, elementRight);
88
- maxBottom = Math.max(maxBottom, elementBottom);
89
- minLeft = Math.min(minLeft, left);
90
- minTop = Math.min(minTop, top);
91
- });
92
-
93
- // 重置无限值
94
- if (minLeft === Infinity) minLeft = 0;
95
- if (minTop === Infinity) minTop = 0;
96
-
97
- // 计算内容区域的实际尺寸
98
- const contentWidth = maxRight - minLeft;
99
- const contentHeight = maxBottom - minTop;
100
-
101
- // 添加适当的边距,确保内容不被裁切
102
- const paddingX = Math.max(40, Math.abs(minLeft));
103
- const paddingY = Math.max(40, Math.abs(minTop));
104
-
105
- // 计算最终的PPT尺寸,但限制在合理范围内
106
- let finalWidth = Math.max(contentWidth + paddingX * 2, 900);
107
- let finalHeight = Math.max(contentHeight + paddingY * 2, 506);
108
-
109
- // 如果计算出的尺寸过大,使用标准比例缩放
110
- if (finalWidth > 1920 || finalHeight > 1080) {
111
- const scale = Math.min(1920 / finalWidth, 1080 / finalHeight);
112
- finalWidth = Math.ceil(finalWidth * scale);
113
- finalHeight = Math.ceil(finalHeight * scale);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }
115
 
116
- // 确保尺寸为偶数(避免半像素问题)
117
- finalWidth = Math.ceil(finalWidth / 2) * 2;
118
- finalHeight = Math.ceil(finalHeight / 2) * 2;
119
-
120
- const result = { width: finalWidth, height: finalHeight };
121
- console.log(`根据元素计算尺寸: ${result.width}x${result.height}`);
122
-
123
  return result;
124
  };
125
 
 
19
  const slide = pptData.slides[slideIndex];
20
  const theme = pptData.theme || {};
21
 
22
+ // 精确计算PPT内容的真实尺寸 - 基于填满画布的图像元素推断
23
  const calculatePptDimensions = (slide) => {
24
+ console.log('开始计算PPT尺寸,当前slide元素数量:', slide.elements?.length || 0);
25
+
26
  // 1. 优先使用PPT数据中的viewportSize和viewportRatio(编辑器的真实尺寸)
27
  if (pptData.viewportSize && pptData.viewportRatio) {
28
  const result = {
 
63
  return result;
64
  }
65
 
66
+ // 5. 基于填满画布的图像元素精确推断PPT尺寸
67
+ if (slide.elements && slide.elements.length > 0) {
68
+ // 寻找可能填满画布的图像元素(left=0, top=0 或接近0,且尺寸较大)
69
+ const candidateImages = slide.elements.filter(element =>
70
+ element.type === 'image' &&
71
+ Math.abs(element.left || 0) <= 10 && // 允许小偏差
72
+ Math.abs(element.top || 0) <= 10 && // 允许小偏差
73
+ (element.width || 0) >= 800 && // 宽度至少800
74
+ (element.height || 0) >= 400 // 高度至少400
75
+ );
 
 
 
 
 
 
 
 
 
76
 
77
+ if (candidateImages.length > 0) {
78
+ // 使用面积最大的图像作为画布尺寸参考
79
+ const referenceImage = candidateImages.reduce((max, current) => {
80
+ const maxArea = (max.width || 0) * (max.height || 0);
81
+ const currentArea = (current.width || 0) * (current.height || 0);
82
+ return currentArea > maxArea ? current : max;
83
+ });
84
+
85
+ const result = {
86
+ width: Math.ceil(referenceImage.width || 1000),
87
+ height: Math.ceil(referenceImage.height || 562)
88
+ };
89
+
90
+ console.log(`基于填满画布的图像推断PPT尺寸: ${result.width}x${result.height} (参考图像: ${referenceImage.id})`);
91
+ console.log(`参考图像信息: left=${referenceImage.left}, top=${referenceImage.top}, width=${referenceImage.width}, height=${referenceImage.height}`);
92
+
93
+ return result;
94
+ }
95
 
96
+ // 如果没有找到填满画布的图像,回退到边界计算
97
+ let maxRight = 0;
98
+ let maxBottom = 0;
99
+ let minLeft = Infinity;
100
+ let minTop = Infinity;
101
+
102
+ // 计算所有元素的实际边界
103
+ slide.elements.forEach(element => {
104
+ const left = element.left || 0;
105
+ const top = element.top || 0;
106
+ const width = element.width || 0;
107
+ const height = element.height || 0;
108
+
109
+ const elementRight = left + width;
110
+ const elementBottom = top + height;
111
+
112
+ maxRight = Math.max(maxRight, elementRight);
113
+ maxBottom = Math.max(maxBottom, elementBottom);
114
+ minLeft = Math.min(minLeft, left);
115
+ minTop = Math.min(minTop, top);
116
+
117
+ console.log(`元素 ${element.id}: type=${element.type}, left=${left}, top=${top}, width=${width}, height=${height}, right=${elementRight}, bottom=${elementBottom}`);
118
+ });
119
+
120
+ // 重置无限值
121
+ if (minLeft === Infinity) minLeft = 0;
122
+ if (minTop === Infinity) minTop = 0;
123
+
124
+ console.log(`元素边界: minLeft=${minLeft}, minTop=${minTop}, maxRight=${maxRight}, maxBottom=${maxBottom}`);
125
+
126
+ // 根据实际元素分布确定画布尺寸
127
+ const canvasLeft = Math.min(0, minLeft);
128
+ const canvasTop = Math.min(0, minTop);
129
+ const canvasRight = Math.max(maxRight, 1000); // 最小宽度1000(基于GitHub数据)
130
+ const canvasBottom = Math.max(maxBottom, 562); // 最小高度562(基于GitHub数据)
131
+
132
+ // 计算最终的画布尺寸
133
+ let finalWidth = canvasRight - canvasLeft;
134
+ let finalHeight = canvasBottom - canvasTop;
135
+
136
+ // 基于从GitHub仓库观察到的实际比例进行智能调整
137
+ const currentRatio = finalWidth / finalHeight;
138
+ console.log(`当前计算比例: ${currentRatio.toFixed(3)}`);
139
+
140
+ // 从GitHub数据分析:1000x562.5 ≈ 1.78 (接近16:9的1.77)
141
+ const targetRatio = 1000 / 562.5; // ≈ 1.778
142
+
143
+ // 如果比例接近观察到的标准比例,调整为精确比例
144
+ if (Math.abs(currentRatio - targetRatio) < 0.2) {
145
+ if (finalWidth > finalHeight * targetRatio) {
146
+ finalHeight = finalWidth / targetRatio;
147
+ } else {
148
+ finalWidth = finalHeight * targetRatio;
149
+ }
150
+ console.log(`调整为GitHub观察到的标准比例: ${targetRatio.toFixed(3)}`);
151
+ }
152
+ // 如果比例接近16:9,调整为标准16:9
153
+ else if (Math.abs(currentRatio - 16/9) < 0.1) {
154
+ if (finalWidth > finalHeight * 16/9) {
155
+ finalHeight = finalWidth / (16/9);
156
+ } else {
157
+ finalWidth = finalHeight * (16/9);
158
+ }
159
+ console.log(`调整为16:9比例`);
160
+ }
161
+ // 如果比例接近4:3,调整为标准4:3
162
+ else if (Math.abs(currentRatio - 4/3) < 0.1) {
163
+ if (finalWidth > finalHeight * 4/3) {
164
+ finalHeight = finalWidth / (4/3);
165
+ } else {
166
+ finalWidth = finalHeight * (4/3);
167
+ }
168
+ console.log(`调整为4:3比例`);
169
+ }
170
+
171
+ // 确保尺寸为偶数(避免半像素问题)
172
+ finalWidth = Math.ceil(finalWidth / 2) * 2;
173
+ finalHeight = Math.ceil(finalHeight / 2) * 2;
174
+
175
+ const result = { width: finalWidth, height: finalHeight };
176
+ console.log(`根据元素边界计算最终尺寸: ${result.width}x${result.height}, 比例: ${(result.width/result.height).toFixed(3)}`);
177
+
178
+ return result;
179
  }
180
 
181
+ // 6. 如果没有元素,使用从GitHub数据分析得出的标准尺寸
182
+ const result = { width: 1000, height: 562 }; // 基于GitHub仓库中观察到的实际数据
183
+ console.log(`使用GitHub数据分析的默认尺寸: ${result.width}x${result.height} (1000x562, 比例≈1.78)`);
 
 
 
 
184
  return result;
185
  };
186