💡 本资源需花费 10 积分 下载 | 新用户注册即送 100 积分,可免费下载!

月

🎭 角色简介

姓名:月

年龄:100岁(还是个鲛人宝宝)

种族:鲛人

外貌:
是偏柔美的清冷长相,眉眼狭长、眼尾带点绯色晕染,唇瓣饱满泛着粉润光泽,鼻梁线条清透精致,皮肤像浸了水的瓷一样细腻泛着柔光。湿软的黑色长发是他最显眼的标志,发丝浓密柔顺,带着天然的卷曲度,垂落时如海藻般贴在颈肩、后背,…

💬 开场白

“`html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Apple风格音乐播放器</title>
<style>
/* 通用样式重置和字体设置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
color: white; /* 设置默认文本颜色为白色 */
}

/* 页面主体样式 – 浅灰色背景 */
body {
padding: 40px;
display: flex; /* 使用flexbox居中播放器 */
justify-content: center;
align-items: center;
min-height: 100vh; /* 确保body至少占满视口高度 */
}

/* 新增:包裹播放器和歌曲列表的容器 */
/* 这个容器现在是垂直方向的Flexbox */
.player-and-list-wrapper {
display: flex;
flex-direction: column; /* 垂直堆叠播放器和列表 */
align-items: center; /* 水平居中 */
gap: 25px; /* 播放器和列表之间的垂直间距 */
position: relative; /* 列表按钮需要相对定位到播放器内部,而非这里 */
max-width: 320px; /* 整体最大宽度由播放器决定 */
/* overflow: hidden; /* 仅在必要时使用,以免裁剪过度 */
}

/* 播放器容器样式 – 固定宽度,并移除阴影 */
.player {
width: 320px; /* 固定宽度,点击列表前后尺寸不变 */
flex-shrink: 0; /* 防止播放器在flex容器中缩小 */
background: rgba(0, 0, 0, 0.15); /* 半透明黑色背景 */
backdrop-filter: blur(20px); /* 背景模糊效果 */
border-radius: 24px;
padding: 25px; /* 稍微缩小内边距 */
border: 1px solid rgba(255, 255, 255, 0.05); /* 替换为内部边框效果 */
color: white;
position: relative; /* 相对定位,用于伪元素和歌曲列表按钮 */
overflow: hidden; /* 隐藏超出部分,用于伪元素和按钮的圆角裁剪 */
}

/* 增强发光效果的伪元素 */
.player::before {
content: '';
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
border-radius: 34px;
background: linear-gradient(45deg,
rgba(255,255,255,0.05) 0%,
rgba(255,255,255,0) 50%);
z-index: -1;
filter: blur(15px);
}

/* 歌曲列表按钮 – 放置在播放器右上角 */
.list-btn {
position: absolute;
top: 20px; /* 距离顶部 */
right: 20px; /* 距离右侧 */
background: none;
border: none;
color: white; /* 纯白色图标 */
font-size: 28px; /* 大小适中 */
cursor: pointer;
transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
line-height: 1;
padding: 0;
width: 28px; /* 稍微缩小 */
height: 28px;
display: flex;
justify-content: center;
align-items: center;
z-index: 10; /* 确保在其他内容之上 */
-webkit-tap-highlight-color: transparent;
}

/* 列表按钮图标样式 */
.list-btn span {
display: block;
width: 20px; /* 稍微缩小 */
height: 2px;
background: white;
position: relative;
box-shadow: 0 5px 0 white, 0 -5px 0 white; /* 稍微缩小间距 */
border-radius: 1px;
}

.list-btn:hover {
transform: scale(1.1);
opacity: 0.9;
}

/* 专辑封面容器样式 – 移除阴影 */
.album-art {
width: 180px; /* 缩小专辑封面尺寸 */
height: 180px; /* 缩小专辑封面尺寸 */
border-radius: 50%;
margin: 0 auto 20px; /* 缩小外边距 */
overflow: hidden;
animation: rotateAlbumArt 15s linear infinite paused;
border: 2px solid rgba(255, 255, 255, 0.1);
flex-shrink: 0;
}

/* 播放状态下专辑封面动画运行 */
.player.playing .album-art {
animation-play-state: running;
}

/* 专辑封面图片样式 */
.album-art img {
width: 100%;
height: 100%;
object-fit: cover;
}

/* 歌曲信息容器样式 */
.song-info {
text-align: center;
margin-bottom: 25px; /* 缩小外边距 */
}

/* 歌曲标题样式 */
.song-title {
font-size: 22px; /* 稍微缩小字体 */
font-weight: 600;
margin-bottom: 6px;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); /* 保持文字阴影,增强可读性 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

/* 艺术家姓名样式 */
.artist {
font-size: 15px; /* 稍微缩小字体 */
color: rgba(255, 255, 255, 0.8);
text-shadow: 0 1px 5px rgba(0, 0, 0, 0.2); /* 保持文字阴影,增强可读性 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

/* 统一滑块的CSS变量定义 */
.slider-base {
-webkit-appearance: none;
width: 100%;
height: 5px; /* 缩小滑块高度 */
background: transparent;
border-radius: 3px;
cursor: pointer;
outline: none;
overflow: hidden;
margin: 0;

/* 定义通用滑块样式变量 */
–fill-color: white;
–track-bg-color: rgba(255, 255, 255, 0.2);
–thumb-size: 12px; /* 缩小滑块圆点大小 */
–thumb-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
–thumb-margin-top: -3.5px; /* 调整垂直居中 */
}

/* 统一滑块轨道样式 */
.slider-base::-webkit-slider-runnable-track {
-webkit-appearance: none;
width: 100%;
height: 5px;
border-radius: 3px;
background: linear-gradient(to right,
var(–fill-color), var(–fill-color)) 0% 0% / var(–current-fill) 100% no-repeat,
var(–track-bg-color) 100% 0% / calc(100% – var(–current-fill)) 100% no-repeat;
transition: background-size 0.1s linear;
}

/* 统一滑块圆点样式 */
.slider-base::-webkit-slider-thumb {
-webkit-appearance: none;
width: var(–thumb-size);
height: var(–thumb-size);
background: white;
border-radius: 50%;
margin-top: var(–thumb-margin-top);
box-shadow: var(–thumb-shadow);
transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* 统一滑块圆点悬停效果 */
.slider-base::-webkit-slider-thumb:hover {
transform: scale(1.1);
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.3);
}

/* 播放进度条滑块样式 – 继承通用滑块样式 */
.progress-slider {
margin-bottom: 20px; /* 缩小外边距 */
–current-fill: 0%;
}

/* 时间信息容器样式 */
.time-info {
display: flex;
justify-content: space-between;
font-size: 11px; /* 缩小字体 */
color: rgba(255, 255, 255, 0.7);
margin-bottom: 25px; /* 缩小外边距 */
}

/* 控件按钮容器样式 */
.controls {
display: flex;
justify-content: center;
align-items: center;
gap: 25px; /* 缩小间距 */
}

/* 上一首/下一首按钮基础样式 */
.control-btn {
background: none;
border: none;
color: rgba(255, 255, 255, 0.7);
font-size: 26px; /* 稍微缩小字体 */
cursor: pointer;
transition: all 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
padding: 5px;
line-height: 1;
-webkit-tap-highlight-color: transparent;
}

/* 上一首/下一首按钮悬停效果 */
.control-btn:hover {
color: white;
transform: scale(1.05);
}

/* 播放/暂停按钮样式 – 与其他按钮UI尺寸一致 */
.play-btn {
font-size: 26px;
padding: 0 5px;
}

/* 音量控制容器样式 */
.volume-control {
display: flex;
align-items: center;
gap: 8px; /* 缩小间距 */
margin-top: 20px; /* 缩小外边距 */
}

/* 音量图标样式 */
.volume-icon {
font-size: 18px; /* 缩小音量图标大小 */
color: rgba(255, 255, 255, 0.7);
line-height: 1;
}

/* 音量调节滑块样式 (input[type="range"]) – 继承通用滑块样式 */
.volume-slider {
–current-fill: 70%;
}

/* 专辑封面旋转动画 */
@keyframes rotateAlbumArt {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

/* — 歌曲列表面板样式 — */

/* 歌曲列表面板 – 垂直出现,只显示两首歌曲高度,无内容形变 */
.song-list-panel {
width: 320px; /* 与播放器宽度一致 */
/* 预估高度:标题(22px+15mb) + 2首歌曲(2*(45px+2*10px padding+4px mb)) + 2*25px (panel padding) = ~225px */
height: 225px; /* 固定高度,确保内部内容不变形 */
flex-shrink: 0; /* 防止列表在Flex容器中收缩 */
background: rgba(255, 255, 255, 0.15); /* 浅灰色半透明背景 */
backdrop-filter: blur(20px); /* 模糊效果 */
border-radius: 24px; /* 匹配播放器圆角 */
border: 1px solid rgba(255, 255, 255, 0.05); /* 替换为内部边框效果 */
padding: 25px; /* 列表面板内部的内边距 */
display: flex;
flex-direction: column;
overflow: hidden; /* 隐藏超出滚动区域的内容 */

/* 隐藏状态:完全透明,不可见,并通过 transform 向下平移 */
opacity: 0;
visibility: hidden;
/* 向下平移自身高度 + 间距,使其初始位置在播放器下方 */
transform: translateY(calc(100% + 25px));

/* 动画过渡:更精细的控制 visibility 和 easing */
/* max-height 也包含在内,但它会从 0 展开到固定 height,
transform 的视觉滑动是主导 */
transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), /* 动画曲线 */
opacity 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
visibility 0s linear 0.5s, /* 隐藏在动画结束时 */
max-height 0.5s cubic-bezier(0.2, 0.8, 0.2, 1); /* 同步 max-height 动画 */
will-change: transform, opacity, max-height; /* 提升动画性能 */

/* 当 max-height 为 0 时,内容会被裁剪。这里是隐藏时的额外控制 */
max-height: 0; /* 默认隐藏时高度为0 */
}

/* 歌曲列表面板激活状态 */
.song-list-panel.active {
opacity: 1;
visibility: visible; /* 立即显示 */
transform: translateY(0); /* 向上滑动到其自然位置 */
max-height: 225px; /* 展开到固定高度 */

transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
opacity 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
visibility 0s linear 0s, /* 立即显示 */
max-height 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* 确保隐藏时内部内容完全折叠 */
/* 由于我们使用固定的 height 和 padding,这些规则是为了防止意外的可见性 */
.song-list-panel:not(.active) h2,
.song-list-panel:not(.active) .song-list-item {
/* 强制隐藏子元素,因为父元素的 overflow:hidden 只能裁剪,不能让内容不可见 */
opacity: 0;
pointer-events: none; /* 禁用点击事件 */
transition: opacity 0.1s; /* 让子元素也淡出 */
}

/* 歌曲列表标题 */
.song-list-panel h2 {
font-size: 22px;
font-weight: 600;
text-align: center;
margin-bottom: 15px;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
flex-shrink: 0;
}

/* 歌曲列表 ul */
.song-list {
list-style: none;
flex-grow: 1;
overflow-y: auto; /* 列表过长时滚动 */
-webkit-overflow-scrolling: touch;
padding-right: 5px;
}
/* 美化滚动条 (仅 Webkit 浏览器) */
.song-list::-webkit-scrollbar {
width: 6px;
}
.song-list::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.05);
border-radius: 3px;
}
.song-list::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 3px;
transition: background-color 0.2s ease;
}
.song-list::-webkit-scrollbar-thumb:hover {
background-color: rgba(255, 255, 255, 0.3);
}

/* 歌曲列表项 */
.song-list-item {
display: flex;
align-items: center;
padding: 10px 12px;
border-bottom: 1px solid rgba(255, 255, 255, 0.08); /* 分隔线透明度降低 */
cursor: pointer;
transition: background-color 0.2s ease, transform 0.1s ease;
border-radius: 8px;
margin-bottom: 4px;
}

.song-list-item:last-child {
border-bottom: none;
}

.song-list-item:hover {
background-color: rgba(255, 255, 255, 0.08);
transform: translateY(-2px);
}

/* 当前播放歌曲的高亮效果 – 移除阴影 */
.song-list-item.playing-now {
background-color: rgba(255, 255, 255, 0.15);
border-color: rgba(255, 255, 255, 0.2);
position: relative;
}

/* 列表项中的专辑封面 – 移除阴影 */
.song-list-item .album-art-sm {
width: 45px;
height: 45px;
border-radius: 50%;
overflow: hidden;
margin-right: 12px;
flex-shrink: 0;
border: 1px solid rgba(255, 255, 255, 0.08);
}

.song-list-item .album-art-sm img {
width: 100%;
height: 100%;
object-fit: cover;
}

/* 列表项中的文本信息 */
.song-list-text {
flex-grow: 1;
min-width: 0;
}

.song-list-text .song-title-sm {
font-size: 15px;
font-weight: 500;
margin-bottom: 2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

/* 列表项的文本内容在隐藏时完全不可见 */
.song-list-panel:not(.active) .song-list-text .song-title-sm,
.song-list-panel:not(.active) .song-list-text .artist-sm {
line-height: 0; /* 确保文字行高也为0 */
height: 0;
margin: 0;
}

.song-list-text .artist-sm {
font-size: 12px;
color: rgba(255, 255, 255, 0.7);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
</head>
<body>
<div class="player-and-list-wrapper">
<!– 歌曲列表面板现在位于播放器上方 –>
<div class="song-list-panel">
<h2>歌曲列表</h2>
<ul class="song-list">
<!– 歌曲列表项将由 JavaScript 动态生成 –>
</ul>
</div>

<div class="player">
<div class="album-art">
<img src="" alt="专辑封面">
</div>

<div class="song-info">
<h1 class="song-title"></h1>
<p class="artist"></p>
</div>

<!– 播放进度条滑块 –>
<input type="range" class="progress-slider slider-base" min="0" max="100" value="0">

<div class="time-info">
<span class="current-time">0:00</span>
<span class="duration">0:00</span>
</div>

<div class="controls">
<button class="control-btn prev-btn">⏮</button>
<button class="control-btn play-btn">▶</button>
<button class="control-btn next-btn">⏭</button>
</div>

<div class="volume-control">
<span class="volume-icon">🔈</span>
<input type="range" class="volume-slider slider-base" min="0" max="100" value="70">
</div>

<!– 歌曲列表按钮 –>
<button class="list-btn"><span></span></button>
</div>
</div>

<!– 音乐来源 –>
<audio id="myAudio"></audio>

<script>
// — DOM 元素获取 —
const playerAndListWrapper = document.querySelector('.player-and-list-wrapper');
const player = document.querySelector('.player');
const albumArtImg = document.querySelector('.album-art img');
const songTitle = document.querySelector('.song-title');
const artistName = document.querySelector('.artist');
const playBtn = document.querySelector('.play-btn');
const prevBtn = document.querySelector('.prev-btn');
const nextBtn = document.querySelector('.next-btn');
const listBtn = document.querySelector('.list-btn'); // 歌曲列表按钮
const progressSlider = document.querySelector('.progress-slider');
const volumeSlider = document.querySelector('.volume-slider');
const currentTimeSpan = document.querySelector('.current-time');
const durationSpan = document.querySelector('.duration');
const myAudio = document.getElementById('myAudio');

const songListPanel = document.querySelector('.song-list-panel'); // 歌曲列表面板
const songListUl = document.querySelector('.song-list');

// — 歌曲数据 (在这里添加/修改歌曲信息) —
const songs = [
{
title: '苏公堤',
artist: '˚˖ 𓂂ꔫ Music ⊹꙳◦',
albumArt: 'https://file.zhuyitai.com/feedback/202511/16/b4d50b883afe5d61c73f2123b77eb979.png',
audioSrc: 'https://files.catbox.moe/o8optg.mp3'
},
{
title: '采茶纪',
artist: '˚˖ 𓂂ꔫ Music ⊹꙳◦',
albumArt: 'https://file.zhuyitai.com/feedback/202511/16/b4d50b883afe5d61c73f2123b77eb979.png',
audioSrc: 'https://files.catbox.moe/qtg3hw.mp3'
},
{
title: '桃花笑',
artist: '˚˖ 𓂂ꔫ Music ⊹꙳◦',
albumArt: 'https://file.zhuyitai.com/feedback/202511/16/b4d50b883afe5d61c73f2123b77eb979.png',
audioSrc: 'https://files.catbox.moe/vifii4.mp3'
},

// 你可以在这里继续添加更多歌曲
// 示例:
// {
// title: '你的新歌曲标题',
// artist: '你的新艺术家',
// albumArt: 'https://example.com/your-new-album-cover.jpg', // 新专辑封面链接
// audioSrc: 'https://example.com/your-new-audio.mp3' // 新音频链接
// },
];

let currentSongIndex = 0; // 当前播放歌曲的索引

// — 函数定义 —

// 格式化时间
function formatTime(seconds) {
const minutes = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${minutes}:${secs < 10 ? '0' : ''}${secs}`;
}

