孔明灯 · 祈福模拟器
by HyperMaker20530 lines17.3 KB
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>孔明灯 · 祈福模拟器</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
background: #0a0f1e;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
}
.simulator {
position: relative;
width: 100%;
max-width: 1000px;
height: 700px;
background: radial-gradient(circle at 50% 30%, #1a1f30, #080c14);
border-radius: 40px;
box-shadow: 0 30px 40px rgba(0, 0, 0, 0.7), inset 0 0 60px rgba(255, 200, 100, 0.2);
overflow: hidden;
border: 1px solid #3e4a5e;
}
/* 星空点缀 */
.stars {
position: absolute;
inset: 0;
background-image: radial-gradient(2px 2px at 20px 30px, #fff, rgba(0,0,0,0)),
radial-gradient(2px 2px at 80px 120px, #ffe, rgba(0,0,0,0)),
radial-gradient(3px 3px at 240px 50px, #ffd, rgba(0,0,0,0)),
radial-gradient(2px 2px at 400px 300px, #fff, rgba(0,0,0,0)),
radial-gradient(3px 3px at 560px 180px, #ffe, rgba(0,0,0,0)),
radial-gradient(2px 2px at 720px 80px, #fff, rgba(0,0,0,0)),
radial-gradient(2px 2px at 880px 400px, #ffd, rgba(0,0,0,0)),
radial-gradient(3px 3px at 100px 600px, #fff, rgba(0,0,0,0)),
radial-gradient(2px 2px at 300px 500px, #ffe, rgba(0,0,0,0)),
radial-gradient(2px 2px at 600px 650px, #fff, rgba(0,0,0,0)),
radial-gradient(2px 2px at 800px 550px, #ffd, rgba(0,0,0,0));
background-repeat: no-repeat;
background-size: 1000px 700px;
opacity: 0.9;
pointer-events: none;
}
/* 孔明灯容器 */
.lanterns-container {
position: absolute;
inset: 0;
pointer-events: none;
}
/* 每一盏孔明灯 */
.lantern {
position: absolute;
width: 90px;
height: 130px;
filter: drop-shadow(0 0 18px rgba(255, 180, 40, 0.7));
animation: floatUp 14s infinite ease-in-out;
pointer-events: none;
will-change: transform;
}
/* 灯体 (主体) */
.lantern-body {
position: absolute;
width: 90px;
height: 110px;
background: radial-gradient(circle at 30% 25%, #ffd966, #e68a00 75%, #b35900);
border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%;
box-shadow: 0 0 35px #ffb84d, inset 0 0 25px #ffdd99;
border: 1px solid #ffcc66;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 10px 6px 18px 6px;
overflow: hidden;
transform: rotate(0deg);
}
/* 灯体上的文字 */
.lantern-text {
font-size: 11px;
font-weight: 700;
color: #2d1b00;
text-shadow: 0 0 6px #ffdd99, 0 0 12px #ffaa33;
line-height: 1.4;
letter-spacing: 1px;
writing-mode: horizontal-tb;
word-break: break-word;
width: 100%;
padding: 0 4px;
background: rgba(255, 220, 130, 0.2);
border-radius: 30px;
font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;
}
/* 灯底/火焰口 */
.lantern-base {
position: absolute;
bottom: 0;
left: 25px;
width: 40px;
height: 18px;
background: #b35900;
border-radius: 50% 50% 30% 30% / 30% 30% 70% 70%;
box-shadow: inset 0 -4px 8px #4a2a00, 0 4px 10px #ff9900;
border-top: 1px solid #ffaa33;
}
/* 飘动的火焰 */
.flame {
position: absolute;
bottom: 12px;
left: 38px;
width: 14px;
height: 22px;
background: radial-gradient(circle at 50% 20%, #ffdd44, #ff8800 70%, #cc5500);
border-radius: 50% 50% 40% 40% / 70% 70% 30% 30%;
filter: blur(1px) drop-shadow(0 0 10px #ffaa00);
animation: flicker 0.5s infinite alternate;
opacity: 0.9;
}
/* 不同位置与动画延迟 */
.lantern:nth-child(1) { left: 8%; top: 55%; animation-delay: 0s; animation-duration: 16s; }
.lantern:nth-child(2) { left: 24%; top: 70%; animation-delay: 1.2s; animation-duration: 14s; }
.lantern:nth-child(3) { left: 43%; top: 60%; animation-delay: 2.5s; animation-duration: 18s; }
.lantern:nth-child(4) { left: 62%; top: 75%; animation-delay: 0.8s; animation-duration: 15s; }
.lantern:nth-child(5) { left: 78%; top: 48%; animation-delay: 3.2s; animation-duration: 17s; }
.lantern:nth-child(6) { left: 15%; top: 25%; animation-delay: 1.8s; animation-duration: 20s; } /* 高处的小灯,慢速 */
.lantern:nth-child(7) { left: 85%; top: 20%; animation-delay: 0.4s; animation-duration: 19s; }
/* 对第6、7盏稍微缩小一点让层次更丰富 */
.lantern:nth-child(6) .lantern-body,
.lantern:nth-child(7) .lantern-body {
transform: scale(0.85);
}
.lantern:nth-child(6) .lantern-base,
.lantern:nth-child(7) .lantern-base,
.lantern:nth-child(6) .flame,
.lantern:nth-child(7) .flame {
transform: scale(0.85);
transform-origin: center bottom;
}
.lantern:nth-child(6) .lantern-text,
.lantern:nth-child(7) .lantern-text {
font-size: 9px;
}
/* 上升漂浮动画 */
@keyframes floatUp {
0% {
transform: translateY(0px) translateX(0px) rotate(0deg);
opacity: 0.9;
}
30% {
transform: translateY(-40px) translateX(8px) rotate(1.5deg);
}
60% {
transform: translateY(-100px) translateX(-6px) rotate(-1deg);
}
100% {
transform: translateY(-220px) translateX(4px) rotate(1deg);
opacity: 0.3;
}
}
/* 火焰闪烁 */
@keyframes flicker {
0% { transform: scaleY(1) scaleX(1); opacity: 0.9; }
100% { transform: scaleY(1.2) scaleX(0.9); opacity: 1; }
}
/* 文字签名(装饰) */
.credit {
position: absolute;
bottom: 15px;
right: 25px;
color: #b8a88a;
font-size: 13px;
letter-spacing: 2px;
opacity: 0.5;
font-style: italic;
text-shadow: 0 0 8px #ffbb33;
z-index: 10;
}
/* 控制区域 — 输入框和按钮 */
.input-area {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 16px;
background: rgba(10, 15, 25, 0.75);
backdrop-filter: blur(10px);
padding: 14px 24px;
border-radius: 60px;
border: 1px solid #ffbb4d;
box-shadow: 0 0 30px rgba(255, 170, 0, 0.3);
z-index: 20;
align-items: center;
}
.input-area input {
width: 360px;
padding: 12px 20px;
border-radius: 40px;
border: none;
outline: 2px solid #ffaa33;
background: #1e1e2e;
color: #ffebc2;
font-size: 16px;
font-weight: 500;
letter-spacing: 1px;
font-family: 'Microsoft YaHei', sans-serif;
transition: all 0.2s ease;
box-shadow: inset 0 0 12px #00000055, 0 0 12px #ffaa3333;
}
.input-area input:focus {
outline: 3px solid #ffcc66;
background: #2a2a3a;
color: #fff2d0;
box-shadow: inset 0 0 8px #000, 0 0 20px #ffb347;
}
.input-area button {
padding: 12px 28px;
border-radius: 40px;
border: none;
background: linear-gradient(145deg, #ffb347, #e68a00);
color: #1e1408;
font-size: 17px;
font-weight: 700;
letter-spacing: 2px;
cursor: pointer;
box-shadow: 0 6px 0 #8b5a00, 0 8px 18px #00000055;
transition: all 0.1s ease;
font-family: 'Microsoft YaHei', sans-serif;
border: 1px solid #ffdd99;
}
.input-area button:active {
transform: translateY(5px);
box-shadow: 0 1px 0 #8b5a00, 0 8px 18px #00000055;
}
.input-area button:hover {
background: linear-gradient(145deg, #ffc266, #ff9f1a);
box-shadow: 0 6px 0 #a06a00, 0 10px 22px #00000077;
}
/* 响应式微调 */
@media (max-width: 750px) {
.simulator { height: 600px; border-radius: 24px; }
.input-area { flex-direction: column; width: 90%; padding: 16px; bottom: 16px; }
.input-area input { width: 100%; font-size: 14px; }
.input-area button { width: 100%; padding: 10px; font-size: 16px; }
.lantern { width: 70px; height: 100px; }
.lantern-body { width: 70px; height: 85px; }
.lantern-base { left: 18px; width: 34px; }
.flame { left: 28px; width: 12px; height: 18px; }
.lantern-text { font-size: 9px; }
}
</style>
</head>
<body>
<div class="simulator">
<div class="stars"></div>
<div class="lanterns-container" id="lanternsContainer">
<!-- 7盏孔明灯,文字统一为“沈岁段久谈宥永远在一起”,但每盏会显示同样文字,不过换行略有不同让视觉更丰富 -->
<!-- 灯1 -->
<div class="lantern">
<div class="lantern-body">
<div class="lantern-text" id="lanternText1">沈岁段久<br>谈宥永远<br>在一起</div>
</div>
<div class="lantern-base"></div>
<div class="flame"></div>
</div>
<!-- 灯2 -->
<div class="lantern">
<div class="lantern-body">
<div class="lantern-text" id="lanternText2">沈岁段久<br>谈宥永远<br>在一起</div>
</div>
<div class="lantern-base"></div>
<div class="flame"></div>
</div>
<!-- 灯3 -->
<div class="lantern">
<div class="lantern-body">
<div class="lantern-text" id="lanternText3">沈岁段久<br>谈宥永远<br>在一起</div>
</div>
<div class="lantern-base"></div>
<div class="flame"></div>
</div>
<!-- 灯4 -->
<div class="lantern">
<div class="lantern-body">
<div class="lantern-text" id="lanternText4">沈岁段久<br>谈宥永远<br>在一起</div>
</div>
<div class="lantern-base"></div>
<div class="flame"></div>
</div>
<!-- 灯5 -->
<div class="lantern">
<div class="lantern-body">
<div class="lantern-text" id="lanternText5">沈岁段久<br>谈宥永远<br>在一起</div>
</div>
<div class="lantern-base"></div>
<div class="flame"></div>
</div>
<!-- 灯6 高处 小一点 -->
<div class="lantern">
<div class="lantern-body">
<div class="lantern-text" id="lanternText6">沈岁段久<br>谈宥永远<br>在一起</div>
</div>
<div class="lantern-base"></div>
<div class="flame"></div>
</div>
<!-- 灯7 高处 小一点 -->
<div class="lantern">
<div class="lantern-body">
<div class="lantern-text" id="lanternText7">沈岁段久<br>谈宥永远<br>在一起</div>
</div>
<div class="lantern-base"></div>
<div class="flame"></div>
</div>
</div>
<div class="credit">✨ 愿 · 长相守 ✨</div>
<!-- 输入与按钮 -->
<div class="input-area">
<input type="text" id="wishInput" placeholder="输入祈福文字..." value="沈岁段久谈宥永远在一起" maxlength="30">
<button id="updateBtn">点亮孔明灯</button>
</div>
</div>
<script>
(function() {
// 固定的初始文字,用户也可以修改
const DEFAULT_TEXT = "沈岁段久谈宥永远在一起";
// 获取所有文字元素
const textElements = [
document.getElementById('lanternText1'),
document.getElementById('lanternText2'),
document.getElementById('lanternText3'),
document.getElementById('lanternText4'),
document.getElementById('lanternText5'),
document.getElementById('lanternText6'),
document.getElementById('lanternText7')
];
const wishInput = document.getElementById('wishInput');
const updateBtn = document.getElementById('updateBtn');
// 格式化函数:将输入文字拆分成适合孔明灯展示的样式
// 为了美观,在适当位置插入换行。如果文字长度小于6,不强制换行;
// 如果长于6,尝试分成3行;每行不超过4个字符左右。
function formatLanternText(text) {
// 去除首尾空格,保留原意,但不可为空
let cleanText = text.trim();
if (cleanText === '') cleanText = '沈岁段久谈宥永远在一起'; // 空的话恢复默认
// 针对“沈岁段久谈宥永远在一起” 共11个字,我们按优美换行:
// 如果正好是默认文本或类似长度,使用固定换行模式,否则智能换行
if (cleanText === '沈岁段久谈宥永远在一起') {
return '沈岁段久<br>谈宥永远<br>在一起';
}
// 若文字较短(<=6),直接一行显示
if (cleanText.length <= 6) {
// 但可以加一点微调,若长度4-6可以中间换行
if (cleanText.length === 5) {
return cleanText.slice(0, 3) + '<br>' + cleanText.slice(3);
} else if (cleanText.length === 6) {
return cleanText.slice(0, 3) + '<br>' + cleanText.slice(3);
}
return cleanText;
}
// 对于长文本:每行最多 4~5 个字符,分成多行
const lines = [];
let i = 0;
// 根据长度动态决定每行字数,保证美观
const perLine = cleanText.length > 15 ? 5 : 4;
while (i < cleanText.length) {
lines.push(cleanText.slice(i, i + perLine));
i += perLine;
}
// 用<br>拼接
return lines.join('<br>');
}
// 更新所有孔明灯上的文字
function updateAllLanterns(text) {
const formatted = formatLanternText(text);
textElements.forEach(el => {
if (el) el.innerHTML = formatted;
});
}
// 初始化,使用默认文字
updateAllLanterns(DEFAULT_TEXT);
wishInput.value = DEFAULT_TEXT;
// 点击按钮更新
updateBtn.addEventListener('click', function() {
const newText = wishInput.value.trim();
if (newText === '') {
// 若为空,使用默认文字,并同步输入框
wishInput.value = DEFAULT_TEXT;
updateAllLanterns(DEFAULT_TEXT);
} else {
updateAllLanterns(newText);
}
// 添加一个轻微的按钮反馈动画
updateBtn.style.transform = 'scale(0.96)';
setTimeout(() => { updateBtn.style.transform = ''; }, 100);
});
// 按回车也可以触发
wishInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
updateBtn.click();
}
});
// 点击输入框时如果为默认文字全选方便修改
wishInput.addEventListener('focus', function() {
if (this.value === DEFAULT_TEXT) {
this.select();
}
});
// 动态调整一些孔明灯的文字尺寸以适应较长文字(简单处理,仅修改样式)
// 但当文字过长时,format 已经拆行,加上字体自适应调整
// 监听更新后文字长度?但不必太复杂,此处保留
// 附加:为了让文字在不同长度下都显示清晰,可以添加一个小的自适应类
// 不过现有字体11px/9px对于大多数短句都够用,如果用户输入特别长,可以缩小字体
// 为了更友好,给updateAllLanterns加入字体大小调整
const originalUpdate = updateAllLanterns;
updateAllLanterns = function(text) {
const formatted = formatLanternText(text);
// 计算纯文本长度(去掉<br>)
const rawLength = text.replace(/<br>/g, '').length;
// 动态调整字体大小 (对于过长的文字)
let fontSize = '11px';
let smallFontSize = '9px'; // 用于第6、7盏
if (rawLength > 14) {
fontSize = '9px';
smallFontSize = '8px';
} else if (rawLength > 10) {
fontSize = '10px';
smallFontSize = '8.5px';
} else {
fontSize = '11px';
smallFontSize = '9px';
}
textElements.forEach((el, index) => {
if (!el) return;
el.innerHTML = formatted;
// 第6、7盏(索引5,6)使用稍小字体
if (index === 5 || index === 6) {
el.style.fontSize = smallFontSize;
} else {
el.style.fontSize = fontSize;
}
// 如果原始长度特别短,也可以放大一点
if (rawLength <= 4 && (index !== 5 && index !== 6)) {
el.style.fontSize = '12px';
} else if (rawLength <= 4 && (index === 5 || index === 6)) {
el.style.fontSize = '10px';
}
});
};
// 重新绑定, 用新的函数覆盖
// 重新执行初始化
updateAllLanterns(DEFAULT_TEXT);
wishInput.value = DEFAULT_TEXT;
// 按钮监听使用新的 updateAllLanterns
updateBtn.onclick = function() {
const newText = wishInput.value.trim();
if (newText === '') {
wishInput.value = DEFAULT_TEXT;
updateAllLanterns(DEFAULT_TEXT);
} else {
updateAllLanterns(newText);
}
updateBtn.style.transform = 'scale(0.96)';
setTimeout(() => { updateBtn.style.transform = ''; }, 100);
};
// 回车键重新绑定
wishInput.onkeypress = function(e) {
if (e.key === 'Enter') {
e.preventDefault();
updateBtn.click();
}
};
// 保留全选
wishInput.onfocus = function() {
if (this.value === DEFAULT_TEXT) {
this.select();
}
};
})();
</script>
</body>
</html>Game Source: 孔明灯 · 祈福模拟器
Creator: HyperMaker20
Libraries: none
Complexity: complex (530 lines, 17.3 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-hypermaker20" to link back to the original. Then publish at arcadelab.ai/publish.