高清图片源码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Anthropic风格PPT背景</title>
<!-- html2canvas CDN -->
<script src="https://unpkg.com/[email protected]/dist/html2canvas.min.js">
</script>
<style>
:root {
--bg-warm-cream: #F8F3EE;
--soft-peach: #F0D5CB;
--warm-coral: #E8B4A2;
--dusty-rose: #D4957B;
--terracotta: #C1785A;
--deep-umber: #8B5E4C;
--warm-taupe: #A39084;
--pale-blush: #F6E8E0;
--light-clay: #ECD9CC;
--muted-sand: #E8DDD4;
--btn-bg: #C1785A;
--btn-hover: #A86348;
--btn-text: #FFF8F4;
--btn-shadow: rgba(139, 94, 76, 0.25);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #e8e0d8;
font-family: 'Georgia', 'Noto Serif SC', 'Source Han Serif SC', 'STSong', 'SimSun', 'Songti SC', 'Segoe UI', system-ui, sans-serif;
padding: 20px;
gap: 30px;
}
/* ============ 幻灯片容器 ============ */
.slide-container {
width: 1280px;
height: 720px;
position: relative;
overflow: hidden;
background: linear-gradient(160deg,
#F9F4EF 0%,
#F5EBE3 18%,
#FDF7F3 35%,
#F7EDE5 52%,
#FCF5EF 68%,
#F3E5DA 82%,
#F8F0E9 100%);
border-radius: 8px;
box-shadow:
0 4px 24px rgba(139, 94, 76, 0.12),
0 16px 48px rgba(139, 94, 76, 0.08),
0 40px 80px rgba(139, 94, 76, 0.05);
aspect-ratio: 16 / 9;
user-select: none;
flex-shrink: 0;
}
/* ============ 大型柔和光晕 - 右上 ============ */
.glow-top-right {
position: absolute;
top: -120px;
right: -80px;
width: 620px;
height: 520px;
background: radial-gradient(ellipse at center,
rgba(232, 180, 162, 0.45) 0%,
rgba(240, 213, 203, 0.30) 25%,
rgba(246, 232, 224, 0.18) 50%,
rgba(248, 243, 238, 0.05) 75%,
transparent 100%);
border-radius: 50%;
pointer-events: none;
animation: gentlePulse1 14s ease-in-out infinite;
}
/* ============ 大型柔和光晕 - 左下 ============ */
.glow-bottom-left {
position: absolute;
bottom: -140px;
left: -100px;
width: 700px;
height: 560px;
background: radial-gradient(ellipse at center,
rgba(212, 149, 123, 0.35) 0%,
rgba(232, 180, 162, 0.25) 22%,
rgba(240, 213, 203, 0.14) 48%,
rgba(248, 243, 238, 0.04) 72%,
transparent 100%);
border-radius: 50%;
pointer-events: none;
animation: gentlePulse2 16s ease-in-out infinite;
}
/* ============ 中型光晕 - 中右 ============ */
.glow-mid-right {
position: absolute;
top: 38%;
right: -60px;
width: 380px;
height: 340px;
background: radial-gradient(ellipse at center,
rgba(240, 213, 203, 0.40) 0%,
rgba(246, 232, 224, 0.22) 35%,
transparent 100%);
border-radius: 50%;
pointer-events: none;
animation: gentlePulse3 12s ease-in-out infinite;
}
/* ============ 小型强调光点 - 左上区域 ============ */
.accent-dot-1 {
position: absolute;
top: 85px;
left: 160px;
width: 55px;
height: 55px;
background: radial-gradient(circle at 40% 35%,
rgba(232, 180, 162, 0.7) 0%,
rgba(212, 149, 123, 0.35) 40%,
transparent 100%);
border-radius: 50%;
pointer-events: none;
animation: floatDot1 9s ease-in-out infinite;
}
.accent-dot-2 {
position: absolute;
bottom: 200px;
right: 280px;
width: 40px;
height: 40px;
background: radial-gradient(circle at 45% 30%,
rgba(193, 120, 90, 0.50) 0%,
rgba(212, 149, 123, 0.20) 45%,
transparent 100%);
border-radius: 50%;
pointer-events: none;
animation: floatDot2 11s ease-in-out infinite;
}
/* ============ 有机曲线装饰 - 1 ============ */
.organic-curve-1 {
position: absolute;
top: 55px;
right: 200px;
width: 320px;
height: 180px;
pointer-events: none;
}
.organic-curve-1 svg {
width: 100%;
height: 100%;
}
/* ============ 有机曲线装饰 - 2 ============ */
.organic-curve-2 {
position: absolute;
bottom: 100px;
left: 100px;
width: 280px;
height: 160px;
pointer-events: none;
}
.organic-curve-2 svg {
width: 100%;
height: 100%;
}
/* ============ 细微纹理叠加层 ============ */
.texture-overlay {
position: absolute;
inset: 0;
pointer-events: none;
opacity: 0.04;
background-image:
repeating-linear-gradient(0deg,
transparent,
transparent 2px,
rgba(139, 94, 76, 0.6) 2px,
rgba(139, 94, 76, 0.6) 2.5px),
repeating-linear-gradient(90deg,
transparent,
transparent 2px,
rgba(139, 94, 76, 0.6) 2px,
rgba(139, 94, 76, 0.6) 2.5px);
border-radius: 8px;
}
/* ============ 底部柔和渐变条 ============ */
.bottom-gradient-bar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 100px;
background: linear-gradient(to top,
rgba(200, 165, 145, 0.22) 0%,
rgba(220, 185, 165, 0.10) 30%,
transparent 100%);
pointer-events: none;
}
/* ============ 角落装饰小圆环 ============ */
.corner-ring {
position: absolute;
bottom: 55px;
right: 75px;
width: 70px;
height: 70px;
pointer-events: none;
}
.corner-ring svg {
width: 100%;
height: 100%;
}
/* ============ 中央微妙的网格点阵 ============ */
.dot-grid {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0.06;
background-image: radial-gradient(circle, #8B5E4C 1.2px, transparent 1.2px);
background-size: 48px 48px;
background-position: 24px 24px;
border-radius: 8px;
}
/* ============ 动画定义 ============ */
@keyframes gentlePulse1 {
0%,
100% {
transform: scale(1) translate(0, 0);
opacity: 0.9;
}
25% {
transform: scale(1.06) translate(-8px, 6px);
opacity: 1;
}
50% {
transform: scale(1.02) translate(4px, -10px);
opacity: 0.85;
}
75% {
transform: scale(1.08) translate(-4px, -3px);
opacity: 0.95;
}
}
@keyframes gentlePulse2 {
0%,
100% {
transform: scale(1) translate(0, 0);
opacity: 0.85;
}
30% {
transform: scale(1.07) translate(10px, -8px);
opacity: 1;
}
55% {
transform: scale(0.96) translate(-5px, 6px);
opacity: 0.78;
}
80% {
transform: scale(1.04) translate(3px, 4px);
opacity: 0.92;
}
}
@keyframes gentlePulse3 {
0%,
100% {
transform: scale(1) translate(0, 0);
opacity: 0.75;
}
40% {
transform: scale(1.09) translate(-6px, -4px);
opacity: 0.95;
}
70% {
transform: scale(0.94) translate(5px, 7px);
opacity: 0.68;
}
}
@keyframes floatDot1 {
0%,
100% {
transform: translate(0, 0);
}
33% {
transform: translate(8px, -10px);
}
66% {
transform: translate(-6px, 7px);
}
}
@keyframes floatDot2 {
0%,
100% {
transform: translate(0, 0);
}
40% {
transform: translate(-7px, -8px);
}
75% {
transform: translate(5px, 9px);
}
}
/* ============ 导出按钮样式 ============ */
.export-btn-wrapper {
display: flex;
align-items: center;
gap: 14px;
flex-wrap: wrap;
justify-content: center;
}
.export-btn {
display: inline-flex;
align-items: center;
gap: 9px;
padding: 13px 28px;
font-size: 1rem;
font-family: inherit;
font-weight: 500;
letter-spacing: 0.02em;
color: var(--btn-text);
background: var(--btn-bg);
border: none;
border-radius: 40px;
cursor: pointer;
box-shadow: 0 4px 16px var(--btn-shadow), 0 1px 4px rgba(139, 94, 76, 0.15);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
white-space: nowrap;
-webkit-tap-highlight-color: transparent;
}
.export-btn::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.12) 0%,
transparent 50%,
rgba(255, 255, 255, 0.06) 100%);
border-radius: 40px;
pointer-events: none;
transition: opacity 0.3s;
}
.export-btn:hover {
background: var(--btn-hover);
box-shadow: 0 8px 28px rgba(139, 94, 76, 0.35), 0 2px 8px rgba(139, 94, 76, 0.2);
transform: translateY(-2px);
}
.export-btn:active {
transform: translateY(0);
box-shadow: 0 2px 10px var(--btn-shadow), 0 1px 3px rgba(139, 94, 76, 0.12);
transition: all 0.1s ease;
}
.export-btn:focus-visible {
outline: 3px solid rgba(193, 120, 90, 0.5);
outline-offset: 3px;
}
/* 按钮图标 */
.btn-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
flex-shrink: 0;
}
.btn-icon svg {
width: 100%;
height: 100%;
transition: transform 0.3s ease;
}
.export-btn:hover .btn-icon svg {
transform: translateY(2px);
}
/* 加载状态 */
.export-btn.loading {
pointer-events: none;
opacity: 0.8;
background: #b06d50;
}
.export-btn.loading .btn-icon svg {
animation: spinDownload 0.8s linear infinite;
}
@keyframes spinDownload {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 成功状态 */
.export-btn.success {
background: #6B9E7A;
box-shadow: 0 4px 18px rgba(107, 158, 122, 0.4);
pointer-events: none;
animation: successPulse 0.5s ease-out;
}
.export-btn.success::after {
opacity: 0;
}
@keyframes successPulse {
0% {
transform: scale(1);
}
30% {
transform: scale(1.04);
}
100% {
transform: scale(1);
}
}
/* 提示文字 */
.export-hint {
font-size: 0.85rem;
color: #8B5E4C;
opacity: 0.7;
letter-spacing: 0.03em;
pointer-events: none;
}
/* ============ Toast 提示 ============ */
.toast {
position: fixed;
top: 24px;
left: 50%;
transform: translateX(-50%) translateY(-120px);
background: #3D2E28;
color: #F8F3EE;
padding: 12px 24px;
border-radius: 30px;
font-size: 0.9rem;
letter-spacing: 0.03em;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
z-index: 9999;
pointer-events: none;
transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
display: flex;
align-items: center;
gap: 8px;
}
.toast.show {
transform: translateX(-50%) translateY(0);
}
.toast-icon {
font-size: 1.2rem;
}
/* ============ 响应式 ============ */
@media (max-width: 1340px) {
.slide-container {
width: 96vw;
height: auto;
aspect-ratio: 16 / 9;
}
.glow-top-right {
top: -10%;
right: -6%;
width: 48%;
height: 65%;
}
.glow-bottom-left {
bottom: -15%;
left: -8%;
width: 55%;
height: 70%;
}
.glow-mid-right {
top: 36%;
right: -5%;
width: 30%;
height: 42%;
}
.accent-dot-1 {
top: 11%;
left: 14%;
width: 4.5%;
height: auto;
aspect-ratio: 1;
}
.accent-dot-2 {
bottom: 26%;
right: 22%;
width: 3.2%;
height: auto;
aspect-ratio: 1;
}
.organic-curve-1 {
top: 7%;
right: 14%;
width: 26%;
height: auto;
aspect-ratio: 16/9;
}
.organic-curve-2 {
bottom: 12%;
left: 8%;
width: 22%;
height: auto;
aspect-ratio: 14/8;
}
.corner-ring {
bottom: 7%;
right: 6%;
width: 5.5%;
height: auto;
aspect-ratio: 1;
}
.dot-grid {
background-size: 3.75vw 3.75vw;
background-position: 1.875vw 1.875vw;
}
.bottom-gradient-bar {
height: 13%;
}
.export-btn {
padding: 11px 22px;
font-size: 0.9rem;
border-radius: 34px;
}
.export-btn::after {
border-radius: 34px;
}
}
@media (max-width: 768px) {
.slide-container {
width: 100vw;
border-radius: 4px;
}
.texture-overlay,
.dot-grid {
border-radius: 4px;
}
.organic-curve-1,
.organic-curve-2,
.corner-ring {
display: none;
}
.accent-dot-1,
.accent-dot-2 {
width: 6%;
}
.glow-top-right {
top: -8%;
right: -10%;
width: 55%;
}
.glow-bottom-left {
bottom: -12%;
left: -12%;
width: 60%;
}
.export-btn {
padding: 10px 20px;
font-size: 0.85rem;
border-radius: 30px;
gap: 6px;
}
.export-btn::after {
border-radius: 30px;
}
.export-hint {
font-size: 0.75rem;
}
body {
gap: 20px;
padding: 12px;
}
}
</style>
</head>
<body>
<!-- 幻灯片容器 -->
<div class="slide-container" id="slideContainer">
<!-- 大型柔和光晕 -->
<div class="glow-top-right"></div>
<div class="glow-bottom-left"></div>
<div class="glow-mid-right"></div>
<!-- 小强调光点 -->
<div class="accent-dot-1"></div>
<div class="accent-dot-2"></div>
<!-- 有机曲线装饰 1 -->
<div class="organic-curve-1">
<svg viewBox="0 0 320 180" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 140 C 60 145, 100 90, 160 75 C 220 60, 260 20, 320 30"
stroke="rgba(193, 120, 90, 0.22)" stroke-width="2.8" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<path d="M10 155 C 70 158, 110 108, 170 92 C 230 76, 265 38, 310 44"
stroke="rgba(212, 149, 123, 0.18)" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<path d="M20 168 C 75 170, 120 125, 175 110 C 235 95, 270 60, 300 62"
stroke="rgba(163, 144, 132, 0.15)" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</div>
<!-- 有机曲线装饰 2 -->
<div class="organic-curve-2">
<svg viewBox="0 0 280 160" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M280 20 C 210 15, 180 70, 120 80 C 60 90, 30 140, 0 130"
stroke="rgba(193, 120, 90, 0.20)" stroke-width="2.6" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<path d="M270 35 C 200 30, 170 82, 110 92 C 50 102, 25 148, 5 140"
stroke="rgba(212, 149, 123, 0.16)" stroke-width="1.8" fill="none" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</div>
<!-- 角落装饰圆环 -->
<div class="corner-ring">
<svg viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="35" cy="35" r="30" stroke="rgba(193, 120, 90, 0.25)" stroke-width="1.8" fill="none" />
<circle cx="35" cy="35" r="20" stroke="rgba(212, 149, 123, 0.18)" stroke-width="1.4" fill="none" stroke-dasharray="8 5" />
<circle cx="35" cy="35" r="4" fill="rgba(193, 120, 90, 0.35)" />
</svg>
</div>
<!-- 底部柔和渐变条 -->
<div class="bottom-gradient-bar"></div>
<!-- 细微纹理叠加 -->
<div class="texture-overlay"></div>
<!-- 中央微弱点阵 -->
<div class="dot-grid"></div>
</div>
<!-- 导出按钮区域 -->
<div class="export-btn-wrapper">
<button class="export-btn" id="exportBtn" title="导出为PNG背景图片(2560×1440高清)">
<span class="btn-icon">
<!-- 下载图标 -->
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 3V16M12 16L7 11M12 16L17 11" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 19H20" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/>
</svg>
</span>
<span class="btn-text">导出背景图片</span>
</button>
<span class="export-hint">高清PNG · 2560×1440</span>
</div>
<!-- Toast 提示 -->
<div class="toast" id="toast">
<span class="toast-icon"></span>
<span class="toast-message"></span>
</div>
<script>
(function() {
const exportBtn = document.getElementById('exportBtn');
const slideContainer = document.getElementById('slideContainer');
const toast = document.getElementById('toast');
const toastIcon = toast.querySelector('.toast-icon');
const toastMessage = toast.querySelector('.toast-message');
const btnText = exportBtn.querySelector('.btn-text');
const btnIconContainer = exportBtn.querySelector('.btn-icon');
// 原始按钮内容备份
const originalBtnHTML = exportBtn.innerHTML;
let isExporting = false;
let toastTimer = null;
// Toast 显示函数
function showToast(message, icon = '✅', duration = 2800) {
if (toastTimer) clearTimeout(toastTimer);
toastMessage.textContent = message;
toastIcon.textContent = icon;
toast.classList.add('show');
toastTimer = setTimeout(() => {
toast.classList.remove('show');
toastTimer = null;
}, duration);
}
// 格式化日期为 YYYYMMDD
function getDateString() {
const now = new Date();
const y = now.getFullYear();
const m = String(now.getMonth() + 1).padStart(2, '0');
const d = String(now.getDate()).padStart(2, '0');
return `${y}${m}${d}`;
}
// 导出函数
async function exportImage() {
if (isExporting) return;
isExporting = true;
// 设置加载状态
exportBtn.classList.add('loading');
btnText.textContent = '导出中...';
exportBtn.setAttribute('aria-busy', 'true');
// 存储原始圆角值以便恢复
const originalBorderRadius = slideContainer.style.borderRadius;
// 导出时移除圆角,得到更适合PPT的直角背景
slideContainer.style.borderRadius = '0px';
// 同步处理内部元素的圆角
const textureOverlay = slideContainer.querySelector('.texture-overlay');
const dotGrid = slideContainer.querySelector('.dot-grid');
const originalTextureRadius = textureOverlay ? textureOverlay.style.borderRadius : '';
const originalDotGridRadius = dotGrid ? dotGrid.style.borderRadius : '';
if (textureOverlay) textureOverlay.style.borderRadius = '0px';
if (dotGrid) dotGrid.style.borderRadius = '0px';
try {
// 检查 html2canvas 是否可用
if (typeof html2canvas === 'undefined') {
throw new Error('html2canvas 库加载失败,请检查网络连接后刷新页面重试。');
}
const canvas = await html2canvas(slideContainer, {
scale: 2, // 2倍分辨率:2560×1440
useCORS: true,
allowTaint: true,
backgroundColor: null, // 使用元素自身背景
logging: false,
imageTimeout: 15000,
});
// 生成 Blob 并触发下载
canvas.toBlob((blob) => {
if (!blob) {
throw new Error('图片生成失败,请重试。');
}
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `anthropic-ppt-background-${getDateString()}.png`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 释放内存
setTimeout(() => URL.revokeObjectURL(url), 2000);
// 成功状态
exportBtn.classList.remove('loading');
exportBtn.classList.add('success');
btnText.textContent = '下载完成 ✓';
exportBtn.setAttribute('aria-busy', 'false');
showToast('背景图片已导出!', '✅', 2500);
// 恢复按钮
setTimeout(() => {
exportBtn.classList.remove('success');
exportBtn.innerHTML = originalBtnHTML;
// 重新获取引用(因为innerHTML被重置了)
updateButtonRefs();
isExporting = false;
}, 2000);
}, 'image/png', 0.95);
} catch (error) {
console.error('导出失败:', error);
exportBtn.classList.remove('loading');
exportBtn.setAttribute('aria-busy', 'false');
btnText.textContent = '导出失败,重试';
showToast(error.message || '导出失败,请重试', '⚠️', 3500);
// 恢复按钮
setTimeout(() => {
exportBtn.innerHTML = originalBtnHTML;
updateButtonRefs();
isExporting = false;
}, 2200);
} finally {
// 恢复圆角
slideContainer.style.borderRadius = originalBorderRadius;
if (textureOverlay) textureOverlay.style.borderRadius = originalTextureRadius;
if (dotGrid) dotGrid.style.borderRadius = originalDotGridRadius;
}
}
// 更新按钮内部元素引用(在重置innerHTML后使用)
function updateButtonRefs() {
// 重新获取按钮内的元素引用
const newBtnText = exportBtn.querySelector('.btn-text');
const newBtnIcon = exportBtn.querySelector('.btn-icon');
// 更新闭包中的引用(通过重新绑定事件时使用最新引用)
if (newBtnText && newBtnIcon) {
// 引用更新在下一次点击时自动生效
}
}
// 绑定点击事件
exportBtn.addEventListener('click', exportImage);
// 键盘快捷键:Ctrl+E / Cmd+E 导出
document.addEventListener('keydown', (e) => {
if ((e.ctrlKey || e.metaKey) && e.key === 'e') {
e.preventDefault();
if (!isExporting) {
exportImage();
}
}
});
// 初始更新按钮引用
updateButtonRefs();
console.log('✨ Anthropic 风格 PPT 背景已就绪');
console.log(' 🖱️点击下方按钮或按 Ctrl+E / Cmd+E 导出高清背景图');
console.log(' 📐导出尺寸:2560×1440 (2x)');
})();
</script>
</body>
</html>
2 个帖子 - 1 位参与者