// 加载指定索引的歌曲
function loadSong(index) {
if (index < 0) { // 如果是上一首,且当前是第一首,则跳到最后一首
currentSongIndex = songs.length – 1;
} else if (index >= songs.length) { // 如果是下一首,且当前是最后一首,则跳到第一首
currentSongIndex = 0;
} else {
currentSongIndex = index;
}

const song = songs[currentSongIndex];

albumArtImg.src = song.albumArt;
songTitle.textContent = song.title;
artistName.textContent = song.artist;
myAudio.src = song.audioSrc;

// 重新设置播放器状态
player.classList.remove('playing');
playBtn.textContent = '▶';
progressSlider.value = 0;
progressSlider.style.setProperty('–current-fill', `0%`);
currentTimeSpan.textContent = formatTime(0);

// 更新歌曲列表中的高亮显示
updateSongListHighlight();
}

// 动态生成歌曲列表
function renderSongList() {
songListUl.innerHTML = ''; // 清空现有列表
songs.forEach((song, index) => {
const li = document.createElement('li');
li.classList.add('song-list-item');
if (index === currentSongIndex) {
li.classList.add('playing-now');
}
li.dataset.index = index; // 存储歌曲索引

li.innerHTML = `
<div class="album-art-sm">
<img src="${song.albumArt}" alt="专辑封面">
</div>
<div class="song-list-text">
<div class="song-title-sm">${song.title}</div>
<div class="artist-sm">${song.artist}</div>
</div>
`;
songListUl.appendChild(li);

// 给每个列表项添加点击事件
li.addEventListener('click', () => {
loadSong(index); // 加载点击的歌曲
myAudio.play(); // 播放
player.classList.add('playing');
playBtn.textContent = '⏸';
songListPanel.classList.remove('active'); // 隐藏列表
});
});
}

