随机发病,运势,冷笑话,段子

This commit is contained in:
XsX05
2025-09-03 10:27:10 +08:00
parent e08511d860
commit fe79c20d2f
6 changed files with 471 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
margin: 0;
min-height: 100vh;
overflow-x: hidden;
transition: background 0.5s ease;
}
/* Hand-drawn Comic Theme Background - NEW VIBRANT VERSION */
body.theme-comic {
background: linear-gradient(-45deg, #ff7e5f, #feb47b, #ffcc80, #ffecb3);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
}
@keyframes gradientBG {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* Placeholder for Emoji Theme Background */
body.theme-emoji {
background-color: #fffde7;
}
/* Placeholder for Retro TV Theme Background */
body.theme-retro {
background-color: #3d2b1f;
}

View File

@@ -0,0 +1,199 @@
@import url('https://fonts.googleapis.com/css2?family=Zhi+Mang+Xing&display=swap');
/* --- General & Theme Switcher --- */
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
text-align: center;
}
.theme-switcher {
position: fixed;
top: 15px;
right: 15px;
display: flex;
gap: 5px;
background: rgba(255, 255, 255, 0.8);
padding: 5px;
border-radius: 20px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
z-index: 100;
}
.theme-icon {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: all 0.2s ease;
border: 2px solid transparent;
}
.theme-icon.active {
border-color: #ff7043;
transform: scale(1.1);
}
/* --- Comic Theme Styles --- */
.theme-comic header h1 {
font-family: 'Zhi Mang Xing', cursive;
font-size: 4em;
color: #d84315; /* Deep Orange */
text-shadow: 2px 2px 0 #fff;
margin: 0.2em 0;
}
.theme-comic .divider {
height: 3px;
background: linear-gradient(90deg, #ffca28, #ff7043, #29b6f6, #66bb6a);
border-radius: 3px;
margin: 20px auto;
width: 80%;
}
.theme-comic .joke-card {
background: rgba(255, 255, 255, 0.85); /* White with transparency */
backdrop-filter: blur(5px);
border-radius: 15px;
padding: 40px;
min-height: 200px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
display: flex;
justify-content: center;
align-items: center;
position: relative;
margin-bottom: 20px;
transform: rotate(-1deg);
transition: transform 0.2s ease;
}
.theme-comic .joke-card:hover {
transform: rotate(1deg) scale(1.02);
}
.theme-comic .joke-text {
font-family: 'Zhi Mang Xing', cursive;
font-size: 2em;
line-height: 1.6;
color: #5d4037;
}
.theme-comic .new-joke-btn {
background: #1e88e5; /* Vibrant Blue */
color: white;
font-family: 'Zhi Mang Xing', cursive;
font-size: 2.5em;
border: none;
border-radius: 50px;
padding: 10px 30px;
cursor: pointer;
box-shadow: 0 5px 0 #1565c0; /* Darker Blue */
transition: all 0.1s ease-in-out;
}
.theme-comic .new-joke-btn:active {
transform: translateY(5px);
box-shadow: none;
}
/* --- Loading Animation --- */
.loading-container { display: none; }
.loading-container.visible { display: block; }
.loading-anim {
height: 60px;
width: 80px;
margin: 0 auto 10px;
}
.book {
transform-style: preserve-3d;
transform: rotateY(-30deg);
animation: flip 3s infinite;
}
.book, .book-page {
width: 40px;
height: 55px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -20px;
margin-top: -27.5px;
}
.book-page {
background: #ffca28;
border: 1px solid #ff7043;
border-radius: 3px;
transform-origin: left;
}
.book-page:nth-child(1) { animation: flip-page 3s infinite; }
.book-page:nth-child(2) { animation: flip-page 3s -1s infinite; }
.book-page:nth-child(3) { animation: flip-page 3s -2s infinite; }
@keyframes flip { 50% { transform: rotateY(30deg); } }
@keyframes flip-page { 30%, 100% { transform: rotateY(180deg); } }
/* --- Feedback Buttons & Animations --- */
.feedback-buttons {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 30px;
}
.feedback-btn {
background: none;
border: none;
font-size: 2em;
cursor: pointer;
transition: transform 0.2s ease;
}
.feedback-btn:hover { transform: scale(1.2); }
#animation-container {
position: fixed;
top: 0; left: 0; width: 100%; height: 100%;
pointer-events: none; z-index: 999;
}
.confetti, .snowflake {
position: absolute;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.confetti {
width: 10px; height: 10px;
animation-name: fall;
}
.snowflake {
font-size: 20px; color: #fff;
animation-name: fall;
}
@keyframes fall {
from { transform: translateY(-10vh) rotate(0deg); }
to { transform: translateY(110vh) rotate(360deg); }
}
.joke-card.absurd {
animation: absurd-flash 0.5s 2;
}
@keyframes absurd-flash {
0%, 100% { border: 2px solid transparent; }
50% { border: 5px solid red; }
}
/* --- General Joke Text Visibility --- */
.joke-text {
opacity: 0;
transform: scale(0.9);
transition: opacity 0.4s ease, transform 0.4s ease;
}
.joke-text.visible {
opacity: 1;
transform: scale(1);
}
/* --- Responsive --- */
@media (max-width: 600px) {
.theme-comic header h1 { font-size: 3em; }
.theme-comic .joke-card { padding: 25px; transform: rotate(0); }
.theme-comic .joke-card:hover { transform: rotate(0); }
.theme-comic .joke-text { font-size: 1.5em; }
}

View File

@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>段子游乐场</title>
<link rel="stylesheet" href="css/background.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body class="theme-comic"> <!-- Default Theme -->
<div class="theme-switcher">
<div class="theme-icon" data-theme="theme-comic" title="手绘漫画">✏️</div>
<div class="theme-icon" data-theme="theme-emoji" title="表情包狂欢">😂</div>
<div class="theme-icon" data-theme="theme-retro" title="复古电视">📺</div>
</div>
<div class="container">
<header>
<h1>段子游乐场</h1>
<div class="divider"></div>
</header>
<main>
<div id="joke-card" class="joke-card">
<div class="loading-container">
<div class="loading-anim">
<div class="book">
<div class="book-page"></div>
<div class="book-page"></div>
<div class="book-page"></div>
</div>
</div>
<p>段子菌正在翻笑话库...</p>
</div>
<p id="joke-text" class="joke-text"></p>
</div>
<div class="feedback-buttons">
<button id="btn-lol" class="feedback-btn" title="笑到拍桌">🤣</button>
<button id="btn-cold" class="feedback-btn" title="有点冷">🥶</button>
<button id="btn-seen" class="feedback-btn" title="似曾相识">🤔</button>
<button id="btn-absurd" class="feedback-btn" title="离谱但好笑">🤯</button>
</div>
<button id="new-joke-btn" class="new-joke-btn">
<span class="btn-text">再来一个!</span>
</button>
</main>
</div>
<!-- Animation & Sound Containers -->
<div id="animation-container"></div>
<audio id="sound-lol" src="https://www.myinstants.com/media/sounds/yay-6326.mp3" preload="auto"></audio>
<audio id="sound-cold" src="https://www.myinstants.com/media/sounds/zapsplat_cartoon_whoosh_fast_swoosh_001_76761.mp3" preload="auto"></audio>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,122 @@
document.addEventListener('DOMContentLoaded', () => {
// Elements
const body = document.body;
const jokeTextElem = document.getElementById('joke-text');
const newJokeBtn = document.getElementById('new-joke-btn');
const loadingContainer = document.querySelector('.loading-container');
const animationContainer = document.getElementById('animation-container');
const jokeCard = document.getElementById('joke-card');
// API
const apiBaseUrls = ["https://60s.api.shumengya.top", "https://60s-cf.viki.moe", "https://60s.viki.moe"];
const apiPath = "/v2/duanzi";
let currentApiIndex = 0;
// --- Core Functions ---
const showLoading = (isLoading) => {
loadingContainer.classList.toggle('visible', isLoading);
if (isLoading) jokeTextElem.classList.remove('visible');
};
const displayJoke = (joke) => {
jokeTextElem.textContent = joke;
showLoading(false);
setTimeout(() => jokeTextElem.classList.add('visible'), 50);
};
const fetchJoke = async () => {
showLoading(true);
try {
const url = apiBaseUrls[currentApiIndex] + apiPath;
const response = await fetch(url, { timeout: 5000 });
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
if (data.code === 200 && data.data && data.data.duanzi) {
displayJoke(data.data.duanzi);
} else {
throw new Error('Invalid data format');
}
} catch (error) {
console.error(`API error with ${apiBaseUrls[currentApiIndex]}:`, error);
currentApiIndex = (currentApiIndex + 1) % apiBaseUrls.length;
if (currentApiIndex !== 0) {
fetchJoke(); // Try next API
} else {
displayJoke('段子菌迷路了!点击‘再来一个’让它重新找路~');
}
}
};
// --- Theme Switcher ---
const themeSwitcher = document.querySelector('.theme-switcher');
themeSwitcher.addEventListener('click', (e) => {
if (e.target.classList.contains('theme-icon')) {
const theme = e.target.dataset.theme;
body.className = theme; // Set body class to the selected theme
// Update active icon
themeSwitcher.querySelectorAll('.theme-icon').forEach(icon => icon.classList.remove('active'));
e.target.classList.add('active');
alert(`主题已切换!部分主题(如表情包、复古电视)将在后续阶段实现。`);
}
});
// Set initial active theme icon
themeSwitcher.querySelector(`[data-theme="${body.className}"]`).classList.add('active');
// --- Feedback Buttons & Animations ---
const btnLol = document.getElementById('btn-lol');
const btnCold = document.getElementById('btn-cold');
const btnSeen = document.getElementById('btn-seen');
const btnAbsurd = document.getElementById('btn-absurd');
const soundLol = document.getElementById('sound-lol');
const soundCold = document.getElementById('sound-cold');
btnLol.addEventListener('click', () => {
soundLol.play();
createParticles(20, 'confetti');
});
btnCold.addEventListener('click', () => {
soundCold.play();
createParticles(15, 'snowflake');
});
btnSeen.addEventListener('click', () => {
displayJoke("原来你也听过!那再给你换个新鲜的~");
setTimeout(fetchJoke, 1500);
});
btnAbsurd.addEventListener('click', () => {
jokeCard.classList.add('absurd');
setTimeout(() => jokeCard.classList.remove('absurd'), 1000);
});
function createParticles(count, type) {
animationContainer.innerHTML = ''; // Clear previous
const colors = ['#ffca28', '#ff7043', '#29b6f6', '#66bb6a'];
for (let i = 0; i < count; i++) {
const particle = document.createElement('div');
particle.classList.add(type);
if (type === 'confetti') {
particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
} else {
particle.textContent = '❄️';
}
particle.style.left = `${Math.random() * 100}vw`;
const duration = Math.random() * 3 + 2; // 2-5 seconds
const delay = Math.random() * -duration; // Start at different times
particle.style.animationDuration = `${duration}s`;
particle.style.animationDelay = `${delay}s`;
animationContainer.appendChild(particle);
}
}
// --- Event Listeners ---
newJokeBtn.addEventListener('click', fetchJoke);
// --- Initial Load ---
fetchJoke();
});

View File

@@ -0,0 +1,47 @@
{
"api_name": "60s-api",
"api_version": "2.22.1",
"api_docs": "https://docs.60s-api.viki.moe",
"author": "Viki <hi@viki.moe>",
"user_group": "595941841",
"github_repo": "https://github.com/vikiboss/60s",
"updated": "2025/09/01 11:12:08",
"updated_at": 1756696328000,
"endpoints": [
"/v2/60s",
"/v2/answer",
"/v2/baike",
"/v2/bili",
"/v2/bing",
"/v2/changya",
"/v2/chemical",
"/v2/douyin",
"/v2/duanzi",
"/v2/epic",
"/v2/exchange_rate",
"/v2/fabing",
"/v2/hitokoto",
"/v2/ip",
"/v2/kfc",
"/v2/luck",
"/v2/maoyan",
"/v2/today_in_history",
"/v2/toutiao",
"/v2/weibo",
"/v2/zhihu",
"/v2/lunar",
"/v2/ai-news",
"/v2/awesome-js",
"/v2/qrcode",
"/v2/dad-joke",
"/v2/hacker-news/:type",
"/v2/og",
"/v2/hash",
"/v2/fanyi",
"/v2/fanyi/langs",
"/v2/weather",
"/v2/weather/forecast",
"/v2/ncm-rank",
"/v2/ncm-rank/:id"
]
}

View File

@@ -0,0 +1,8 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"index": 347,
"duanzi": "我不想读书,主要是因为家里牛啊,猪啊羊啊都没人喂。"
}
}