<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>梦幻3D进度条 作者:是江枫呀</title>
<style>
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: #fff;
overflow: hidden;
position: relative;
}
@keyframes gradientBG {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* 代码雨样式 */
.rain {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 0;
}
.rain div {
position: absolute;
top: -20px;
opacity: 0;
animation: rainFall linear infinite;
animation-fill-mode: forwards;
color: #0f0;
font-weight: bold;
white-space: nowrap;
}
@keyframes rainFall {
0% {
top: -20px;
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
top: 100vh;
opacity: 0;
}
}
.data-container {
background-color: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
padding: 30px;
width: 80%;
max-width: 600px;
z-index: 1;
position: relative;
}
h1 {
text-align: center;
color: #fff;
margin-bottom: 30px;
font-weight: 600;
text-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
}
.data-item {
margin-bottom: 25px;
position: relative;
}
.data-label {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.data-label span:first-child {
font-weight: 500;
color: #fff;
flex-grow: 1;
}
.data-label span:last-child {
font-weight: bold;
color: #fff;
margin-left: 10px;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
.custom-button {
padding: 3px 8px;
background-color: rgba(255, 255, 255, 0.2);
color: #fff;
border: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 5px;
font-size: 12px;
cursor: pointer;
transition: all 0.3s ease-in-out;
margin-left: 10px;
}
.custom-button:hover {
background-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}
.data-bar-container {
height: 30px;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 15px;
overflow: hidden;
position: relative;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2) inset;
}
.data-bar {
height: 100%;
width: 0%;
border-radius: 15px;
position: relative;
transition: width 1.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 15px;
box-sizing: border-box;
transform-style: preserve-3d;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.data-bar::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
border-radius: 17px;
background: linear-gradient(45deg, #fff, #f0f0f0);
z-index: -1;
transform: scale(1, 1.1);
opacity: 0.3;
}
.data-bar::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
90deg,
rgba(255, 255, 255, 0.2) 0%,
rgba(255, 255, 255, 0) 50%,
rgba(255, 255, 255, 0.2) 100%
);
opacity: 0.5;
pointer-events: none;
}
.data-value {
color: #fff;
font-size: 14px;
font-weight: bold;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
z-index: 1;
}
/* 不同数据条的渐变色 */
#tasks-bar {
background: linear-gradient(90deg, #a78bfa, #8b5cf6, #6366f1);
}
#progress-bar {
background: linear-gradient(90deg, #60a5fa, #3b82f6, #2563eb);
}
#satisfaction-bar {
background: linear-gradient(90deg, #f5b7b1, #ec9a9a, #ee6c4d);
}
#completion-bar {
background: linear-gradient(90deg, #a3e635, #84cc16, #65a30d);
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
justify-content: center;
align-items: center;
z-index: 100;
}
.modal-content {
background-color: rgba(255, 255, 255, 0.95);
padding: 20px;
border-radius: 10px;
width: 300px;
text-align: center;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.modal-input {
padding: 10px;
margin: 10px 0;
width: 100%;
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
}
.modal-buttons {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 15px;
}
.modal-button {
padding: 8px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
}
.confirm-button {
background-color: #7b68ee;
color: white;
}
.cancel-button {
background-color: #ddd;
color: #555;
}
.settings-button {
position: absolute;
top: 20px;
left: 20px;
padding: 8px 15px;
background-color: rgba(255, 255, 255, 0.2);
color: #fff;
border: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 5px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease-in-out;
z-index: 10;
}
.settings-button:hover {
background-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 0 15px rgba(255, 255, 255, 0.5);
}
.settings-panel {
display: none;
position: absolute;
top: 60px;
left: 20px;
background-color: rgba(255, 255, 255, 0.95);
border-radius: 10px;
padding: 15px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
z-index: 10;
width: 200px;
}
.settings-panel h3 {
margin-top: 0;
color: #333;
}
.settings-panel label {
display: block;
margin: 10px 0 5px;
color: #555;
}
.settings-panel select {
width: 100%;
padding: 8px;
border-radius: 5px;
border: 1px solid #ddd;
}
.settings-panel button {
margin-top: 15px;
padding: 8px 15px;
background-color: #7b68ee;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="rain" id="rain"></div>
<div class="data-container">
<h1>梦幻3D数据展示</h1>
<div class="data-item" data-key="tasks">
<div class="data-label">
<span>完成任务</span>
<button class="custom-button" data-key="tasks">设置</button>
<span id="tasks-value">35%</span>
</div>
<div class="data-bar-container">
<div class="data-bar" id="tasks-bar">
<span class="data-value">35%</span>
</div>
</div>
</div>
<div class="data-item" data-key="progress">
<div class="data-label">
<span>进度</span>
<button class="custom-button" data-key="progress">设置</button>
<span id="progress-value">65%</span>
</div>
<div class="data-bar-container">
<div class="data-bar" id="progress-bar">
<span class="data-value">65%</span>
</div>
</div>
</div>
<div class="data-item" data-key="satisfaction">
<div class="data-label">
<span>满意度</span>
<button class="custom-button" data-key="satisfaction">设置</button>
<span id="satisfaction-value">85%</span>
</div>
<div class="data-bar-container">
<div class="data-bar" id="satisfaction-bar">
<span class="data-value">85%</span>
</div>
</div>
</div>
<div class="data-item" data-key="completion">
<div class="data-label">
<span>完成度</span>
<button class="custom-button" data-key="completion">设置</button>
<span id="completion-value">45%</span>
</div>
<div class="data-bar-container">
<div class="data-bar" id="completion-bar">
<span class="data-value">45%</span>
</div>
</div>
</div>
</div>
<button class="settings-button" id="settings-button">设置</button>
<div class="settings-panel" id="settings-panel">
<h3>动画设置</h3>
<label for="animation-speed">动画速度</label>
<select id="animation-speed">
<option value="fast">快速</option>
<option value="normal" selected>正常</option>
<option value="slow">缓慢</option>
</select>
<label for="code-rain">代码雨</label>
<select id="code-rain">
<option value="on" selected>开启</option>
<option value="off">关闭</option>
</select>
<button id="save-settings">保存设置</button>
</div>
<div class="modal" id="settings-modal">
<div class="modal-content">
<h2 id="modal-title">设置百分比</h2>
<input type="number" id="modal-input" class="modal-input" min="0" max="100">
<div class="modal-buttons">
<button class="modal-button cancel-button" id="cancel-button">取消</button>
<button class="modal-button confirm-button" id="confirm-button">确认</button>
</div>
</div>
</div>
<script>
// 代码雨效果
function createRain() {
const rain = document.getElementById('rain');
const characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}[]()<>+-*/=!';
const numberOfDrops = 100;
for (let i = 0; i < numberOfDrops; i++) {
const drop = document.createElement('div');
const length = Math.floor(Math.random() * 1) + 1;
let text = '';
for (let j = 0; j < length; j++) {
text += characters.charAt(Math.floor(Math.random() * characters.length));
}
drop.textContent = text;
drop.style.left = `${Math.random() * 100}%`;
drop.style.animationDuration = `${0.5 + Math.random() * 10}s`;
drop.style.animationDelay = `${Math.random() * 2}s`;
rain.appendChild(drop);
}
}
// 初始化代码雨
createRain();
// 获取DOM元素
const dataItems = document.querySelectorAll('.data-item');
const settingsModal = document.getElementById('settings-modal');
const modalTitle = document.getElementById('modal-title');
const modalInput = document.getElementById('modal-input');
const confirmButton = document.getElementById('confirm-button');
const cancelButton = document.getElementById('cancel-button');
const settingsButton = document.getElementById('settings-button');
const settingsPanel = document.getElementById('settings-panel');
const animationSpeedSelect = document.getElementById('animation-speed');
const codeRainSelect = document.getElementById('code-rain');
const saveSettingsButton = document.getElementById('save-settings');
const rainElement = document.getElementById('rain');
let activeKey = null;
let animationSpeed = 'normal';
let codeRainEnabled = true;
// 初始化 - 加载保存的数据
function initializeDataBars() {
dataItems.forEach(item => {
const key = item.dataset.key;
const savedValue = localStorage.getItem(key);
if (savedValue) {
const bar = item.querySelector('.data-bar');
const valueElement = bar.querySelector('.data-value');
const labelValueElement = item.querySelector('.data-label span:last-child');
bar.style.width = `${savedValue}%`;
valueElement.textContent = `${savedValue}%`;
labelValueElement.textContent = `${savedValue}%`;
}
});
// 加载动画速度设置
const savedAnimationSpeed = localStorage.getItem('animationSpeed');
if (savedAnimationSpeed) {
animationSpeed = savedAnimationSpeed;
animationSpeedSelect.value = savedAnimationSpeed;
}
// 加载代码雨设置
const savedCodeRain = localStorage.getItem('codeRain');
if (savedCodeRain) {
codeRainEnabled = savedCodeRain === 'on';
codeRainSelect.value = savedCodeRain;
if (!codeRainEnabled) {
rainElement.style.display = 'none';
}
}
}
// 更新数据条
function updateDataBar(key, value) {
const item = document.querySelector(`.data-item[data-key="${key}"]`);
const bar = item.querySelector('.data-bar');
const valueElement = bar.querySelector('.data-value');
const labelValueElement = item.querySelector('.data-label span:last-child');
// 动画效果
bar.style.transition = 'none';
bar.style.width = '0%';
valueElement.textContent = '0%';
labelValueElement.textContent = '0%';
setTimeout(() => {
bar.style.transition = `width ${getAnimationDuration()}s cubic-bezier(0.175, 0.885, 0.32, 1.275)`;
bar.style.width = `${value}%`;
valueElement.textContent = `${value}%`;
labelValueElement.textContent = `${value}%`;
}, 10);
// 保存数据到本地存储
localStorage.setItem(key, value);
}
function getAnimationDuration() {
switch (animationSpeed) {
case 'fast':
return 0.8;
case 'slow':
return 1.6;
default:
return 1.2;
}
}
// 显示设置弹窗
function showSettingsModal(key) {
activeKey = key;
const item = document.querySelector(`.data-item[data-key="${key}"]`);
const labelValueElement = item.querySelector('.data-label span:last-child');
const currentValue = parseInt(labelValueElement.textContent);
modalInput.value = currentValue;
modalTitle.textContent = `设置 ${item.querySelector('.data-label span:first-child').textContent} 百分比`;
settingsModal.style.display = 'flex';
}
// 隐藏设置弹窗并保存数据
function hideSettingsModal() {
settingsModal.style.display = 'none';
if (activeKey) {
const value = parseInt(modalInput.value);
if (value >= 0 && value <= 100) {
updateDataBar(activeKey, value);
} else {
alert('请输入0到100之间的值');
}
activeKey = null;
}
}
// 显示/隐藏设置面板
settingsButton.addEventListener('click', () => {
if (settingsPanel.style.display === 'block') {
settingsPanel.style.display = 'none';
} else {
settingsPanel.style.display = 'block';
}
});
// 保存设置
saveSettingsButton.addEventListener('click', () => {
animationSpeed = animationSpeedSelect.value;
codeRainEnabled = codeRainSelect.value === 'on';
localStorage.setItem('animationSpeed', animationSpeed);
localStorage.setItem('codeRain', codeRainEnabled ? 'on' : 'off');
if (codeRainEnabled) {
rainElement.style.display = 'block';
} else {
rainElement.style.display = 'none';
}
settingsPanel.style.display = 'none';
// 重新加载所有数据条以应用新的动画速度
dataItems.forEach(item => {
const key = item.dataset.key;
const savedValue = localStorage.getItem(key);
if (savedValue) {
updateDataBar(key, savedValue);
}
});
});
// 页面加载完成后执行
window.addEventListener('load', () => {
// 初始化数据条
initializeDataBars();
// 设置按钮点击事件
const customButtons = document.querySelectorAll('.custom-button');
customButtons.forEach(button => {
button.addEventListener('click', () => {
showSettingsModal(button.dataset.key);
});
});
// 确认按钮点击事件
confirmButton.addEventListener('click', hideSettingsModal);
// 取消按钮点击事件
cancelButton.addEventListener('click', () => {
settingsModal.style.display = 'none';
activeKey = null;
});
// 点击模态框外部关闭模态框
settingsModal.addEventListener('click', (e) => {
if (e.target === settingsModal) {
settingsModal.style.display = 'none';
activeKey = null;
}
});
});
// 页面刷新后重新加载动画
window.addEventListener('load', () => {
setTimeout(() => {
dataItems.forEach(item => {
const key = item.dataset.key;
const bar = item.querySelector('.data-bar');
const value = localStorage.getItem(key) || parseFloat(bar.style.width);
// 重置动画
bar.style.transition = 'none';
bar.style.width = '0%';
bar.querySelector('.data-value').textContent = '0%';
item.querySelector('.data-label span:last-child').textContent = '0%';
// 重新开始动画
setTimeout(() => {
bar.style.transition = `${getAnimationDuration()}s cubic-bezier(0.175, 0.885, 0.32, 1.275)`;
bar.style.width = `${value}%`;
bar.querySelector('.data-value').textContent = `${value}%`;
item.querySelector('.data-label span:last-child').textContent = `${value}%`;
}, 10);
});
}, 100);
});
</script>
</body>
</html>
index.html