// 更新歌曲列表中的高亮显示
function updateSongListHighlight() {
document.querySelectorAll('.song-list-item').forEach((item, index) => {
if (index === currentSongIndex) {
item.classList.add('playing-now');
// 确保当前播放的歌曲在列表中可见
setTimeout(() => {
item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}, 0);
} else {
item.classList.remove('playing-now');
}
});
}

// — 事件监听器 —

// 播放/暂停功能
playBtn.addEventListener('click', function() {
if (myAudio.paused) {
myAudio.play();
player.classList.add('playing');
playBtn.textContent = '⏸';
} else {
myAudio.pause();
player.classList.remove('playing');
playBtn.textContent = '▶';
}
});

// 上一首
prevBtn.addEventListener('click', () => {
loadSong(currentSongIndex – 1);
if (!myAudio.paused || player.classList.contains('playing')) { // 如果之前在播放,则继续播放
myAudio.play();
}
});

// 下一首
nextBtn.addEventListener('click', () => {
loadSong(currentSongIndex + 1);
if (!myAudio.paused || player.classList.contains('playing')) {
myAudio.play();
}
});

// 歌曲列表按钮 – 现在也负责关闭列表
listBtn.addEventListener('click', () => {
if (songListPanel.classList.contains('active')) {
// 如果列表已显示,则关闭它
songListPanel.classList.remove('active');
} else {
// 如果列表未显示,则显示它并重新渲染
renderSongList();
songListPanel.classList.add('active');
}
});

