返回 Pixelle-Video
image_satirical_cartoon.html
根目录 / templates / 1080x1920 / image_satirical_cartoon.html
1 <!DOCTYPE html>
2 <html lang="zh-CN">
3 <head>
4 <meta charset="UTF-8">
5 <meta name="template:media-width" content="1024">
6 <meta name="template:media-height" content="1024">
7 <meta name="viewport" content="width=1080, height=1920">
8 <title>80年代讽刺漫画风格 全屏图片 只有标题 - 1080x1920</title>
9 <!-- Google Fonts - 中文字体 -->
10 <link rel="preconnect" href="https://fonts.googleapis.com">
11 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
12 <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700;900&family=Noto+Serif+SC:wght@400;700;900&family=Liu+Jian+Mao+Cao&family=Ma+Shan+Zheng&display=swap" rel="stylesheet">
13 <style>
14
15 * { margin: 0; padding: 0; box-sizing: border-box; }
16
17 html, body { width: 1080px; height: 1920px; overflow: hidden; }
18
19 body {
20 font-family: 'Noto Sans SC', 'PingFang SC', 'Source Han Sans', 'Microsoft YaHei', -apple-system, BlinkMacSystemFont, sans-serif;
21 color: #fff;
22 position: relative;
23 background: transparent; /* 移除黑色背景 */
24 }
25
26 /* 背景使用图片并做模糊处理,完全覆盖整个页面 */
27 .bg {
28 position: relative;
29 width: 100%;
30 height: 100%;
31 background-image: url("{{image}}");
32 background-size: cover;
33 background-position: center;
34 z-index: 0;
35 display: flex;
36 justify-content: center;
37 align-items: center;
38 }
39
40 .title {
41 width: 900px;
42 text-align: center;
43 font-size: 92px;
44 font-weight: 800;
45 line-height: 1.2;
46 text-shadow: 0 6px 22px rgba(0,0,0,0.6),
47 -2px -2px 0 #000,
48 2px -2px 0 #000,
49 -2px 2px 0 #000,
50 2px 2px 0 #000;
51 letter-spacing: 4px;
52 /* 确保文本不会溢出 */
53 word-wrap: break-word;
54 overflow-wrap: break-word;
55 white-space: nowrap;
56 }
57
58 /* Footer */
59 .footer {
60 display: flex;
61 align-items: center;
62 justify-content: space-between;
63 width: 100%;
64 padding: 25px 20px 0 20px;
65 position: absolute;
66 bottom: 20px;
67 color: #fff;
68 text-shadow: -1px -1px 0 #000,
69 1px -1px 0 #000,
70 -1px 1px 0 #000,
71 1px 1px 0 #000;
72 }
73
74 .author {
75 display: flex;
76 flex-direction: column;
77 gap: 6px;
78 letter-spacing: 2px;
79 }
80
81 .author-name {
82 font-size: 30px;
83 font-weight: 600;
84 display: flex;
85 align-items: center;
86 gap: 10px;
87 }
88
89 .author-mark {
90 width: 8px;
91 height: 8px;
92 /* border-radius: 50%; */
93 /* background: rgba(149, 165, 166, 0.7); */
94 }
95
96 .author-desc {
97 font-size: 22px;
98 /* color: #5d6d7e; */
99 line-height: 1.3;
100 font-weight: 400;
101 }
102
103 .logo-section {
104 display: flex;
105 flex-direction: column;
106 align-items: flex-end;
107 gap: 8px;
108 }
109
110 .logo {
111 font-size: 24px;
112 font-weight: 500;
113 }
114
115 .logo-marks {
116 display: flex;
117 gap: 5px;
118 }
119
120 .logo-mark {
121 width: 6px;
122 height: 6px;
123 border-radius: 50%;
124 background: rgba(149, 165, 166, 0.45);
125 }
126
127 .logo-mark.active {
128 background: rgba(149, 165, 166, 0.75);
129 }
130 </style>
131 </head>
132 <body>
133 <div class="bg">
134 <div class="title">{{title}}</div>
135 </div>
136 <div class="footer">
137 <div class="author">
138 <div class="author-name">
139 <span class="author-mark"></span>
140 <div class="logo">{{author=@Pixelle.AI}}</div>
141 </div>
142 <div class="author-desc">{{describe=Open Source Omnimodal AI Creative Agent}}</div>
143 </div>
144 <div class="logo-section">
145 <div class="logo">{{brand=Pixelle-Video}}</div>
146 <div class="logo-marks">
147 <div class="logo-mark"></div>
148 <div class="logo-mark active"></div>
149 <div class="logo-mark"></div>
150 <div class="logo-mark"></div>
151 </div>
152 </div>
153 </div>
154 <script>
155 /**
156 * 根据文本宽度自动调整字体大小
157 * @param {HTMLElement} element - 要调整的元素
158 * @param {number} maxWidth - 最大宽度(px)
159 * @param {number} minFontSize - 最小字体大小(px)
160 * @param {number} maxFontSize - 最大字体大小(px)
161 */
162 function autoFitFontSize(element, maxWidth, minFontSize, maxFontSize) {
163 try {
164 if (!element || !element.textContent || !element.textContent.trim()) {
165 return;
166 }
167
168 if (!document.body) {
169 return;
170 }
171
172 // 创建一个临时的测量元素
173 const measure = document.createElement('span');
174 measure.style.visibility = 'hidden';
175 measure.style.position = 'absolute';
176 measure.style.top = '-9999px';
177 measure.style.left = '-9999px';
178 measure.style.whiteSpace = 'nowrap';
179
180 // 复制元素的样式
181 const computedStyle = window.getComputedStyle(element);
182 measure.style.fontFamily = computedStyle.fontFamily;
183 measure.style.fontSize = computedStyle.fontSize;
184 measure.style.fontWeight = computedStyle.fontWeight;
185 measure.style.letterSpacing = computedStyle.letterSpacing;
186 measure.textContent = element.textContent;
187
188 document.body.appendChild(measure);
189
190 // 二分查找合适的字体大小
191 let low = minFontSize;
192 let high = maxFontSize;
193 let bestSize = maxFontSize;
194
195 // 先检查最大字体是否合适
196 measure.style.fontSize = maxFontSize + 'px';
197 if (measure.offsetWidth <= maxWidth) {
198 bestSize = maxFontSize;
199 } else {
200 // 使用二分查找
201 while (high - low > 0.5) {
202 const mid = (low + high) / 2;
203 measure.style.fontSize = mid + 'px';
204
205 if (measure.offsetWidth <= maxWidth) {
206 bestSize = mid;
207 low = mid;
208 } else {
209 high = mid;
210 }
211 }
212 }
213
214 // 应用找到的字体大小
215 element.style.fontSize = bestSize + 'px';
216
217 // 清理临时元素
218 if (measure.parentNode) {
219 document.body.removeChild(measure);
220 }
221 } catch (error) {
222 console.error('自动调整字体大小出错:', error);
223 }
224 }
225
226 // 页面加载完成后自动调整字体大小
227 function initAutoFit() {
228 try {
229 const titleElement = document.querySelector('.title');
230 if (titleElement) {
231 // 获取容器的实际宽度
232 const maxWidth = 900;
233 // 自动调整字体大小:最小12px,最大72px
234 autoFitFontSize(titleElement, maxWidth, 12, 72);
235 }
236 } catch (error) {
237 console.error('初始化自动调整字体大小出错:', error);
238 }
239 }
240
241 // 等待 DOM 加载完成
242 if (document.readyState === 'loading') {
243 document.addEventListener('DOMContentLoaded', initAutoFit);
244 } else {
245 // DOM 已经加载完成
246 initAutoFit();
247 }
248
249 // 如果内容是通过模板引擎动态插入的,可以监听内容变化
250 // 使用 MutationObserver 监听文本变化
251 if (typeof MutationObserver !== 'undefined') {
252 try {
253 const observer = new MutationObserver(function(mutations) {
254 let shouldUpdate = false;
255 mutations.forEach(function(mutation) {
256 if (mutation.type === 'childList' || mutation.type === 'characterData') {
257 shouldUpdate = true;
258 }
259 });
260
261 if (shouldUpdate) {
262 // 延迟执行,避免频繁调用
263 setTimeout(initAutoFit, 100);
264 }
265 });
266
267 // 等待 body 元素存在后再观察
268 if (document.body) {
269 observer.observe(document.body, {
270 childList: true,
271 subtree: true,
272 characterData: true
273 });
274 } else {
275 document.addEventListener('DOMContentLoaded', function() {
276 if (document.body) {
277 observer.observe(document.body, {
278 childList: true,
279 subtree: true,
280 characterData: true
281 });
282 }
283 });
284 }
285 } catch (error) {
286 console.error('设置 MutationObserver 出错:', error);
287 }
288 }
289 </script>
290 </body>
291 </html>
291 lines HTML