随机发病,运势,冷笑话,段子
This commit is contained in:
16
frontend/60sapi/娱乐消遣/随机冷笑话/css/Untitled-1.html
Normal file
16
frontend/60sapi/娱乐消遣/随机冷笑话/css/Untitled-1.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!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="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="card">
|
||||||
|
<p id="joke">加载中...</p>
|
||||||
|
<button id="next">换一个</button>
|
||||||
|
</div>
|
||||||
|
<script src="script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
107
frontend/60sapi/娱乐消遣/随机冷笑话/css/background.css
Normal file
107
frontend/60sapi/娱乐消遣/随机冷笑话/css/background.css
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/* background.css - 动态渐变背景 */
|
||||||
|
body {
|
||||||
|
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
|
||||||
|
background-size: 400% 400%;
|
||||||
|
animation: gradient 15s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes gradient {
|
||||||
|
0% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:root {
|
||||||
|
--bg-yellow: #FFFDE7; /* 浅黄 */
|
||||||
|
--bg-blue: #E3F2FD; /* 淡蓝 */
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: linear-gradient(180deg, var(--bg-yellow) 0%, var(--bg-blue) 100%);
|
||||||
|
background-attachment: fixed; /* 固定背景,滚动时不移动 */
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: background-color 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light Theme (Default) */
|
||||||
|
[data-theme="light"] {
|
||||||
|
background: linear-gradient(to bottom, #87CEEB, #B0E0E6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark Theme */
|
||||||
|
[data-theme="dark"] {
|
||||||
|
background: linear-gradient(to bottom, #232526, #414345);
|
||||||
|
}
|
||||||
|
[data-theme="dark"] .snowflake {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Winter Theme */
|
||||||
|
[data-theme="winter"] {
|
||||||
|
background: linear-gradient(to bottom, #a1c4fd, #c2e9fb);
|
||||||
|
}
|
||||||
|
[data-theme="winter"] .background-bottom {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
background: linear-gradient(to top, white, rgba(255, 255, 255, 0));
|
||||||
|
z-index: -1;
|
||||||
|
border-radius: 50% 50% 0 0 / 20px;
|
||||||
|
box-shadow: 0 -10px 20px rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#snowflake-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.snowflake {
|
||||||
|
position: absolute;
|
||||||
|
top: -10%;
|
||||||
|
color: white;
|
||||||
|
font-size: 20px;
|
||||||
|
user-select: none;
|
||||||
|
animation: fall linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fall {
|
||||||
|
to {
|
||||||
|
transform: translateY(105vh) rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#frost-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url('https://www.transparenttextures.com/patterns/ice-age.png') repeat;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.5s ease-in-out;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
#frost-overlay.is-frosted {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
217
frontend/60sapi/娱乐消遣/随机冷笑话/css/style.css
Normal file
217
frontend/60sapi/娱乐消遣/随机冷笑话/css/style.css
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
:root {
|
||||||
|
--primary-color-light: #4A90E2;
|
||||||
|
--text-color-light: #333;
|
||||||
|
--card-bg-light: rgba(255, 255, 255, 0.85);
|
||||||
|
|
||||||
|
--primary-color-dark: #5271C4;
|
||||||
|
--text-color-dark: #E0E0E0;
|
||||||
|
--card-bg-dark: rgba(40, 40, 40, 0.85);
|
||||||
|
|
||||||
|
--primary-color-winter: #6A82FB;
|
||||||
|
--text-color-winter: #2c3e50;
|
||||||
|
--card-bg-winter: rgba(255, 255, 255, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-nav {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 50px;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-switcher {
|
||||||
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-btn {
|
||||||
|
background: transparent;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 1.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s, border-color 0.2s;
|
||||||
|
}
|
||||||
|
.theme-btn:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
.theme-btn.active {
|
||||||
|
border-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-family: 'ZCOOL KuaiLe', cursive;
|
||||||
|
font-size: 3em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
transition: color 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.joke-stream {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.joke-card {
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 30px 40px;
|
||||||
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
min-height: 150px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
transition: background-color 0.5s ease, border-color 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#joke-text {
|
||||||
|
font-size: 1.5em;
|
||||||
|
line-height: 1.6;
|
||||||
|
transition: opacity 0.3s, color 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Theming --- */
|
||||||
|
|
||||||
|
/* Light Theme */
|
||||||
|
[data-theme="light"] .title { color: white; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); }
|
||||||
|
[data-theme="light"] .joke-card { background-color: var(--card-bg-light); }
|
||||||
|
[data-theme="light"] #joke-text { color: var(--text-color-light); }
|
||||||
|
[data-theme="light"] #new-joke-btn { background-color: var(--primary-color-light); box-shadow: 0 4px 15px rgba(74, 144, 226, 0.4); }
|
||||||
|
[data-theme="light"] footer { color: rgba(255, 255, 255, 0.8); }
|
||||||
|
|
||||||
|
/* Dark Theme */
|
||||||
|
[data-theme="dark"] .title { color: #EAEAEA; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); }
|
||||||
|
[data-theme="dark"] .joke-card { background-color: var(--card-bg-dark); border-color: rgba(255, 255, 255, 0.1); }
|
||||||
|
[data-theme="dark"] #joke-text { color: var(--text-color-dark); }
|
||||||
|
[data-theme="dark"] #new-joke-btn { background-color: var(--primary-color-dark); box-shadow: 0 4px 15px rgba(82, 113, 196, 0.4); }
|
||||||
|
[data-theme="dark"] footer { color: rgba(200, 200, 200, 0.7); }
|
||||||
|
|
||||||
|
/* Winter Theme */
|
||||||
|
[data-theme="winter"] .title { color: #1e3a5f; text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.7); }
|
||||||
|
[data-theme="winter"] .joke-card {
|
||||||
|
background-color: var(--card-bg-winter);
|
||||||
|
border-color: rgba(255, 255, 255, 0.8);
|
||||||
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1), inset 0 0 15px rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
[data-theme="winter"] #joke-text { color: var(--text-color-winter); }
|
||||||
|
[data-theme="winter"] #new-joke-btn { background-color: var(--primary-color-winter); box-shadow: 0 4px 15px rgba(106, 130, 251, 0.4); }
|
||||||
|
[data-theme="winter"] footer { color: #1e3a5f; }
|
||||||
|
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#new-joke-btn {
|
||||||
|
color: white;
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 15px 35px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#new-joke-btn:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#new-joke-btn:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.interactions {
|
||||||
|
margin-top: 25px;
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interaction-btn {
|
||||||
|
background: rgba(255, 255, 255, 0.7);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.9);
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 1.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s, background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interaction-btn:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
transition: color 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loader */
|
||||||
|
#loader {
|
||||||
|
position: absolute;
|
||||||
|
transition: color 0.5s ease;
|
||||||
|
}
|
||||||
|
[data-theme="light"] #loader { color: var(--primary-color-light); }
|
||||||
|
[data-theme="dark"] #loader { color: var(--primary-color-dark); }
|
||||||
|
[data-theme="winter"] #loader { color: var(--primary-color-winter); }
|
||||||
|
|
||||||
|
.snowflake-loader {
|
||||||
|
font-size: 40px;
|
||||||
|
display: inline-block;
|
||||||
|
animation: spin 1.5s linear infinite;
|
||||||
|
}
|
||||||
|
.snowflake-loader::before {
|
||||||
|
content: '❄';
|
||||||
|
}
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.title {
|
||||||
|
font-size: 2.5em;
|
||||||
|
}
|
||||||
|
.joke-card {
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
#joke-text {
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
.top-nav {
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
58
frontend/60sapi/娱乐消遣/随机冷笑话/index.html
Normal file
58
frontend/60sapi/娱乐消遣/随机冷笑话/index.html
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<!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 href="https://fonts.googleapis.com/css2?family=ZCOOL+KuaiLe&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="css/background.css">
|
||||||
|
<link rel="stylesheet" href="css/style.css">
|
||||||
|
</head>
|
||||||
|
<body data-theme="light">
|
||||||
|
<div id="snowflake-container"></div>
|
||||||
|
<div id="frost-overlay"></div>
|
||||||
|
<div class="background-bottom"></div>
|
||||||
|
|
||||||
|
<nav class="top-nav">
|
||||||
|
<div class="theme-switcher">
|
||||||
|
<button class="theme-btn" data-theme-target="light" title="清新风">☀️</button>
|
||||||
|
<button class="theme-btn" data-theme-target="dark" title="暗黑风">🌙</button>
|
||||||
|
<button class="theme-btn" data-theme-target="winter" title="冰雪风">❄️</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<h1 class="title">冷笑话生成器</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="joke-card">
|
||||||
|
<div id="loader" class="hidden">
|
||||||
|
<div class="snowflake-loader"></div>
|
||||||
|
<p>思考中...</p>
|
||||||
|
</div>
|
||||||
|
<p id="joke-text">点击下面的按钮,来点冷笑话吧!</p>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<button id="new-joke-btn">再来一个</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="interactions">
|
||||||
|
<button class="interaction-btn" id="like-btn" title="好笑">👍</button>
|
||||||
|
<button class="interaction-btn" id="dislike-btn" title="不好笑">👎</button>
|
||||||
|
<button class="interaction-btn" id="collect-btn" title="收藏">⭐️</button>
|
||||||
|
<button class="interaction-btn" id="share-btn" title="分享">🔗</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>© 2024 冷笑话工坊</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<audio id="wind-sound" src="https://www.soundjay.com/nature/sounds/wind-howl-01.mp3" preload="auto"></audio>
|
||||||
|
<audio id="snow-sound" src="https://www.soundjay.com/nature/sounds/walking-in-snow-01.mp3" preload="auto"></audio>
|
||||||
|
|
||||||
|
<script src="js/script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
117
frontend/60sapi/娱乐消遣/随机冷笑话/js/script.js
Normal file
117
frontend/60sapi/娱乐消遣/随机冷笑话/js/script.js
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const jokeTextElem = document.getElementById('joke-text');
|
||||||
|
const newJokeBtn = document.getElementById('new-joke-btn');
|
||||||
|
const snowflakeContainer = document.getElementById('snowflake-container');
|
||||||
|
const frostOverlay = document.getElementById('frost-overlay');
|
||||||
|
const windSound = document.getElementById('wind-sound');
|
||||||
|
const snowSound = document.getElementById('snow-sound');
|
||||||
|
const loader = document.getElementById('loader');
|
||||||
|
const themeBtns = document.querySelectorAll('.theme-btn');
|
||||||
|
|
||||||
|
const apiEndpoints = [
|
||||||
|
'https://60s.api.shumengya.top/v2/dad-joke',
|
||||||
|
];
|
||||||
|
let currentApiIndex = 0;
|
||||||
|
|
||||||
|
async function fetchJoke() {
|
||||||
|
jokeTextElem.classList.add('hidden');
|
||||||
|
loader.classList.remove('hidden');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(apiEndpoints[currentApiIndex]);
|
||||||
|
if (!response.ok) throw new Error('Network response was not ok');
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.code === 200 && data.data.content) {
|
||||||
|
updateJokeText(data.data.content);
|
||||||
|
if (document.body.dataset.theme === 'winter' && Math.random() < 0.3) {
|
||||||
|
triggerFrostEffect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('API returned invalid data');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Fetch error:', error);
|
||||||
|
currentApiIndex = (currentApiIndex + 1) % apiEndpoints.length;
|
||||||
|
if (currentApiIndex !== 0) {
|
||||||
|
fetchJoke();
|
||||||
|
} else {
|
||||||
|
jokeTextElem.textContent = '冰箱坏了,暂时没有冷笑话...';
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
loader.classList.add('hidden');
|
||||||
|
jokeTextElem.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateJokeText(text) {
|
||||||
|
jokeTextElem.textContent = '';
|
||||||
|
let i = 0;
|
||||||
|
const typing = setInterval(() => {
|
||||||
|
if (i < text.length) {
|
||||||
|
jokeTextElem.textContent += text.charAt(i);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
clearInterval(typing);
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSnowflakes() {
|
||||||
|
const snowflakeCount = document.body.dataset.theme === 'dark' ? 50 : 30;
|
||||||
|
snowflakeContainer.innerHTML = '';
|
||||||
|
for (let i = 0; i < snowflakeCount; i++) {
|
||||||
|
const snowflake = document.createElement('div');
|
||||||
|
snowflake.className = 'snowflake';
|
||||||
|
snowflake.textContent = '❄️';
|
||||||
|
|
||||||
|
snowflake.style.left = `${Math.random() * 100}vw`;
|
||||||
|
snowflake.style.fontSize = `${Math.random() * 15 + 10}px`;
|
||||||
|
snowflake.style.opacity = Math.random() * 0.5 + 0.3;
|
||||||
|
|
||||||
|
const duration = Math.random() * 10 + 8;
|
||||||
|
const delay = Math.random() * 10;
|
||||||
|
|
||||||
|
snowflake.style.animation = `fall ${duration}s linear ${delay}s infinite`;
|
||||||
|
|
||||||
|
snowflakeContainer.appendChild(snowflake);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerFrostEffect() {
|
||||||
|
frostOverlay.classList.add('is-frosted');
|
||||||
|
windSound.play().catch(e => console.error("Audio play failed:", e));
|
||||||
|
setTimeout(() => {
|
||||||
|
frostOverlay.classList.remove('is-frosted');
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTheme(theme) {
|
||||||
|
document.body.dataset.theme = theme;
|
||||||
|
localStorage.setItem('joke-theme', theme);
|
||||||
|
|
||||||
|
themeBtns.forEach(btn => {
|
||||||
|
btn.classList.toggle('active', btn.dataset.themeTarget === theme);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (theme === 'winter') {
|
||||||
|
snowSound.play().catch(e => console.error("Audio play failed:", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recreate snowflakes for theme-specific density
|
||||||
|
createSnowflakes();
|
||||||
|
}
|
||||||
|
|
||||||
|
themeBtns.forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
setTheme(btn.dataset.themeTarget);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
newJokeBtn.addEventListener('click', fetchJoke);
|
||||||
|
|
||||||
|
// Initial setup
|
||||||
|
const savedTheme = localStorage.getItem('joke-theme') || 'light';
|
||||||
|
setTheme(savedTheme);
|
||||||
|
fetchJoke();
|
||||||
|
});
|
||||||
47
frontend/60sapi/娱乐消遣/随机冷笑话/接口集合.json
Normal file
47
frontend/60sapi/娱乐消遣/随机冷笑话/接口集合.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
8
frontend/60sapi/娱乐消遣/随机冷笑话/返回接口.json
Normal file
8
frontend/60sapi/娱乐消遣/随机冷笑话/返回接口.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841",
|
||||||
|
"data": {
|
||||||
|
"index": 121,
|
||||||
|
"content": "这个世界上谁最懂猪?蜘蛛(知猪)人。"
|
||||||
|
}
|
||||||
|
}
|
||||||
90
frontend/60sapi/娱乐消遣/随机发病文学/css/background.css
Normal file
90
frontend/60sapi/娱乐消遣/随机发病文学/css/background.css
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
body {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
color: #e0e0e0;
|
||||||
|
font-family: 'Courier New', Courier, monospace;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bg-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -2;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: transform 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floating-emoji {
|
||||||
|
position: absolute;
|
||||||
|
user-select: none;
|
||||||
|
opacity: 0;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float-top-to-bottom {
|
||||||
|
0% { transform: translateY(-10vh) rotate(0deg); opacity: 0; }
|
||||||
|
10%, 90% { opacity: 0.7; }
|
||||||
|
100% { transform: translateY(110vh) rotate(360deg); opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float-bottom-to-top {
|
||||||
|
0% { transform: translateY(110vh) rotate(0deg); opacity: 0; }
|
||||||
|
10%, 90% { opacity: 0.7; }
|
||||||
|
100% { transform: translateY(-10vh) rotate(360deg); opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float-left-to-right {
|
||||||
|
0% { transform: translateX(-10vw) rotate(0deg); opacity: 0; }
|
||||||
|
10%, 90% { opacity: 0.7; }
|
||||||
|
100% { transform: translateX(110vw) rotate(360deg); opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float-right-to-left {
|
||||||
|
0% { transform: translateX(110vw) rotate(0deg); opacity: 0; }
|
||||||
|
10%, 90% { opacity: 0.7; }
|
||||||
|
100% { transform: translateX(-10vw) rotate(360deg); opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-fragment {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 24px;
|
||||||
|
color: rgba(255, 0, 255, 0.4);
|
||||||
|
opacity: 0;
|
||||||
|
animation: float-fragment 15s linear infinite, fade-in-out 15s linear infinite;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float-fragment {
|
||||||
|
0% { transform: translate(0, 0) rotate(0deg); }
|
||||||
|
25% { transform: translate(20px, 40px) rotate(15deg); }
|
||||||
|
50% { transform: translate(-30px, -10px) rotate(-10deg); }
|
||||||
|
75% { transform: translate(10px, -30px) rotate(5deg); }
|
||||||
|
100% { transform: translate(0, 0) rotate(0deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-out {
|
||||||
|
0%, 100% { opacity: 0; }
|
||||||
|
10%, 90% { opacity: 0.4; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-crack {
|
||||||
|
position: absolute;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M 100 100 L 0 0 M 100 100 L 200 0 M 100 100 L 50 200 M 100 100 L 150 200" stroke="rgba(255,255,255,0.5)" stroke-width="1" fill="none"/></svg>');
|
||||||
|
opacity: 0;
|
||||||
|
animation: flicker-crack 25s steps(1, end) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flicker-crack {
|
||||||
|
0%, 100% { opacity: 0; }
|
||||||
|
50% { opacity: 0.3; }
|
||||||
|
51% { opacity: 0; }
|
||||||
|
75% { opacity: 0.2; }
|
||||||
|
76% { opacity: 0; }
|
||||||
|
}
|
||||||
235
frontend/60sapi/娱乐消遣/随机发病文学/css/style.css
Normal file
235
frontend/60sapi/娱乐消遣/随机发病文学/css/style.css
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-card {
|
||||||
|
background: rgba(20, 20, 20, 0.7);
|
||||||
|
border: none;
|
||||||
|
padding: 40px;
|
||||||
|
max-width: 600px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
position: relative;
|
||||||
|
clip-path: polygon(2% 5%, 97% 0%, 100% 95%, 0% 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-animated .content-card {
|
||||||
|
animation: tremble 0.4s infinite, glitch-shadow 1.5s steps(1, end) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes tremble {
|
||||||
|
0% { clip-path: polygon(2% 5%, 97% 0%, 100% 95%, 0% 100%); }
|
||||||
|
25% { clip-path: polygon(2% 5%, 98% 2%, 99% 100%, 1% 98%); }
|
||||||
|
50% { clip-path: polygon(3% 4%, 96% 1%, 100% 96%, 2% 100%); }
|
||||||
|
75% { clip-path: polygon(1% 6%, 97% 3%, 98% 95%, 0% 99%); }
|
||||||
|
100% { clip-path: polygon(2% 5%, 97% 0%, 100% 95%, 0% 100%); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes glitch-shadow {
|
||||||
|
0% {
|
||||||
|
box-shadow:
|
||||||
|
0 0 8px rgba(255, 0, 255, 0.5),
|
||||||
|
inset 0 0 8px rgba(255, 0, 255, 0.4);
|
||||||
|
}
|
||||||
|
33% {
|
||||||
|
box-shadow:
|
||||||
|
0 0 8px rgba(0, 255, 255, 0.5),
|
||||||
|
inset 0 0 8px rgba(0, 255, 255, 0.4);
|
||||||
|
}
|
||||||
|
66% {
|
||||||
|
box-shadow:
|
||||||
|
0 0 8px rgba(0, 255, 0, 0.5),
|
||||||
|
inset 0 0 8px rgba(0, 255, 0, 0.4);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
box-shadow:
|
||||||
|
0 0 8px rgba(255, 0, 255, 0.5),
|
||||||
|
inset 0 0 8px rgba(255, 0, 255, 0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#literature-text {
|
||||||
|
font-size: 1.2em;
|
||||||
|
line-height: 1.8;
|
||||||
|
min-height: 100px;
|
||||||
|
color: #e0e0e0;
|
||||||
|
text-shadow: 0 0 5px rgba(0, 255, 135, 0.5);
|
||||||
|
animation: text-flicker 15s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-animated #literature-text {
|
||||||
|
animation: text-flicker 15s linear infinite, text-shadow-glitch 2s steps(1, end) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes text-flicker {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50.0% { opacity: 0.95; }
|
||||||
|
50.5% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes text-shadow-glitch {
|
||||||
|
0% {
|
||||||
|
text-shadow:
|
||||||
|
1px 0 0 rgba(255,0,255,0.5),
|
||||||
|
-1px 0 0 rgba(0,255,255,0.5);
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
text-shadow:
|
||||||
|
-1px 0 0 rgba(255,0,255,0.5),
|
||||||
|
1px 0 0 rgba(0,255,255,0.5);
|
||||||
|
}
|
||||||
|
11%, 100% {
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
margin-top: 30px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#new-literature-btn {
|
||||||
|
background-color: #ff00ff;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 25px;
|
||||||
|
font-size: 1em;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: transform 0.2s, box-shadow 0.2s;
|
||||||
|
box-shadow: 0 0 10px #ff00ff, 0 0 20px #ff00ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#new-literature-btn:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 0 15px #ff00ff, 0 0 30px #ff00ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#new-literature-btn:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation Toggle Switch */
|
||||||
|
.switch-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 50px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #ccc;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
left: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
background-color: white;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .slider {
|
||||||
|
background-color: #ff00ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .slider:before {
|
||||||
|
transform: translateX(26px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider.round {
|
||||||
|
border-radius: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider.round:before {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Glitch Overlay & Animations */
|
||||||
|
#glitch-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-animated #glitch-overlay {
|
||||||
|
animation: color-shift 15s steps(1, end) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes color-shift {
|
||||||
|
0%, 100% { background: transparent; }
|
||||||
|
10% { background: rgba(255, 0, 0, 0.05); }
|
||||||
|
10.1% { background: transparent; }
|
||||||
|
20% { background: rgba(0, 255, 0, 0.05); }
|
||||||
|
20.1% { background: transparent; }
|
||||||
|
30% { background: rgba(0, 0, 255, 0.05); }
|
||||||
|
30.1% { background: transparent; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.flicker-block {
|
||||||
|
position: absolute;
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-animated .flicker-block {
|
||||||
|
animation: flicker 3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flicker {
|
||||||
|
0%, 100% { opacity: 0; }
|
||||||
|
50% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Design */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.content-card {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
#literature-text {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
.controls {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
frontend/60sapi/娱乐消遣/随机发病文学/index.html
Normal file
34
frontend/60sapi/娱乐消遣/随机发病文学/index.html
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<!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>
|
||||||
|
<div id="bg-container">
|
||||||
|
</div>
|
||||||
|
<div id="glitch-overlay"></div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="content-card">
|
||||||
|
<p id="literature-text">正在加载发病文学...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<button id="new-literature-btn">再疯一次</button>
|
||||||
|
<div class="switch-container">
|
||||||
|
<label for="animation-toggle">关闭动画</label>
|
||||||
|
<label class="switch">
|
||||||
|
<input type="checkbox" id="animation-toggle" checked>
|
||||||
|
<span class="slider round"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
147
frontend/60sapi/娱乐消遣/随机发病文学/js/script.js
Normal file
147
frontend/60sapi/娱乐消遣/随机发病文学/js/script.js
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const literatureTextElem = document.getElementById('literature-text');
|
||||||
|
const newLiteratureBtn = document.getElementById('new-literature-btn');
|
||||||
|
const animationToggle = document.getElementById('animation-toggle');
|
||||||
|
const bgContainer = document.getElementById('bg-container');
|
||||||
|
const body = document.body;
|
||||||
|
|
||||||
|
const apiEndpoints = [
|
||||||
|
'https://60s.api.shumengya.top/v2/fabing',
|
||||||
|
// Add fallback APIs here if available
|
||||||
|
];
|
||||||
|
|
||||||
|
let currentApiIndex = 0;
|
||||||
|
|
||||||
|
async function fetchLiterature() {
|
||||||
|
literatureTextElem.textContent = '正在卖力发疯中...';
|
||||||
|
literatureTextElem.style.opacity = '0.5';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(apiEndpoints[currentApiIndex]);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.code === 200) {
|
||||||
|
literatureTextElem.textContent = data.data.saying;
|
||||||
|
} else {
|
||||||
|
throw new Error('API returned an error');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Fetch error:', error);
|
||||||
|
currentApiIndex = (currentApiIndex + 1) % apiEndpoints.length;
|
||||||
|
if (currentApiIndex !== 0) {
|
||||||
|
fetchLiterature(); // Retry with the next API
|
||||||
|
} else {
|
||||||
|
literatureTextElem.textContent = '疯不起来了,请稍后再试。';
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
literatureTextElem.style.opacity = '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFloatingEmojis() {
|
||||||
|
const existingEmojis = bgContainer.querySelectorAll('.floating-emoji');
|
||||||
|
existingEmojis.forEach(e => e.remove());
|
||||||
|
|
||||||
|
const emojis = ['🤯', '😵', '🤪', '🥴', '🤡', '👹', '👻', '💀', '💥', '🔥', '🌪️', '😵💫'];
|
||||||
|
const animationNames = ['float-top-to-bottom', 'float-bottom-to-top', 'float-left-to-right', 'float-right-to-left'];
|
||||||
|
const emojiCount = 25;
|
||||||
|
|
||||||
|
for (let i = 0; i < emojiCount; i++) {
|
||||||
|
const emojiEl = document.createElement('div');
|
||||||
|
emojiEl.className = 'floating-emoji';
|
||||||
|
emojiEl.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||||
|
|
||||||
|
const animationName = animationNames[Math.floor(Math.random() * animationNames.length)];
|
||||||
|
emojiEl.style.animationName = animationName;
|
||||||
|
emojiEl.style.animationDuration = `${Math.random() * 10 + 15}s`; // 15-25 seconds
|
||||||
|
emojiEl.style.animationDelay = `${Math.random() * 20}s`;
|
||||||
|
emojiEl.style.fontSize = `${Math.random() * 20 + 20}px`;
|
||||||
|
|
||||||
|
// Set initial position based on animation direction
|
||||||
|
if (animationName.includes('top') || animationName.includes('bottom')) { // Vertical movement
|
||||||
|
emojiEl.style.left = `${Math.random() * 100}vw`;
|
||||||
|
} else { // Horizontal movement
|
||||||
|
emojiEl.style.top = `${Math.random() * 100}vh`;
|
||||||
|
}
|
||||||
|
|
||||||
|
bgContainer.appendChild(emojiEl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFragments() {
|
||||||
|
const existingFragments = bgContainer.querySelectorAll('.text-fragment');
|
||||||
|
existingFragments.forEach(f => f.remove());
|
||||||
|
|
||||||
|
const fragments = ['我', '疯', '了', '?', '!', '…', '救命', '为什么', '好烦', '啊啊啊'];
|
||||||
|
for (let i = 0; i < 20; i++) {
|
||||||
|
const frag = document.createElement('div');
|
||||||
|
frag.className = 'text-fragment';
|
||||||
|
frag.textContent = fragments[Math.floor(Math.random() * fragments.length)];
|
||||||
|
frag.style.top = `${Math.random() * 100}%`;
|
||||||
|
frag.style.left = `${Math.random() * 100}%`;
|
||||||
|
frag.style.animationDelay = `${Math.random() * 15}s`;
|
||||||
|
frag.style.fontSize = `${Math.random() * 12 + 12}px`;
|
||||||
|
bgContainer.appendChild(frag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCracks() {
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
const crack = document.createElement('div');
|
||||||
|
crack.className = 'screen-crack';
|
||||||
|
crack.style.top = `${Math.random() * 80}%`;
|
||||||
|
crack.style.left = `${Math.random() * 80}%`;
|
||||||
|
crack.style.transform = `rotate(${Math.random() * 360}deg)`;
|
||||||
|
crack.style.animationDelay = `${Math.random() * 25}s`;
|
||||||
|
bgContainer.appendChild(crack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFlickerBlocks() {
|
||||||
|
const glitchOverlay = document.getElementById('glitch-overlay');
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
const block = document.createElement('div');
|
||||||
|
block.className = 'flicker-block';
|
||||||
|
block.style.width = `${Math.random() * 100 + 50}px`;
|
||||||
|
block.style.height = `${Math.random() * 100 + 50}px`;
|
||||||
|
block.style.top = `${Math.random() * 90}%`;
|
||||||
|
block.style.left = `${Math.random() * 90}%`;
|
||||||
|
block.style.animationDuration = `${Math.random() * 2 + 2}s`;
|
||||||
|
block.style.animationDelay = `${Math.random() * 3}s`;
|
||||||
|
glitchOverlay.appendChild(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleAnimations() {
|
||||||
|
if (animationToggle.checked) {
|
||||||
|
body.classList.add('body-animated');
|
||||||
|
} else {
|
||||||
|
body.classList.remove('body-animated');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', (e) => {
|
||||||
|
if (!animationToggle.checked) return;
|
||||||
|
const x = (window.innerWidth / 2) - e.pageX;
|
||||||
|
const y = (window.innerHeight / 2) - e.pageY;
|
||||||
|
bgContainer.style.transform = `translateX(${x / 50}px) translateY(${y / 50}px)`;
|
||||||
|
});
|
||||||
|
|
||||||
|
newLiteratureBtn.addEventListener('click', fetchLiterature);
|
||||||
|
animationToggle.addEventListener('change', toggleAnimations);
|
||||||
|
|
||||||
|
// Initial setup
|
||||||
|
createFloatingEmojis();
|
||||||
|
createFragments();
|
||||||
|
createCracks();
|
||||||
|
createFlickerBlocks();
|
||||||
|
toggleAnimations();
|
||||||
|
fetchLiterature();
|
||||||
|
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
createFloatingEmojis();
|
||||||
|
createFragments();
|
||||||
|
});
|
||||||
|
});
|
||||||
47
frontend/60sapi/娱乐消遣/随机发病文学/接口集合.json
Normal file
47
frontend/60sapi/娱乐消遣/随机发病文学/接口集合.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
8
frontend/60sapi/娱乐消遣/随机发病文学/返回接口.json
Normal file
8
frontend/60sapi/娱乐消遣/随机发病文学/返回接口.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841",
|
||||||
|
"data": {
|
||||||
|
"index": 347,
|
||||||
|
"duanzi": "我不想读书,主要是因为家里牛啊,猪啊羊啊都没人喂。"
|
||||||
|
}
|
||||||
|
}
|
||||||
36
frontend/60sapi/娱乐消遣/随机搞笑段子/css/background.css
Normal file
36
frontend/60sapi/娱乐消遣/随机搞笑段子/css/background.css
Normal 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;
|
||||||
|
}
|
||||||
199
frontend/60sapi/娱乐消遣/随机搞笑段子/css/style.css
Normal file
199
frontend/60sapi/娱乐消遣/随机搞笑段子/css/style.css
Normal 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; }
|
||||||
|
}
|
||||||
59
frontend/60sapi/娱乐消遣/随机搞笑段子/index.html
Normal file
59
frontend/60sapi/娱乐消遣/随机搞笑段子/index.html
Normal 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>
|
||||||
122
frontend/60sapi/娱乐消遣/随机搞笑段子/js/script.js
Normal file
122
frontend/60sapi/娱乐消遣/随机搞笑段子/js/script.js
Normal 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();
|
||||||
|
});
|
||||||
47
frontend/60sapi/娱乐消遣/随机搞笑段子/接口集合.json
Normal file
47
frontend/60sapi/娱乐消遣/随机搞笑段子/接口集合.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
8
frontend/60sapi/娱乐消遣/随机搞笑段子/返回接口.json
Normal file
8
frontend/60sapi/娱乐消遣/随机搞笑段子/返回接口.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841",
|
||||||
|
"data": {
|
||||||
|
"index": 347,
|
||||||
|
"duanzi": "我不想读书,主要是因为家里牛啊,猪啊羊啊都没人喂。"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
frontend/60sapi/娱乐消遣/随机运势/css/background.css
Normal file
26
frontend/60sapi/娱乐消遣/随机运势/css/background.css
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
body {
|
||||||
|
background: linear-gradient(-45deg, #0a021a, #2a0d3f, #4a1a6c, #7b2f8f);
|
||||||
|
background-size: 400% 400%;
|
||||||
|
animation: gradientBG 20s ease infinite;
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes gradientBG {
|
||||||
|
0% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
342
frontend/60sapi/娱乐消遣/随机运势/css/style.css
Normal file
342
frontend/60sapi/娱乐消遣/随机运势/css/style.css
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 600px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-size: 2.8em;
|
||||||
|
color: #f0e6ff;
|
||||||
|
text-shadow: 0 0 10px #d1a9ff, 0 0 20px #d1a9ff;
|
||||||
|
margin-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
header p {
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #e0c8ff;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crystal-ball-container {
|
||||||
|
perspective: 1000px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crystal-ball {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.6), rgba(200, 180, 255, 0.1));
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 0 30px #c390ff, 0 0 60px #a060e0, inset 0 0 20px rgba(255, 220, 255, 0.3);
|
||||||
|
animation: float 6s ease-in-out infinite;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reflection {
|
||||||
|
width: 80px;
|
||||||
|
height: 40px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 40px;
|
||||||
|
transform: rotate(-30deg);
|
||||||
|
filter: blur(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.swirl {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 120%;
|
||||||
|
height: 120%;
|
||||||
|
background: linear-gradient(45deg, rgba(255, 192, 203, 0.1), rgba(128, 0, 128, 0.2));
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: swirl 10s linear infinite;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-20px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes swirl {
|
||||||
|
from { transform: translate(-50%, -50%) rotate(0deg); }
|
||||||
|
to { transform: translate(-50%, -50%) rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.fortune-card {
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
min-height: 120px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
|
||||||
|
transition: opacity 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fortune-content {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fortune-content.visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#luck-desc {
|
||||||
|
font-size: 2em;
|
||||||
|
color: #ffc0cb;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#luck-tip {
|
||||||
|
font-size: 1.1em;
|
||||||
|
color: #e0e0e0;
|
||||||
|
margin: 0;
|
||||||
|
padding-bottom: 20px; /* Add some space before the new details */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fortune-details {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-top: 20px;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item h3 {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #ffc0cb;
|
||||||
|
margin: 0 0 5px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item p {
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#lucky-color {
|
||||||
|
display: inline-block;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2px solid white;
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
||||||
|
/* Remove the text content */
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tarot Card Styles */
|
||||||
|
.tarot-container {
|
||||||
|
margin-top: 40px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-container h2 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
color: #f0e6ff;
|
||||||
|
text-shadow: 0 0 8px #d1a9ff;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-card-container {
|
||||||
|
width: 180px;
|
||||||
|
height: 280px;
|
||||||
|
perspective: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-card-inner {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transition: transform 0.8s;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-card-container.flipped .tarot-card-inner {
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-card-front,
|
||||||
|
.tarot-card-back {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-card-back {
|
||||||
|
background: linear-gradient(135deg, #4a1a6c, #2a0d3f);
|
||||||
|
border: 2px solid #d1a9ff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 3em;
|
||||||
|
color: #d1a9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-card-back::after {
|
||||||
|
content: '✧'; /* A simple star symbol */
|
||||||
|
text-shadow: 0 0 10px #f0e6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-card-front {
|
||||||
|
background: linear-gradient(135deg, #3e165b, #592883);
|
||||||
|
border: 2px solid #d1a9ff;
|
||||||
|
color: white;
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tarot-name {
|
||||||
|
font-size: 1.4em;
|
||||||
|
color: #ffc0cb;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tarot-interpretation {
|
||||||
|
font-size: 0.9em;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Side Decorations */
|
||||||
|
.side-decor {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 15vw;
|
||||||
|
height: 100vh;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-decor {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-decor {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decor-symbol {
|
||||||
|
position: absolute;
|
||||||
|
color: rgba(209, 169, 255, 0.5);
|
||||||
|
text-shadow: 0 0 10px rgba(240, 230, 255, 0.7);
|
||||||
|
animation: floatSymbol 20s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes floatSymbol {
|
||||||
|
0%, 100% {
|
||||||
|
transform: translateY(0) rotate(0deg);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
25%, 75% {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateY(-20vh) rotate(180deg);
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#get-fortune-btn {
|
||||||
|
background: linear-gradient(45deg, #da70d6, #8a2be2);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding: 15px 30px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s, box-shadow 0.2s;
|
||||||
|
box-shadow: 0 0 15px #c390ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#get-fortune-btn:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 0 25px #d1a9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#get-fortune-btn:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
border: 4px solid rgba(255, 255, 255, 0.2);
|
||||||
|
border-left-color: #ffc0cb;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
display: none; /* Hidden by default */
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner.visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
margin-top: 40px;
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Design */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
header h1 {
|
||||||
|
font-size: 2.2em;
|
||||||
|
}
|
||||||
|
.crystal-ball {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
.fortune-card {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.fortune-details {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tarot-card-container {
|
||||||
|
width: 150px;
|
||||||
|
height: 233px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide side decor on smaller screens */
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.side-decor {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
71
frontend/60sapi/娱乐消遣/随机运势/index.html
Normal file
71
frontend/60sapi/娱乐消遣/随机运势/index.html
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<!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>
|
||||||
|
<div class="side-decor left-decor"></div>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<h1>水晶球占卜</h1>
|
||||||
|
<p>洞察你今日的运势</p>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<div class="crystal-ball-container">
|
||||||
|
<div class="crystal-ball">
|
||||||
|
<div class="reflection"></div>
|
||||||
|
<div class="swirl"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="fortune-card" class="fortune-card">
|
||||||
|
<div class="loading-spinner"></div>
|
||||||
|
<div class="fortune-content">
|
||||||
|
<h2 id="luck-desc"></h2>
|
||||||
|
<p id="luck-tip"></p>
|
||||||
|
<div class="fortune-details">
|
||||||
|
<div class="detail-item">
|
||||||
|
<h3>今日咒语</h3>
|
||||||
|
<p id="fortune-summary"></p>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<h3>幸运色</h3>
|
||||||
|
<p id="lucky-color"></p>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<h3>幸运数字</h3>
|
||||||
|
<p id="lucky-number"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- New Tarot Card Section -->
|
||||||
|
<div class="tarot-container">
|
||||||
|
<h2>每日塔罗指引</h2>
|
||||||
|
<div id="tarot-card" class="tarot-card-container">
|
||||||
|
<div class="tarot-card-inner">
|
||||||
|
<div class="tarot-card-back">
|
||||||
|
<!-- Back of the card design -->
|
||||||
|
</div>
|
||||||
|
<div class="tarot-card-front">
|
||||||
|
<h3 id="tarot-name"></h3>
|
||||||
|
<p id="tarot-interpretation"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="get-fortune-btn">再次占卜</button>
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<p>仅供娱乐,祝您好运</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
<div class="side-decor right-decor"></div>
|
||||||
|
<script src="js/script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
175
frontend/60sapi/娱乐消遣/随机运势/js/script.js
Normal file
175
frontend/60sapi/娱乐消遣/随机运势/js/script.js
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const getFortuneBtn = document.getElementById('get-fortune-btn');
|
||||||
|
const fortuneCard = document.getElementById('fortune-card');
|
||||||
|
const fortuneContent = fortuneCard.querySelector('.fortune-content');
|
||||||
|
const luckDescElem = document.getElementById('luck-desc');
|
||||||
|
const luckTipElem = document.getElementById('luck-tip');
|
||||||
|
const fortuneSummaryElem = document.getElementById('fortune-summary');
|
||||||
|
const luckyColorElem = document.getElementById('lucky-color');
|
||||||
|
const luckyNumberElem = document.getElementById('lucky-number');
|
||||||
|
const loadingSpinner = fortuneCard.querySelector('.loading-spinner');
|
||||||
|
const tarotCardContainer = document.getElementById('tarot-card');
|
||||||
|
const tarotNameElem = document.getElementById('tarot-name');
|
||||||
|
const tarotInterpretationElem = document.getElementById('tarot-interpretation');
|
||||||
|
|
||||||
|
const apiBaseUrls = [
|
||||||
|
"https://60s.api.shumengya.top",
|
||||||
|
"https://60s-cf.viki.moe",
|
||||||
|
"https://60s.viki.moe",
|
||||||
|
"https://60s.b23.run",
|
||||||
|
"https://60s.114128.xyz",
|
||||||
|
"https://60s-cf.114128.xyz"
|
||||||
|
];
|
||||||
|
const apiPath = "/v2/luck";
|
||||||
|
|
||||||
|
const mantras = [
|
||||||
|
"顺其自然,皆是美好。",
|
||||||
|
"相信直觉,它知道方向。",
|
||||||
|
"每一次呼吸都是新的开始。",
|
||||||
|
"心怀感恩,好运自来。",
|
||||||
|
"拥抱变化,发现惊喜。",
|
||||||
|
"你的能量,超乎想象。",
|
||||||
|
"保持微笑,宇宙会回应你。"
|
||||||
|
];
|
||||||
|
|
||||||
|
const tarotDeck = [
|
||||||
|
{ name: "愚者", interpretation: "新的开始,无限的潜力,天真和自由。勇敢地迈出第一步。" },
|
||||||
|
{ name: "魔术师", interpretation: "创造力,意志力,显化。你拥有实现目标所需的一切资源。" },
|
||||||
|
{ name: "女祭司", interpretation: "直觉,潜意识,神秘。倾听你内心的声音,智慧在你之内。" },
|
||||||
|
{ name: "皇后", interpretation: "丰饶,母性,创造。享受生活的美好,与自然和谐相处。" },
|
||||||
|
{ name: "皇帝", interpretation: "权威,结构,控制。建立秩序和纪律,掌控你的生活。" },
|
||||||
|
{ name: "教皇", interpretation: "传统,信仰,灵性指导。寻求智慧和知识,遵循传统。" },
|
||||||
|
{ name: "恋人", interpretation: "爱,和谐,选择。做出与你内心价值观一致的决定。" },
|
||||||
|
{ name: "战车", interpretation: "胜利,决心,控制。以坚定的意志力克服障碍,勇往直前。" },
|
||||||
|
{ name: "力量", interpretation: "勇气,内在力量,同情。用温柔和耐心驯服内心的野兽。" },
|
||||||
|
{ name: "隐士", interpretation: "内省,孤独,寻求真理。花时间独处,向内寻求答案。" },
|
||||||
|
{ name: "命运之轮", interpretation: "变化,命运,转折点。生活总在变化,顺应潮流。" },
|
||||||
|
{ name: "正义", interpretation: "公平,真理,因果。为你的行为负责,寻求平衡。" },
|
||||||
|
{ name: "倒吊人", interpretation: "新的视角,顺从,牺牲。放手,从不同的角度看问题。" },
|
||||||
|
{ name: "死神", interpretation: "结束,转变,新生。一个周期的结束是另一个周期的开始。" },
|
||||||
|
{ name: "节制", interpretation: "平衡,和谐,耐心。融合对立的力量,找到中间道路。" },
|
||||||
|
{ name: "恶魔", interpretation: "束缚,物质主义,诱惑。认识到你的束缚,并寻求解放。" },
|
||||||
|
{ name: "塔", interpretation: "突变,启示,解放。旧的结构正在崩塌,为新的结构让路。" },
|
||||||
|
{ name: "星星", interpretation: "希望,灵感,平静。在黑暗之后,总有希望的曙光。" },
|
||||||
|
{ name: "月亮", interpretation: "幻觉,恐惧,潜意识。面对你的恐惧,相信你的直觉。" },
|
||||||
|
{ name: "太阳", interpretation: "成功,喜悦,活力。拥抱光明,享受生活的乐趣。" },
|
||||||
|
{ name: "审判", interpretation: "觉醒,重生,评估。一个反思和更新的时刻。" },
|
||||||
|
{ name: "世界", interpretation: "完成,整合,成就。一个旅程的成功结束,庆祝你的成就。" }
|
||||||
|
];
|
||||||
|
|
||||||
|
let currentApiIndex = 0;
|
||||||
|
|
||||||
|
const showLoading = (isLoading) => {
|
||||||
|
if (isLoading) {
|
||||||
|
fortuneContent.classList.remove('visible');
|
||||||
|
loadingSpinner.classList.add('visible');
|
||||||
|
} else {
|
||||||
|
loadingSpinner.classList.remove('visible');
|
||||||
|
setTimeout(() => {
|
||||||
|
fortuneContent.classList.add('visible');
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchFortune = async () => {
|
||||||
|
showLoading(true);
|
||||||
|
tarotCardContainer.classList.remove('flipped'); // Reset card on new fetch
|
||||||
|
|
||||||
|
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) {
|
||||||
|
updateFortune(data.data);
|
||||||
|
drawTarotCard(); // Draw a tarot card on success
|
||||||
|
} 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) {
|
||||||
|
fetchFortune(); // Try next API
|
||||||
|
} else {
|
||||||
|
displayError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateFortune = (data) => {
|
||||||
|
luckDescElem.textContent = data.luck_desc || '运势';
|
||||||
|
luckTipElem.textContent = data.luck_tip || '今日运势平平,保持好心情。';
|
||||||
|
|
||||||
|
// Generate and display additional details
|
||||||
|
fortuneSummaryElem.textContent = mantras[Math.floor(Math.random() * mantras.length)];
|
||||||
|
luckyColorElem.style.backgroundColor = `#${Math.floor(Math.random()*16777215).toString(16).padStart(6, '0')}`;
|
||||||
|
luckyNumberElem.textContent = Math.floor(Math.random() * 100);
|
||||||
|
|
||||||
|
showLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const displayError = () => {
|
||||||
|
luckDescElem.textContent = '占卜失败';
|
||||||
|
luckTipElem.textContent = '无法连接到星辰之力,请稍后再试。';
|
||||||
|
fortuneSummaryElem.textContent = '---';
|
||||||
|
luckyColorElem.style.backgroundColor = 'transparent';
|
||||||
|
luckyNumberElem.textContent = '-';
|
||||||
|
showLoading(false);
|
||||||
|
tarotNameElem.textContent = '指引中断';
|
||||||
|
tarotInterpretationElem.textContent = '星辰之力暂时无法连接。';
|
||||||
|
tarotCardContainer.classList.add('flipped'); // Show error on card
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawTarotCard = () => {
|
||||||
|
const card = tarotDeck[Math.floor(Math.random() * tarotDeck.length)];
|
||||||
|
tarotNameElem.textContent = card.name;
|
||||||
|
tarotInterpretationElem.textContent = card.interpretation;
|
||||||
|
|
||||||
|
// Flip the card after a short delay to allow the main content to appear
|
||||||
|
setTimeout(() => {
|
||||||
|
tarotCardContainer.classList.add('flipped');
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const createSideDecorations = () => {
|
||||||
|
const leftContainer = document.querySelector('.left-decor');
|
||||||
|
const rightContainer = document.querySelector('.right-decor');
|
||||||
|
if (!leftContainer || !rightContainer) return;
|
||||||
|
|
||||||
|
const symbols = ['✧', '✦', '☾', '✶', '✵', '✩', '✨'];
|
||||||
|
const symbolCount = 15; // Number of symbols per side
|
||||||
|
|
||||||
|
const createSymbols = (container) => {
|
||||||
|
for (let i = 0; i < symbolCount; i++) {
|
||||||
|
const symbol = document.createElement('span');
|
||||||
|
symbol.classList.add('decor-symbol');
|
||||||
|
symbol.textContent = symbols[Math.floor(Math.random() * symbols.length)];
|
||||||
|
|
||||||
|
// Randomize properties for a more natural look
|
||||||
|
symbol.style.top = `${Math.random() * 90}vh`;
|
||||||
|
symbol.style.left = `${Math.random() * 80}%`;
|
||||||
|
symbol.style.fontSize = `${Math.random() * 20 + 10}px`;
|
||||||
|
symbol.style.animationDelay = `${Math.random() * 20}s`;
|
||||||
|
symbol.style.animationDuration = `${Math.random() * 20 + 15}s`; // Duration between 15s and 35s
|
||||||
|
|
||||||
|
container.appendChild(symbol);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createSymbols(leftContainer);
|
||||||
|
createSymbols(rightContainer);
|
||||||
|
};
|
||||||
|
|
||||||
|
getFortuneBtn.addEventListener('click', fetchFortune);
|
||||||
|
tarotCardContainer.addEventListener('click', () => {
|
||||||
|
tarotCardContainer.classList.toggle('flipped');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial actions on page load
|
||||||
|
fetchFortune();
|
||||||
|
createSideDecorations();
|
||||||
|
});
|
||||||
7
frontend/60sapi/娱乐消遣/随机运势/接口集合.json
Normal file
7
frontend/60sapi/娱乐消遣/随机运势/接口集合.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[
|
||||||
|
"https://60s-cf.viki.moe",
|
||||||
|
"https://60s.viki.moe",
|
||||||
|
"https://60s.b23.run",
|
||||||
|
"https://60s.114128.xyz",
|
||||||
|
"https://60s-cf.114128.xyz"
|
||||||
|
]
|
||||||
10
frontend/60sapi/娱乐消遣/随机运势/返回接口.json
Normal file
10
frontend/60sapi/娱乐消遣/随机运势/返回接口.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841",
|
||||||
|
"data": {
|
||||||
|
"luck_desc": "恋愛運",
|
||||||
|
"luck_rank": 21,
|
||||||
|
"luck_tip": "闪亮的邂逅之日!顺其自然吧",
|
||||||
|
"luck_tip_index": 19
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user