// 音乐加载完成后,更新总时长和初始化音量滑块
myAudio.addEventListener('loadedmetadata', function() {
durationSpan.textContent = formatTime(myAudio.duration);
if (myAudio.volume === 1) {
myAudio.volume = 0.7;
volumeSlider.value = 70;
}
volumeSlider.style.setProperty('–current-fill', `${volumeSlider.value}%`);
});

// 音乐播放时,更新当前时间和进度条
myAudio.addEventListener('timeupdate', function() {
const progressPercent = (myAudio.currentTime / myAudio.duration) * 100;
progressSlider.value = progressPercent;
progressSlider.style.setProperty('–current-fill', `${progressPercent}%`);
currentTimeSpan.textContent = formatTime(myAudio.currentTime);
});

// 进度条滑动时,改变音乐播放位置
progressSlider.addEventListener('input', function() {
const seekTime = (this.value / 100) * myAudio.duration;
myAudio.currentTime = seekTime;
this.style.setProperty('–current-fill', `${this.value}%`);
currentTimeSpan.textContent = formatTime(seekTime);
});

// 音乐播放结束时
myAudio.addEventListener('ended', function() {
if (currentSongIndex < songs.length – 1) {
loadSong(currentSongIndex + 1);
myAudio.play();
player.classList.add('playing');
playBtn.textContent = '⏸';
} else {
loadSong(0);
player.classList.remove('playing');
playBtn.textContent = '▶';
}
});

// 音量滑块滑动时,改变音乐音量
volumeSlider.addEventListener('input', function() {
myAudio.volume = this.value / 100;
this.style.setProperty('–current-fill', `${this.value}%`);
});

// — 初始化 —
loadSong(currentSongIndex);
volumeSlider.value = myAudio.volume * 100;
volumeSlider.style.setProperty('–current-fill', `${volumeSlider.value}%`);
</script>
</body>
</html>
“`

“`html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>人,鱼的眼泪是珍珠,鱼哭给你</title>
<style>
/* 引入外部字体,增添古风韵味 */
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&display=swap');

/* — 变量定义 — */
:root {
–font-family-main: 'Noto Serif SC', serif;
–color-background-start: #fff0f5; /* 樱花粉 */
–color-background-end: #ffe4e1; /* 薄雾玫瑰 */
–color-text-primary: #8b5f65; /* 玫瑰棕 */
–color-text-secondary: #a07c82; /* 灰粉色 */
–color-accent: #ffb6c1; /* 浅粉色 */
–color-accent-deep: #db7093; /* 玫瑰红 */
–color-border: rgba(219, 112, 147, 0.3);
–color-card-bg: rgba(255, 255, 255, 0.8);
–shadow-light: rgba(139, 95, 101, 0.1);
–shadow-medium: rgba(139, 95, 101, 0.2);
}

/* — 基础样式重置 — */
.pearl-tear-container * {
box-sizing: border-box;
margin: 0;
padding: 0;
}

/* — 主容器与背景 — */
.pearl-tear-container {
font-family: var(–font-family-main);
color: var(–color-text-primary);
width: 100%;
max-width: 800px;
margin: 40px auto;
position: relative;
overflow: hidden;
background: linear-gradient(160deg, var(–color-background-start), var(–color-background-end));
border-radius: 20px;
box-shadow: 0 20px 50px var(–shadow-medium);
padding: 20px;
}

/* — 漂浮物装饰:花瓣与气泡 — */
.floating-elements {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 0;
}

.floater {
position: absolute;
animation: float-around 25s infinite ease-in-out;
bottom: -150px;
opacity: 0;
}

@keyframes float-around {
0% {
transform: translateY(0) translateX(0) rotate(0deg) scale(1);
opacity: 0;
}
10%, 90% {
opacity: 0.7;
}
100% {
transform: translateY(-105vh) translateX(var(–x-end, 0px)) rotate(var(–r-end, 0deg)) scale(0.8);
opacity: 0;
}
}

/* 随机化每个漂浮物的属性 */
.floater.petal { content: '🌸'; font-size: 20px; }
.floater.bubble { background-color: rgba(255, 182, 193, 0.2); border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.3); }

.floater:nth-child(1) { width: 20px; height: 20px; left: 10%; animation-duration: 22s; –x-end: 20px; –r-end: 90deg; }
.floater:nth-child(2) { width: 35px; height: 35px; left: 25%; animation-duration: 30s; animation-delay: 3s; –x-end: -30px; –r-end: 180deg; }
.floater:nth-child(3) { font-size: 15px; left: 40%; animation-duration: 18s; animation-delay: 7s; –x-end: 10px; –r-end: -45deg; }
.floater:nth-child(4) { width: 50px; height: 50px; left: 55%; animation-duration: 40s; animation-delay: 0s; –x-end: -40px; }
.floater:nth-child(5) { font-size: 25px; left: 70%; animation-duration: 25s; animation-delay: 5s; –x-end: 25px; –r-end: 270deg; }
.floater:nth-child(6) { width: 40px; height: 40px; left: 85%; animation-duration: 35s; animation-delay: 8s; –x-end: -15px; }
.floater:nth-child(7) { font-size: 18px; left: 5%; animation-duration: 28s; animation-delay: 2s; –x-end: 5px; –r-end: 60deg; }

/* — 内容区域 — */
.content-wrapper {
position: relative;
z-index: 1;
background: var(–color-card-bg);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-radius: 15px;
padding: 40px;
box-shadow: 0 5px 25px var(–shadow-light);
border: 1px solid rgba(255, 255, 255, 0.5);
}

/* — 标题与作者 — */
.header {
text-align: center;
margin-bottom: 40px;
}

.main-title {
font-size: 2.4em;
font-weight: 700;
letter-spacing: 3px;
margin-bottom: 10px;
text-shadow: 1px 1px 5px var(–shadow-light);
color: var(–color-text-primary);
}

.author-name {
font-size: 1.2em;
color: var(–color-text-secondary);
font-style: italic;
}

/* — 内容版块通用样式 — */
.content-section {
margin-bottom: 40px;
}
.content-section:last-child {
margin-bottom: 0;
}

.section-title {
display: inline-block;
font-size: 1.6em;
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 10px;
position: relative;
}

/* 标题下方的装饰线 */
.section-title::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 80%;
height: 1px;
background: linear-gradient(to right, transparent, var(–color-accent), transparent);
}

.section-content {
line-height: 1.8;
font-size: 1.05em;
}

/* — 角色信息版块特定样式 — */
.character-info-grid {
display: flex;
gap: 30px;
align-items: center;
flex-wrap: wrap;
justify-content: center;
}

.char-avatar-wrapper {
flex-shrink: 0;
}

.char-avatar {
width: 160px;
height: 160px;
border-radius: 50%;
background-image: url('https://file.zhuyitai.com/feedback/202511/16/876ee4e30c31d33a6489814edafdb22d.jpg');
background-size: cover;
background-position: center;
border: 5px solid white;
box-shadow: 0 0 20px var(–shadow-medium);
transition: transform 0.4s ease, box-shadow 0.4s ease;
}

.char-avatar:hover {
transform: scale(1.05);
box-shadow: 0 0 30px var(–color-accent);
}

.char-details {
display: flex;
flex-direction: column;
gap: 15px;
flex-grow: 1;
min-width: 250px;
}

.char-detail-item {
display: flex;
align-items: baseline;
background: rgba(255, 240, 245, 0.5);
padding: 8px 12px;
border-radius: 8px;
border-left: 3px solid var(–color-accent);
}

.char-detail-item strong {
width: 80px;
flex-shrink: 0;
color: var(–color-text-primary);
font-weight: 600;
}

.char-detail-item span {
color: var(–color-text-secondary);
}

/* — 开场白列表 — */
.opening-list {
display: flex;
flex-direction: column;
gap: 15px;
}

.opening-item {
background-color: rgba(255, 255, 255, 0.7);
border: 1px solid var(–color-border);
border-radius: 12px;
padding: 20px 25px;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
position: relative;
overflow: hidden;
}

.opening-item:hover {
transform: translateY(-5px);
border-color: var(–color-accent-deep);
box-shadow: 0 8px 20px var(–shadow-light);
background-color: rgba(255, 255, 255, 0.9);
}

/* 点击反馈效果 */
.opening-item .ripple {
position: absolute;
border-radius: 50%;
background: var(–color-accent);
transform: scale(0);
animation: ripple-effect 0.6s linear;
pointer-events: none;
}

@keyframes ripple-effect {
to {
transform: scale(4);
opacity: 0;
}
}

.opening-item h4 {
font-size: 1.25em;
font-weight: 600;
margin-bottom: 8px;
color: var(–color-text-primary);
}

.opening-item p {
font-size: 1em;
color: var(–color-text-secondary);
margin: 0;
}

.loading-placeholder {
color: var(–color-text-secondary);
font-style: italic;
text-align: center;
padding: 20px;
}

</style>
</head>
<body>
<div class="pearl-tear-container">
<!– 漂浮的装饰元素 –>
<div class="floating-elements">
<div class="floater bubble"></div><div class="floater petal">🌸</div><div class="floater bubble"></div>
<div class="floater petal">🌸</div><div class="floater bubble"></div><div class="floater petal">🌸</div>
<div class="floater bubble"></div>
</div>

<div class="content-wrapper">
<!– 标题区域 –>
<header class="header">
<h1 class="main-title">人,鱼的眼泪是珍珠,鱼哭给你</h1>
<p class="author-name">—— 月</p>
</header>

<main>
<!– 角色信息版块 –>
<section class="content-section">
<h2 class="section-title">绯色之尾</h2>
<div class="section-content character-info-grid">
<div class="char-avatar-wrapper">
<div class="char-avatar" title="被月神眷顾的月泽鲛"></div>
</div>
<div class="char-details">
<div class="char-detail-item"><strong>姓名:</strong> <span>月</span></div>
<div class="char-detail-item"><strong>种族:</strong> <span>鲛人(月泽鲛)</span></div>
<div class="char-detail-item"><strong>年龄:</strong> <span>一百岁(幼崽期)</span></div>
<div class="char-detail-item"><strong>特征:</strong> <span>绯粉色鱼尾,额间月印</span></div>
<div class="char-detail-item"><strong>喜好:</strong> <span>亮晶晶的东西、糖葫芦</span></div>
</div>
</div>
</section>

<!– 动态开场白列表版块 –>
<section class="content-section">
<h2 class="section-title">汐声之引</h2>
<div class="section-content opening-list" id="opening-list-container">
<!– 开场白将由JavaScript动态加载于此 –>
<div class="loading-placeholder">正在聆听远方的歌声……</div>
</div>
</section>
</main>
</div>
</div>

<script>
// — 交互逻辑 —

// 点击反馈效果
function createRipple(event) {
const button = event.currentTarget;
const circle = document.createElement("span");
const diameter = Math.max(button.clientWidth, button.clientHeight);
const radius = diameter / 2;

// 修正 clientX/Y 在不同浏览器下的兼容性
const rect = button.getBoundingClientRect();
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX – rect.left – radius}px`;
circle.style.top = `${event.clientY – rect.top – radius}px`;
circle.classList.add("ripple");

const ripple = button.getElementsByClassName("ripple")[0];
if (ripple) {
ripple.remove();
}
button.appendChild(circle);
}

// 开场白列表加载与跳转功能
async function loadOpenings() {
const container = document.getElementById('opening-list-container');
if (!container) return;

if (typeof getChatMessages !== 'function' || typeof setChatMessage !== 'function') {
container.innerHTML = '<p class="loading-placeholder">未能连接到时空之海,无法获取故事开端。</p>';
return;
}

try {
const messages = await getChatMessages("0", { include_swipe: true });

if (!messages || messages.length === 0 || !messages[0].swipes || messages[0].swipes.length <= 1) {
container.innerHTML = '<p class="loading-placeholder">大海一片寂静,暂无新的故事。</p>';
return;
}

container.innerHTML = '';
const swipes = messages[0].swipes;

for (let i = 1; i < swipes.length; i++) {
const content = swipes[i];
let title = `未名之卷 ${i}`;
let description = "轻触开启一段未知的缘分。";

const titleMatch = content.match(/<!–s*title:s*(.*?)s*–>/);
if (titleMatch) title = titleMatch[1].trim();

const descMatch = content.match(/<!–s*desc:s*(.*?)(?=s*–>)–>/s);
if (descMatch) description = descMatch[1].trim();

const item = document.createElement('div');
item.className = 'opening-item';
item.innerHTML = `<h4>${title}</h4><p>${description}</p>`;
item.title = `点击开启故事:${title}`;

item.addEventListener('click', (event) => {
createRipple(event);
switchToOpening(i, item);
});

container.appendChild(item);
}

} catch (error) {
console.error('加载开场白失败:', error);
container.innerHTML = '<p class="loading-placeholder" style="color: #c0392b;">海潮涌动,讯息中断,请稍后再试。</p>';
}
}

async function switchToOpening(swipeId, element) {
if (element) {
element.style.pointerEvents = 'none';
element.style.opacity = '0.6';
}

// 延迟一小段时间让涟漪效果可见
setTimeout(async () => {
try {
const messages = await getChatMessages("0", { include_swipe: true });
if (messages && messages[0].swipes && messages[0].swipes[swipeId]) {
await setChatMessage(messages[0].swipes[swipeId], 0, {
swipe_id: swipeId,
refresh: 'display_and_render_current'
});
} else {
throw new Error(`无法找到ID为 ${swipeId} 的故事线。`);
}
} catch (error) {
console.error('切换开场白失败:', error);
alert(`切换失败: ${error.message}`);
if(element){
element.style.pointerEvents = 'auto';
element.style.opacity = '1';
}
}
}, 400); // 延迟时间略小于涟漪动画时间
}

window.addEventListener('load', loadOpenings);

</script>
</body>
</html>
“`

角色卡

西拉斯

2025-12-31 17:30:50

角色卡

你们这个综艺正经吗?

2025-12-31 17:31:01

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索