<!DOCTYPE html>
<html lang="zh-CN" class="light-theme">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>漫画风格工具箱 - 多功能工具集合</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lucide-icons@0.309.0/dist/umd/lucide-icons.min.css">
<style>
/* 导入字体 */
@import url('https://fonts.googleapis.com/css2?family=Bangers&family=ZCOOL+KuaiLe&display=swap');
/* 主题变量 - 浅色模式 */
:root {
--color-background: #ffffff;
--color-background-secondary: #f9f9f9;
--color-background-tertiary: #f0f0f0;
--color-foreground: #000000;
--color-foreground-muted: #333333;
--color-foreground-subtle: #666666;
--color-surface: #f0f0f0;
--color-surface-hover: #e0e0e0;
--color-surface-active: #d0d0d0;
--color-border: #000000;
--color-accent: #000000;
--color-accent-hover: #333333;
--color-accent-muted: #666666;
--color-header-bg: #ffffff;
--color-header-text: #000000;
--color-tool-header-bg: #000000;
--color-tool-header-text: #ffffff;
--color-card-bg: #ffffff;
--color-card-shadow: #000000;
--color-input-bg: #ffffff;
--color-input-border: #000000;
--color-button-bg: #000000;
--color-button-text: #ffffff;
--color-button-hover: #333333;
--color-progress-bg: #f0f0f0;
--color-progress-fill: #000000;
--color-success-bg: #f0f0f0;
--color-success-text: #000000;
--color-error-bg: #fff0f0;
--color-error-text: #ff0000;
--color-highlight: #ffff00;
--color-highlight-alt: #ff9900;
--color-favorite: #ff0000;
--shadow-comic: 5px 5px 0px var(--color-card-shadow);
--border-comic: 3px solid var(--color-border);
--border-comic-thin: 2px solid var(--color-border);
--border-comic-dashed: 3px dashed var(--color-border);
--font-comic: 'Bangers', 'ZCOOL KuaiLe', cursive, sans-serif;
--font-sans: 'Arial', sans-serif;
--font-mono: 'Courier New', monospace;
--pattern-dots: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23000000' fill-opacity='0.1' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E");
--pattern-lines: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23000000' fill-opacity='0.1' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 5v1H5z'/%3E%3Cpath d='M6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
--pattern-zigzag: url("data:image/svg+xml,%3Csvg width='40' height='12' viewBox='0 0 40 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 6.172L6.172 0h5.656L0 11.828V6.172zm40 5.656L28.172 0h5.656L40 6.172v5.656zM6.172 12l12-12h3.656l12 12h-5.656L20 3.828 11.828 12H6.172zm12 0L20 10.172 21.828 12h-3.656z' fill='%23000000' fill-opacity='0.1' fill-rule='evenodd'/%3E%3C/svg%3E");
--pattern-bg: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23000000' fill-opacity='0.03' fill-rule='evenodd'/%3E%3C/svg%3E");
}
/* 深色模式变量 */
.dark-theme {
--color-background: #121212;
--color-background-secondary: #1e1e1e;
--color-background-tertiary: #2a2a2a;
--color-foreground: #ffffff;
--color-foreground-muted: #cccccc;
--color-foreground-subtle: #999999;
--color-surface: #2a2a2a;
--color-surface-hover: #3a3a3a;
--color-surface-active: #4a4a4a;
--color-border: #ffffff;
--color-accent: #ffffff;
--color-accent-hover: #cccccc;
--color-accent-muted: #999999;
--color-header-bg: #1a1a1a;
--color-header-text: #ffffff;
--color-tool-header-bg: #ffffff;
--color-tool-header-text: #000000;
--color-card-bg: #1e1e1e;
--color-card-shadow: #ffffff;
--color-input-bg: #2a2a2a;
--color-input-border: #ffffff;
--color-button-bg: #ffffff;
--color-button-text: #000000;
--color-button-hover: #cccccc;
--color-progress-bg: #2a2a2a;
--color-progress-fill: #ffffff;
--color-success-bg: #2a2a2a;
--color-success-text: #ffffff;
--color-error-bg: #3a1a1a;
--color-error-text: #ff6666;
--color-highlight: #ffff00;
--color-highlight-alt: #ff9900;
--color-favorite: #ff5555;
--pattern-dots: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.1' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E");
--pattern-lines: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.1' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 5v1H5z'/%3E%3Cpath d='M6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
--pattern-zigzag: url("data:image/svg+xml,%3Csvg width='40' height='12' viewBox='0 0 40 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 6.172L6.172 0h5.656L0 11.828V6.172zm40 5.656L28.172 0h5.656L40 6.172v5.656zM6.172 12l12-12h3.656l12 12h-5.656L20 3.828 11.828 12H6.172zm12 0L20 10.172 21.828 12h-3.656z' fill='%23ffffff' fill-opacity='0.1' fill-rule='evenodd'/%3E%3C/svg%3E");
--pattern-bg: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23ffffff' fill-opacity='0.03' fill-rule='evenodd'/%3E%3C/svg%3E");
}
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-sans);
background-color: var(--color-background);
background-image: var(--pattern-bg);
color: var(--color-foreground);
line-height: 1.5;
min-height: 100vh;
transition: background-color 0.3s, color 0.3s;
}
button, input, select, textarea {
font-family: inherit;
font-size: inherit;
color: inherit;
}
button {
cursor: pointer;
background: none;
border: none;
}
a {
color: inherit;
text-decoration: none;
}
/* 漫画风格元素 */
.comic-title {
font-family: var(--font-comic);
text-transform: uppercase;
letter-spacing: 1px;
transform: rotate(-2deg);
display: inline-block;
position: relative;
z-index: 1;
}
.comic-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 10px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.comic-box {
border: var(--border-comic);
box-shadow: var(--shadow-comic);
position: relative;
background-color: var(--color-card-bg);
transform: rotate(0.5deg);
}
.comic-box-alt {
border: var(--border-comic);
box-shadow: var(--shadow-comic);
position: relative;
background-color: var(--color-card-bg);
transform: rotate(-0.5deg);
}
.comic-button {
font-family: var(--font-comic);
text-transform: uppercase;
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 8px 16px;
position: relative;
box-shadow: 3px 3px 0 var(--color-card-shadow);
transform: rotate(-1deg);
transition: all 0.1s;
}
.comic-button:hover {
transform: rotate(0deg) translate(-2px, -2px);
box-shadow: 5px 5px 0 var(--color-card-shadow);
}
.comic-button:active {
transform: rotate(0deg) translate(2px, 2px);
box-shadow: 1px 1px 0 var(--color-card-shadow);
}
.comic-input {
border: var(--border-comic-thin);
padding: 8px 12px;
background-color: var(--color-input-bg);
box-shadow: 3px 3px 0 rgba(var(--color-card-shadow), 0.2);
}
.comic-input:focus {
outline: none;
box-shadow: 3px 3px 0 rgba(var(--color-card-shadow), 0.5);
}
.comic-badge {
font-family: var(--font-comic);
background-color: var(--color-accent);
color: var(--color-background);
padding: 2px 8px;
transform: rotate(-3deg);
display: inline-block;
}
.comic-divider {
height: 3px;
background-image: var(--pattern-lines);
margin: 20px 0;
}
.comic-speech-bubble {
position: relative;
background-color: var(--color-card-bg);
border: var(--border-comic-thin);
padding: 15px;
border-radius: 30px;
box-shadow: 3px 3px 0 rgba(var(--color-card-shadow), 0.2);
}
.comic-speech-bubble::after {
content: '';
position: absolute;
bottom: -20px;
left: 30px;
width: 30px;
height: 30px;
background-color: var(--color-card-bg);
border-right: var(--border-comic-thin);
border-bottom: var(--border-comic-thin);
transform: rotate(45deg) skew(10deg, 10deg);
z-index: -1;
}
/* 布局 */
.app-container {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container {
width: 100%;
max-width: 1280px;
margin: 0 auto;
padding: 0 20px;
}
.main-content {
display: flex;
flex-direction: column;
gap: 24px;
padding-top: 24px;
padding-bottom: 24px;
}
@media (min-width: 768px) {
.main-content {
flex-direction: row;
}
}
/* 头部 */
.header {
position: sticky;
top: 0;
z-index: 10;
background-color: var(--color-header-bg);
border-bottom: var(--border-comic);
padding: 10px 0;
transition: background-color 0.3s;
}
.header-content {
display: flex;
align-items: center;
justify-content: space-between;
}
.logo-container {
display: flex;
align-items: center;
gap: 12px;
}
.logo-icon {
width: 50px;
height: 50px;
background-color: var(--color-accent);
border: var(--border-comic-thin);
display: flex;
align-items: center;
justify-content: center;
transform: rotate(-5deg);
}
.logo-icon svg {
width: 30px;
height: 30px;
color: var(--color-background);
}
.logo-title {
font-family: var(--font-comic);
font-size: 24px;
transform: rotate(-2deg);
}
.logo-subtitle {
font-size: 12px;
color: var(--color-foreground-muted);
transform: rotate(-2deg);
}
.header-actions {
display: none;
}
@media (min-width: 768px) {
.header-actions {
display: flex;
align-items: center;
gap: 8px;
}
}
.search-container {
position: relative;
width: 250px;
}
.search-icon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--color-foreground-muted);
width: 16px;
height: 16px;
}
.search-input {
width: 100%;
border: var(--border-comic-thin);
border-radius: 20px;
padding: 6px 16px 6px 32px;
background-color: var(--color-input-bg);
}
.icon-button {
width: 40px;
height: 40px;
border: var(--border-comic-thin);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.icon-button:hover {
transform: translate(-1px, -1px);
box-shadow: 3px 3px 0 var(--color-card-shadow);
}
.icon-button svg {
width: 20px;
height: 20px;
}
.menu-button {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.menu-button:hover {
transform: translate(-1px, -1px);
box-shadow: 3px 3px 0 var(--color-card-shadow);
}
.menu-button svg {
width: 24px;
height: 24px;
}
@media (min-width: 768px) {
.menu-button {
display: none;
}
}
/* 主题切换按钮 */
.theme-toggle {
position: relative;
width: 40px;
height: 40px;
border: var(--border-comic-thin);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
box-shadow: 2px 2px 0 var(--color-card-shadow);
overflow: hidden;
}
.theme-toggle:hover {
transform: translate(-1px, -1px);
box-shadow: 3px 3px 0 var(--color-card-shadow);
}
.theme-toggle svg {
width: 20px;
height: 20px;
position: absolute;
transition: transform 0.3s ease;
}
.theme-toggle .sun-icon {
transform: translateY(0);
}
.theme-toggle .moon-icon {
transform: translateY(40px);
}
.dark-theme .theme-toggle .sun-icon {
transform: translateY(-40px);
}
.dark-theme .theme-toggle .moon-icon {
transform: translateY(0);
}
/* 下拉菜单 */
.dropdown {
position: relative;
}
.dropdown-content {
position: absolute;
top: 100%;
right: 0;
margin-top: 8px;
background-color: var(--color-card-bg);
border: var(--border-comic);
box-shadow: var(--shadow-comic);
min-width: 160px;
z-index: 20;
display: none;
}
.dropdown.active .dropdown-content {
display: block;
}
.dropdown-item {
display: flex;
align-items: center;
padding: 8px 12px;
border-bottom: 1px solid var(--color-border);
}
.dropdown-item:last-child {
border-bottom: none;
}
.dropdown-item:hover {
background-color: var(--color-surface-hover);
}
.dropdown-item svg {
width: 16px;
height: 16px;
margin-right: 8px;
}
/* 侧边栏 */
.sidebar {
display: none;
flex-shrink: 0;
transition: all 0.3s ease-in-out;
overflow: hidden;
border: var(--border-comic);
background-color: var(--color-card-bg);
box-shadow: var(--shadow-comic);
transform: rotate(-0.5deg);
}
.sidebar.open {
display: block;
}
@media (min-width: 768px) {
.sidebar {
display: block;
width: 250px;
}
}
.sidebar-content {
display: flex;
flex-direction: column;
gap: 24px;
padding: 20px;
}
.main-nav,
.category-nav {
display: flex;
flex-direction: column;
gap: 4px;
}
.category-title {
font-family: var(--font-comic);
font-size: 18px;
margin-bottom: 8px;
text-transform: uppercase;
position: relative;
display: inline-block;
}
.category-title::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
background-color: var(--color-highlight);
z-index: -1;
}
.nav-button {
display: flex;
align-items: center;
padding: 8px 12px;
border: 1px solid transparent;
border-radius: 4px;
transition: all 0.2s;
text-align: left;
width: 100%;
font-weight: 500;
}
.nav-button:hover {
border-color: var(--color-border);
background-color: var(--color-surface-hover);
transform: translate(-2px, -2px);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.nav-button.active {
border: 1px solid var(--color-border);
background-color: var(--color-surface);
transform: translate(-2px, -2px);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.nav-button svg {
width: 16px;
height: 16px;
margin-right: 8px;
}
.sidebar-footer {
color: var(--color-foreground-muted);
font-size: 12px;
border-top: 1px dashed var(--color-border);
padding-top: 16px;
}
.footer-links {
display: flex;
gap: 16px;
margin-top: 8px;
}
.footer-links a {
text-decoration: underline;
}
.footer-links a:hover {
color: var(--color-foreground);
}
/* 主内容 */
.main {
flex: 1;
display: flex;
flex-direction: column;
gap: 24px;
}
.breadcrumb {
font-size: 14px;
color: var(--color-foreground-muted);
margin-bottom: 16px;
font-style: italic;
}
/* 页面容器 */
.page-container {
display: none;
}
.page-container.active {
display: block;
}
/* 首页样式 */
.hero-section {
position: relative;
padding: 60px 0;
overflow: hidden;
border: var(--border-comic);
background-color: var(--color-card-bg);
box-shadow: var(--shadow-comic);
margin-bottom: 40px;
}
.hero-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: var(--pattern-dots);
opacity: 0.5;
z-index: 0;
}
.hero-content {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 0 20px;
}
.hero-title {
font-family: var(--font-comic);
font-size: 48px;
margin-bottom: 16px;
text-transform: uppercase;
position: relative;
display: inline-block;
}
.hero-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 10px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.hero-subtitle {
font-size: 20px;
margin-bottom: 32px;
max-width: 600px;
}
.hero-buttons {
display: flex;
gap: 16px;
flex-wrap: wrap;
justify-content: center;
}
.hero-button {
font-family: var(--font-comic);
font-size: 18px;
padding: 12px 24px;
background-color: var(--color-button-bg);
color: var(--color-button-text);
border: var(--border-comic-thin);
box-shadow: 4px 4px 0 var(--color-card-shadow);
transform: rotate(-1deg);
transition: all 0.2s;
}
.hero-button:hover {
transform: rotate(0deg) translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.hero-button.secondary {
background-color: var(--color-card-bg);
color: var(--color-foreground);
transform: rotate(1deg);
}
.hero-button.secondary:hover {
transform: rotate(0deg) translate(-2px, -2px);
}
.hero-decoration {
position: absolute;
font-family: var(--font-comic);
font-size: 24px;
color: var(--color-accent);
transform: rotate(-15deg);
z-index: 2;
}
.hero-decoration.top-left {
top: 20px;
left: 40px;
}
.hero-decoration.bottom-right {
bottom: 20px;
right: 40px;
}
.hero-decoration::before {
content: '★';
margin-right: 8px;
}
.hero-decoration::after {
content: '★';
margin-left: 8px;
}
/* 特色工具部分 */
.featured-tools {
margin-bottom: 40px;
}
.section-title-container {
display: flex;
align-items: center;
margin-bottom: 24px;
}
.section-title {
font-family: var(--font-comic);
font-size: 32px;
text-transform: uppercase;
position: relative;
display: inline-block;
margin-right: 16px;
}
.section-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 8px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.section-line {
flex: 1;
height: 3px;
background-image: var(--pattern-lines);
}
.tools-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.tool-card {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 24px;
transition: all 0.2s;
cursor: pointer;
position: relative;
box-shadow: 4px 4px 0 var(--color-card-shadow);
}
.tool-card:hover {
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.tool-card.active {
background-color: var(--color-background-secondary);
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.tool-card-icon {
width: 50px;
height: 50px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
background-color: var(--color-background-tertiary);
}
.tool-card-icon svg {
width: 30px;
height: 30px;
}
.tool-card-title {
font-family: var(--font-comic);
font-size: 20px;
font-weight: 700;
margin-bottom: 8px;
}
.tool-card-description {
font-size: 14px;
color: var(--color-foreground-muted);
margin-bottom: 16px;
}
.tool-card-button {
font-size: 14px;
text-decoration: underline;
font-weight: 500;
color: var(--color-accent);
}
/* 收藏按钮 */
.favorite-button {
position: absolute;
top: 10px;
right: 10px;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
border: 1px solid var(--color-border);
box-shadow: 2px 2px 0 var(--color-card-shadow);
transition: all 0.2s;
z-index: 2;
}
.favorite-button:hover {
transform: scale(1.1);
}
.favorite-button svg {
width: 16px;
height: 16px;
color: var(--color-foreground-muted);
transition: all 0.2s;
}
.favorite-button.active svg {
color: var(--color-favorite);
fill: var(--color-favorite);
}
/* 分类部分 */
.categories-section {
margin-bottom: 40px;
}
.categories-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 24px;
}
.category-card {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 20px;
text-align: center;
transition: all 0.2s;
cursor: pointer;
box-shadow: 4px 4px 0 var(--color-card-shadow);
}
.category-card:hover {
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.category-card-icon {
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 16px;
background-color: var(--color-background-tertiary);
}
.category-card-icon svg {
width: 30px;
height: 30px;
}
.category-card-title {
font-family: var(--font-comic);
font-size: 18px;
font-weight: 700;
margin-bottom: 8px;
}
.category-card-count {
font-size: 14px;
color: var(--color-foreground-muted);
}
/* 统计部分 */
.stats-section {
margin-bottom: 40px;
}
.stats-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 24px;
}
.stat-card {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 24px;
text-align: center;
box-shadow: 4px 4px 0 var(--color-card-shadow);
position: relative;
overflow: hidden;
}
.stat-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: var(--pattern-dots);
opacity: 0.1;
z-index: 0;
}
.stat-value {
font-family: var(--font-comic);
font-size: 36px;
font-weight: 700;
margin-bottom: 8px;
position: relative;
z-index: 1;
}
.stat-label {
font-size: 16px;
color: var(--color-foreground-muted);
position: relative;
z-index: 1;
}
/* 评价部分 */
.testimonials-section {
margin-bottom: 40px;
}
.testimonials-container {
display: grid;
grid-template-columns: 1fr;
gap: 24px;
}
@media (min-width: 768px) {
.testimonials-container {
grid-template-columns: repeat(2, 1fr);
}
}
.testimonial-card {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 24px;
box-shadow: 4px 4px 0 var(--color-card-shadow);
position: relative;
}
.testimonial-content {
font-style: italic;
margin-bottom: 16px;
position: relative;
padding-left: 24px;
}
.testimonial-content::before {
content: '"';
position: absolute;
left: 0;
top: 0;
font-size: 48px;
line-height: 1;
font-family: var(--font-comic);
color: var(--color-accent-muted);
}
.testimonial-author {
display: flex;
align-items: center;
gap: 12px;
}
.testimonial-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: var(--color-background-tertiary);
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--color-border);
}
.testimonial-avatar svg {
width: 20px;
height: 20px;
}
.testimonial-info {
flex: 1;
}
.testimonial-name {
font-weight: 700;
}
.testimonial-role {
font-size: 14px;
color: var(--color-foreground-muted);
}
/* 底部区域 */
.bottom-sections {
display: grid;
grid-template-columns: 1fr;
gap: 24px;
}
@media (min-width: 768px) {
.bottom-sections {
grid-template-columns: 1fr 1fr;
}
}
.info-section {
border: var(--border-comic);
background-color: var(--color-card-bg);
box-shadow: var(--shadow-comic);
transform: rotate(-0.5deg);
}
.section-header {
padding: 16px 24px;
border-bottom: var(--border-comic-thin);
background-color: var(--color-background-secondary);
}
.section-content {
padding: 24px;
}
.tool-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 12px;
}
.tool-list-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px;
border: 1px solid var(--color-border);
background-color: var(--color-card-bg);
transition: all 0.2s;
}
.tool-list-item:hover {
background-color: var(--color-background-secondary);
transform: translate(-2px, -2px);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.tool-indicator {
width: 8px;
height: 8px;
background-color: var(--color-accent);
border-radius: 50%;
margin-right: 12px;
}
.tool-meta {
display: flex;
align-items: center;
gap: 8px;
}
.tool-date {
font-size: 12px;
color: var(--color-foreground-subtle);
}
.tool-tag {
font-size: 10px;
background-color: var(--color-accent);
color: var(--color-background);
padding: 2px 8px;
text-transform: uppercase;
transform: rotate(-2deg);
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 24px;
}
.stat-card {
border: 2px solid var(--color-border);
background-color: var(--color-card-bg);
padding: 16px;
box-shadow: 3px 3px 0 var(--color-card-shadow);
}
.stat-value {
font-size: 32px;
font-weight: 700;
margin-bottom: 4px;
font-family: var(--font-comic);
}
.stat-label {
font-size: 14px;
color: var(--color-foreground-muted);
}
.progress-stats {
display: flex;
flex-direction: column;
gap: 16px;
}
.progress-item {
display: flex;
flex-direction: column;
gap: 4px;
}
.progress-header {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 14px;
margin-bottom: 4px;
}
.progress-bar {
width: 100%;
height: 10px;
background-color: var(--color-progress-bg);
border: 1px solid var(--color-border);
overflow: hidden;
}
.progress-fill {
height: 100%;
background-color: var(--color-progress-fill);
transition: width 0.3s ease;
}
.progress-fill-green {
background-color: var(--color-progress-fill);
background-image: var(--pattern-dots);
}
.progress-fill-yellow {
background-color: var(--color-progress-fill);
background-image: var(--pattern-zigzag);
}
/* 热门工具页面 */
.popular-tools-page {
padding: 20px 0;
}
.popular-tools-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
margin-bottom: 40px;
}
/* 收藏工具页面 */
.favorite-tools-page {
padding: 20px 0;
}
.favorite-tools-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
margin-bottom: 40px;
}
.no-favorites {
text-align: center;
padding: 40px;
border: var(--border-comic-dashed);
background-color: var(--color-card-bg);
}
.no-favorites-icon {
font-size: 48px;
margin-bottom: 16px;
}
.no-favorites-title {
font-family: var(--font-comic);
font-size: 24px;
margin-bottom: 8px;
}
.no-favorites-text {
color: var(--color-foreground-muted);
margin-bottom: 16px;
}
/* 最近使用页面 */
.recent-tools-page {
padding: 20px 0;
}
.recent-tools-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 16px;
margin-bottom: 40px;
}
.recent-tool-item {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 16px;
display: flex;
align-items: center;
gap: 16px;
box-shadow: 4px 4px 0 var(--color-card-shadow);
transition: all 0.2s;
cursor: pointer;
}
.recent-tool-item:hover {
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.recent-tool-icon {
width: 40px;
height: 40px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-background-tertiary);
flex-shrink: 0;
}
.recent-tool-icon svg {
width: 24px;
height: 24px;
}
.recent-tool-info {
flex: 1;
}
.recent-tool-title {
font-weight: 700;
margin-bottom: 4px;
}
.recent-tool-date {
font-size: 12px;
color: var(--color-foreground-muted);
}
.recent-tool-actions {
display: flex;
gap: 8px;
}
.recent-tool-button {
width: 32px;
height: 32px;
border: 1px solid var(--color-border);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
transition: all 0.2s;
}
.recent-tool-button:hover {
background-color: var(--color-surface-hover);
}
.recent-tool-button svg {
width: 16px;
height: 16px;
}
.recent-tool-button.favorite.active svg {
color: var(--color-favorite);
fill: var(--color-favorite);
}
.no-history {
text-align: center;
padding: 40px;
border: var(--border-comic-dashed);
background-color: var(--color-card-bg);
}
.no-history-icon {
font-size: 48px;
margin-bottom: 16px;
}
.no-history-title {
font-family: var(--font-comic);
font-size: 24px;
margin-bottom: 8px;
}
.no-history-text {
color: var(--color-foreground-muted);
margin-bottom: 16px;
}
/* 分类页面 */
.category-page {
padding: 20px 0;
}
.category-header {
margin-bottom: 32px;
}
.category-header-title {
font-family: var(--font-comic);
font-size: 36px;
margin-bottom: 8px;
position: relative;
display: inline-block;
}
.category-header-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 10px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.category-header-description {
font-size: 18px;
color: var(--color-foreground-muted);
max-width: 800px;
}
/* 工具详情页面 */
.tool-detail-page {
padding: 20px 0;
}
.tool-detail-header {
margin-bottom: 32px;
}
.tool-detail-title {
font-family: var(--font-comic);
font-size: 36px;
margin-bottom: 8px;
position: relative;
display: inline-block;
}
.tool-detail-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 10px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.tool-detail-description {
font-size: 18px;
color: var(--color-foreground-muted);
max-width: 800px;
margin-bottom: 24px;
}
.tool-detail-actions {
display: flex;
gap: 16px;
margin-bottom: 32px;
}
.tool-detail-button {
font-family: var(--font-comic);
padding: 8px 16px;
background-color: var(--color-button-bg);
color: var(--color-button-text);
border: var(--border-comic-thin);
box-shadow: 3px 3px 0 var(--color-card-shadow);
transition: all 0.2s;
display: flex;
align-items: center;
gap: 8px;
}
.tool-detail-button:hover {
transform: translate(-2px, -2px);
box-shadow: 5px 5px 0 var(--color-card-shadow);
}
.tool-detail-button.secondary {
background-color: var(--color-card-bg);
color: var(--color-foreground);
}
.tool-detail-button.favorite.active {
background-color: var(--color-favorite);
color: white;
}
.tool-detail-button.favorite.active svg {
fill: white;
}
.tool-detail-content {
border: var(--border-comic);
background-color: var(--color-card-bg);
padding: 24px;
box-shadow: var(--shadow-comic);
}
/* 通知 */
.notification {
position: fixed;
bottom: 20px;
right: 20px;
padding: 12px 16px;
background-color: var(--color-card-bg);
border: var(--border-comic-thin);
box-shadow: var(--shadow-comic);
display: flex;
align-items: center;
gap: 12px;
z-index: 100;
transform: translateY(150%);
transition: transform 0.3s ease;
}
.notification.show {
transform: translateY(0);
}
.notification-icon {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}
.notification-content {
flex: 1;
}
.notification-title {
font-weight: 700;
margin-bottom: 4px;
}
.notification-message {
font-size: 14px;
color: var(--color-foreground-muted);
}
.notification-close {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
/* 页脚 */
.footer {
background-color: var(--color-background-secondary);
border-top: var(--border-comic);
padding: 40px 0;
margin-top: 40px;
}
.footer-content {
display: grid;
grid-template-columns: 1fr;
gap: 32px;
}
@media (min-width: 768px) {
.footer-content {
grid-template-columns: 2fr 1fr 1fr;
}
}
.footer-logo {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.footer-logo-icon {
width: 40px;
height: 40px;
background-color: var(--color-accent);
border: var(--border-comic-thin);
display: flex;
align-items: center;
justify-content: center;
transform: rotate(-5deg);
}
.footer-logo-icon svg {
width: 24px;
height: 24px;
color: var(--color-background);
}
.footer-logo-text {
font-family: var(--font-comic);
font-size: 20px;
}
.footer-description {
margin-bottom: 16px;
color: var(--color-foreground-muted);
}
.footer-social {
display: flex;
gap: 12px;
}
.footer-social-link {
width: 36px;
height: 36px;
border: var(--border-comic-thin);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
transition: all 0.2s;
}
.footer-social-link:hover {
transform: translateY(-3px);
box-shadow: 0 3px 0 var(--color-card-shadow);
}
.footer-social-link svg {
width: 18px;
height: 18px;
}
.footer-links-title {
font-family: var(--font-comic);
font-size: 18px;
margin-bottom: 16px;
position: relative;
display: inline-block;
}
.footer-links-title::after {
content: '';
position: absolute;
bottom: -3px;
left: 0;
width: 100%;
height: 3px;
background-color: var(--color-highlight);
z-index: -1;
}
.footer-links-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 8px;
}
.footer-link {
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s;
}
.footer-link:hover {
transform: translateX(5px);
color: var(--color-accent);
}
.footer-link svg {
width: 16px;
height: 16px;
}
.footer-bottom {
margin-top: 40px;
padding-top: 20px;
border-top: 1px dashed var(--color-border);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 12px;
}
@media (min-width: 768px) {
.footer-bottom {
flex-direction: row;
justify-content: space-between;
text-align: left;
}
}
.footer-copyright {
color: var(--color-foreground-muted);
font-size: 14px;
}
.footer-bottom-links {
display: flex;
gap: 16px;
}
.footer-bottom-link {
font-size: 14px;
color: var(--color-foreground-muted);
transition: all 0.2s;
}
.footer-bottom-link:hover {
color: var(--color-foreground);
text-decoration: underline;
}
/* 漫画风格装饰 */
.comic-dots {
background-image: var(--pattern-dots);
}
.comic-lines {
background-image: var(--pattern-lines);
}
.comic-zigzag {
background-image: var(--pattern-zigzag);
}
.comic-burst {
position: relative;
}
.comic-burst::before {
content: '';
position: absolute;
top: -10px;
right: -10px;
width: 60px;
height: 60px;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M50 0 L60 40 L100 50 L60 60 L50 100 L40 60 L0 50 L40 40 Z' fill='%23ffff00' stroke='%23000000' stroke-width='3'/%3E%3C/svg%3E");
background-size: contain;
background-repeat: no-repeat;
transform: rotate(15deg);
z-index: 1;
}
.comic-burst-text {
position: absolute;
top: 5px;
right: 5px;
font-family: var(--font-comic);
font-size: 12px;
transform: rotate(15deg);
z-index: 2;
}
/* 动画效果 */
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
.shake {
animation: shake 0.5s;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.bounce {
animation: bounce 0.5s;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.spin {
animation: spin 1s linear infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(-15deg); }
50% { transform: translateY(-10px) rotate(-12deg); }
}
.float {
animation: float 3s ease-in-out infinite;
}
/* 速度线效果 */
.speed-lines {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
z-index: 0;
opacity: 0.1;
}
.speed-line {
position: absolute;
height: 100%;
width: 1px;
background-color: var(--color-accent);
transform: skewX(-20deg);
}
.speed-line:nth-child(1) { left: 10%; }
.speed-line:nth-child(2) { left: 20%; }
.speed-line:nth-child(3) { left: 30%; }
.speed-line:nth-child(4) { left: 40%; }
.speed-line:nth-child(5) { left: 50%; }
.speed-line:nth-child(6) { left: 60%; }
.speed-line:nth-child(7) { left: 70%; }
.speed-line:nth-child(8) { left: 80%; }
.speed-line:nth-child(9) { left: 90%; }
/* 页面过渡动画 */
.page-transition {
transition: opacity 0.3s ease, transform 0.3s ease;
}
.page-transition.fade-out {
opacity: 0;
transform: translateY(10px);
}
.page-transition.fade-in {
opacity: 1;
transform: translateY(0);
}
</style>
<div class="app-container">
<!-- 顶部导航栏 -->
<header class="header">
<div class="container header-content">
<div class="logo-container">
<div class="logo-icon">
<i data-lucide="zap"></i>
</div>
<div>
<h1 class="logo-title comic-title">漫画风工具箱</h1>
<p class="logo-subtitle">多功能工具集合</p>
</div>
</div>
<div class="header-actions">
<div class="search-container">
<i data-lucide="search" class="search-icon"></i>
<input type="text" placeholder="搜索工具..." class="search-input comic-input" id="search-input">
</div>
<button class="theme-toggle" id="theme-toggle" aria-label="切换主题">
<i data-lucide="sun" class="sun-icon"></i>
<i data-lucide="moon" class="moon-icon"></i>
</button>
<div class="dropdown">
<button class="icon-button dropdown-trigger">
<i data-lucide="settings"></i>
</button>
<div class="dropdown-content">
<a href="#" class="dropdown-item">
<i data-lucide="info"></i> 关于我们
</a>
<a href="#" class="dropdown-item">
<i data-lucide="settings"></i> 设置
</a>
<a href="#" class="dropdown-item" id="clear-data">
<i data-lucide="trash-2"></i> 清除数据
</a>
</div>
</div>
</div>
<button class="menu-button" id="menu-toggle">
<i data-lucide="menu"></i>
</button>
</div>
</header>
<div class="container main-content">
<!-- 左侧边栏 -->
<aside class="sidebar" id="sidebar">
<div class="sidebar-content">
<!-- 主导航 -->
<nav class="main-nav">
<button class="nav-button" data-page="home-page">
<i data-lucide="home"></i> 首页
</button>
<button class="nav-button" data-page="popular-tools-page">
<i data-lucide="star"></i> 热门工具
</button>
<button class="nav-button" data-page="favorite-tools-page">
<i data-lucide="heart"></i> 收藏工具
</button>
<button class="nav-button" data-page="recent-tools-page">
<i data-lucide="clock"></i> 最近使用
</button>
</nav>
<!-- 工具分类 -->
<div class="category-nav">
<h3 class="category-title">工具分类</h3>
<div class="category-buttons">
<button class="nav-button" data-page="category-page" data-category="image">
<i data-lucide="image"></i> 图片工具
</button>
<button class="nav-button" data-page="category-page" data-category="text">
<i data-lucide="file-text"></i> 文本工具
</button>
<button class="nav-button" data-page="category-page" data-category="video">
<i data-lucide="film"></i> 视频工具
</button>
<button class="nav-button" data-page="category-page" data-category="audio">
<i data-lucide="music"></i> 音频工具
</button>
<button class="nav-button" data-page="category-page" data-category="dev">
<i data-lucide="code"></i> 开发工具
</button>
<button class="nav-button" data-page="category-page" data-category="utility">
<i data-lucide="tool"></i> 实用工具
</button>
</div>
</div>
<!-- 页脚 -->
<div class="sidebar-footer">
<p>© 漫画风工具箱 2025</p>
<div class="footer-links">
<a href="#">提交工具</a>
<a href="#">关于我们</a>
</div>
</div>
</div>
</aside>
<!-- 主内容区 -->
<main class="main">
<!-- 面包屑导航 -->
<div class="breadcrumb" id="breadcrumb">
首页
</div>
<!-- 首页 -->
<div id="home-page" class="page-container active page-transition">
<!-- 英雄区域 -->
<section class="hero-section">
<div class="hero-background"></div>
<div class="speed-lines">
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
</div>
<div class="hero-decoration top-left float">超级工具</div>
<div class="hero-decoration bottom-right float">一站式解决</div>
<div class="hero-content">
<h1 class="hero-title">漫画风工具箱</h1>
<p class="hero-subtitle">一站式在线工具集合,提供100+种实用工具,满足您的各种需求。无需安装,随时随地使用!</p>
<div class="hero-buttons">
<button class="hero-button" id="explore-tools">
<i data-lucide="search"></i> 探索工具
</button>
<button class="hero-button secondary" id="popular-tools">
<i data-lucide="star"></i> 热门工具
</button>
</div>
</div>
</section>
<!-- 特色工具 -->
<section class="featured-tools">
<div class="section-title-container">
<h2 class="section-title">特色工具</h2>
<div class="section-line"></div>
</div>
<div class="tools-grid" id="featured-tools-grid">
<!-- 工具卡片将通过JavaScript动态加载 -->
</div>
</section>
<!-- 工具分类 -->
<section class="categories-section">
<div class="section-title-container">
<h2 class="section-title">工具分类</h2>
<div class="section-line"></div>
</div>
<div class="categories-grid">
<div class="category-card" data-category="image">
<div class="category-card-icon">
<i data-lucide="image"></i>
</div>
<h3 class="category-card-title">图片工具</h3>
<p class="category-card-count">15+ 工具</p>
</div>
<div class="category-card" data-category="text">
<div class="category-card-icon">
<i data-lucide="file-text"></i>
</div>
<h3 class="category-card-title">文本工具</h3>
<p class="category-card-count">12+ 工具</p>
</div>
<div class="category-card" data-category="video">
<div class="category-card-icon">
<i data-lucide="film"></i>
</div>
<h3 class="category-card-title">视频工具</h3>
<p class="category-card-count">8+ 工具</p>
</div>
<div class="category-card" data-category="audio">
<div class="category-card-icon">
<i data-lucide="music"></i>
</div>
<h3 class="category-card-title">音频工具</h3>
<p class="category-card-count">10+ 工具</p>
</div>
<div class="category-card" data-category="dev">
<div class="category-card-icon">
<i data-lucide="code"></i>
</div>
<h3 class="category-card-title">开发工具</h3>
<p class="category-card-count">20+ 工具</p>
</div>
<div class="category-card" data-category="utility">
<div class="category-card-icon">
<i data-lucide="tool"></i>
</div>
<h3 class="category-card-title">实用工具</h3>
<p class="category-card-count">25+ 工具</p>
</div>
</div>
</section>
<!-- 统计数据 -->
<section class="stats-section">
<div class="section-title-container">
<h2 class="section-title">统计数据</h2>
<div class="section-line"></div>
</div>
<div class="stats-container">
<div class="stat-card">
<div class="stat-value">100+</div>
<div class="stat-label">可用工具</div>
</div>
<div class="stat-card">
<div class="stat-value">10K+</div>
<div class="stat-label">每日用户</div>
</div>
<div class="stat-card">
<div class="stat-value">500K+</div>
<div class="stat-label">每月转换</div>
</div>
<div class="stat-card">
<div class="stat-value">98%</div>
<div class="stat-label">用户满意度</div>
</div>
</div>
</section>
<!-- 用户评价 -->
<section class="testimonials-section">
<div class="section-title-container">
<h2 class="section-title">用户评价</h2>
<div class="section-line"></div>
</div>
<div class="testimonials-container">
<div class="testimonial-card">
<div class="testimonial-content">
这个工具箱太棒了!我经常需要转换图片格式,这里的工具简单易用,而且完全免费。黑白漫画风格的界面也很有特色,让人眼前一亮。
</div>
<div class="testimonial-author">
<div class="testimonial-avatar">
<i data-lucide="user"></i>
</div>
<div class="testimonial-info">
<div class="testimonial-name">张小明</div>
<div class="testimonial-role">设计师</div>
</div>
</div>
</div>
<div class="testimonial-card">
<div class="testimonial-content">
作为一名开发者,我经常需要格式化JSON数据。这个工具箱的JSON格式化工具非常好用,而且还有很多其他实用工具。深色模式也很贴心!
</div>
<div class="testimonial-author">
<div class="testimonial-avatar">
<i data-lucide="user"></i>
</div>
<div class="testimonial-info">
<div class="testimonial-name">李程序</div>
<div class="testimonial-role">前端开发者</div>
</div>
</div>
</div>
<div class="testimonial-card">
<div class="testimonial-content">
密码生成器和二维码生成器是我最常用的两个工具。界面简洁明了,操作也很简单。最重要的是不需要安装任何软件,直接在浏览器中就能使用。
</div>
<div class="testimonial-author">
<div class="testimonial-avatar">
<i data-lucide="user"></i>
</div>
<div class="testimonial-info">
<div class="testimonial-name">王安全</div>
<div class="testimonial-role">IT管理员</div>
</div>
</div>
</div>
<div class="testimonial-card">
<div class="testimonial-content">
我喜欢这个工具箱的漫画风格设计,非常有趣!而且工具种类齐全,几乎涵盖了我所有的需求。单位转换工具对我的工作特别有帮助。
</div>
<div class="testimonial-author">
<div class="testimonial-avatar">
<i data-lucide="user"></i>
</div>
<div class="testimonial-info">
<div class="testimonial-name">赵工程</div>
<div class="testimonial-role">工程师</div>
</div>
</div>
</div>
</div>
</section>
<!-- 最新工具 -->
<div class="bottom-sections">
<section class="info-section">
<div class="section-header">
<h2 class="section-title">最新工具</h2>
</div>
<div class="section-content">
<ul class="tool-list">
<li class="tool-list-item">
<div class="tool-indicator"></div>
<span>二维码生成器</span>
<div class="tool-meta">
<span class="tool-date">2025-05-10</span>
<span class="tool-tag">新功能</span>
</div>
</li>
<li class="tool-list-item">
<div class="tool-indicator"></div>
<span>密码生成器</span>
<div class="tool-meta">
<span class="tool-date">2025-05-08</span>
<span class="tool-tag">新功能</span>
</div>
</li>
<li class="tool-list-item">
<div class="tool-indicator"></div>
<span>颜色选择器</span>
<div class="tool-meta">
<span class="tool-date">2025-05-05</span>
<span class="tool-tag">更新</span>
</div>
</li>
<li class="tool-list-item">
<div class="tool-indicator"></div>
<span>单位转换工具</span>
<div class="tool-meta">
<span class="tool-date">2025-05-01</span>
<span class="tool-tag">新功能</span>
</div>
</li>
</ul>
</div>
</section>
<!-- 统计数据 -->
<section class="info-section">
<div class="section-header">
<h2 class="section-title">统计数据</h2>
</div>
<div class="section-content">
<div class="stats-grid">
<div class="stat-card">
<h3 class="stat-value">100+</h3>
<p class="stat-label">可用工具</p>
</div>
<div class="stat-card">
<h3 class="stat-value">10K+</h3>
<p class="stat-label">每日用户</p>
</div>
</div>
<div class="progress-stats">
<div class="progress-item">
<div class="progress-header">
<span class="progress-label">免费工具</span>
<span class="progress-value">85%</span>
</div>
<div class="progress-bar">
<div class="progress-fill" style="width: 85%;"></div>
</div>
</div>
<div class="progress-item">
<div class="progress-header">
<span class="progress-label">每日转换</span>
<span class="progress-value">50,000+</span>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-green" style="width: 70%;"></div>
</div>
</div>
<div class="progress-item">
<div class="progress-header">
<span class="progress-label">用户满意度</span>
<span class="progress-value">98%</span>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-yellow" style="width: 98%;"></div>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
<!-- 热门工具页面 -->
<div id="popular-tools-page" class="page-container page-transition">
<div class="section-title-container">
<h2 class="section-title">热门工具</h2>
<div class="section-line"></div>
</div>
<p class="section-description">这些是我们用户最常使用的工具,快来试试吧!</p>
<div class="popular-tools-grid" id="popular-tools-grid">
<!-- 工具卡片将通过JavaScript动态加载 -->
</div>
</div>
<!-- 收藏工具页面 -->
<div id="favorite-tools-page" class="page-container page-transition">
<div class="section-title-container">
<h2 class="section-title">收藏工具</h2>
<div class="section-line"></div>
</div>
<p class="section-description">这里是您收藏的工具,方便您快速访问。</p>
<div class="favorite-tools-grid" id="favorite-tools-grid">
<!-- 收藏的工具卡片将通过JavaScript动态加载 -->
</div>
</div>
<!-- 最近使用页面 -->
<div id="recent-tools-page" class="page-container page-transition">
<div class="section-title-container">
<h2 class="section-title">最近使用</h2>
<div class="section-line"></div>
</div>
<p class="section-description">这里记录了您最近使用过的工具,方便您快速访问。</p>
<div class="recent-tools-list" id="recent-tools-list">
<!-- 最近使用的工具将通过JavaScript动态加载 -->
</div>
</div>
<!-- 分类页面 -->
<div id="category-page" class="page-container page-transition">
<div class="category-header">
<h2 class="category-header-title" id="category-title">图片工具</h2>
<p class="category-header-description" id="category-description">各种图片处理工具,满足您的图片编辑需求。</p>
</div>
<div class="tools-grid" id="category-tools-grid">
<!-- 工具卡片将通过JavaScript动态加载 -->
</div>
</div>
<!-- 工具详情页面 -->
<div id="tool-detail-page" class="page-container page-transition">
<div class="tool-detail-header">
<h2 class="tool-detail-title" id="tool-detail-title">图片格式转换</h2>
<p class="tool-detail-description" id="tool-detail-description">支持多种格式互转,快速简便,保持图片质量。</p>
<div class="tool-detail-actions">
<button class="tool-detail-button favorite" id="detail-favorite-button">
<i data-lucide="heart"></i> 收藏工具
</button>
<button class="tool-detail-button secondary">
<i data-lucide="share"></i> 分享工具
</button>
</div>
</div>
<div class="tool-detail-content" id="tool-detail-content">
<!-- 工具内容将通过JavaScript动态加载 -->
</div>
</div>
</main>
</div>
<!-- 通知 -->
<div class="notification" id="notification">
<div class="notification-icon">
<i data-lucide="info"></i>
</div>
<div class="notification-content">
<div class="notification-title" id="notification-title">通知标题</div>
<div class="notification-message" id="notification-message">通知内容</div>
</div>
<div class="notification-close" id="notification-close">
<i data-lucide="x"></i>
</div>
</div>
<!-- 页脚 -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-info">
<div class="footer-logo">
<div class="footer-logo-icon">
<i data-lucide="zap"></i>
</div>
<div class="footer-logo-text">漫画风工具箱</div>
</div>
<p class="footer-description">
一站式在线工具集合,提供100+种实用工具,满足您的各种需求。无需安装,随时随地使用!
</p>
<div class="footer-social">
<a href="#" class="footer-social-link">
<i data-lucide="github"></i>
</a>
<a href="#" class="footer-social-link">
<i data-lucide="twitter"></i>
</a>
<a href="#" class="footer-social-link">
<i data-lucide="instagram"></i>
</a>
<a href="#" class="footer-social-link">
<i data-lucide="facebook"></i>
</a>
</div>
</div>
<div class="footer-links">
<h3 class="footer-links-title">快速链接</h3>
<ul class="footer-links-list">
<li><a href="#" class="footer-link"><i data-lucide="home"></i> 首页</a></li>
<li><a href="#" class="footer-link"><i data-lucide="tool"></i> 所有工具</a></li>
<li><a href="#" class="footer-link"><i data-lucide="star"></i> 热门工具</a></li>
<li><a href="#" class="footer-link"><i data-lucide="clock"></i> 最近更新</a></li>
<li><a href="#" class="footer-link"><i data-lucide="help-circle"></i> 帮助中心</a></li>
</ul>
</div>
<div class="footer-links">
<h3 class="footer-links-title">联系我们</h3>
<ul class="footer-links-list">
<li><a href="#" class="footer-link"><i data-lucide="mail"></i> 联系我们</a></li>
<li><a href="#" class="footer-link"><i data-lucide="info"></i> 关于我们</a></li>
<li><a href="#" class="footer-link"><i data-lucide="message-square"></i> 反馈建议</a></li>
<li><a href="#" class="footer-link"><i data-lucide="plus-circle"></i> 提交工具</a></li>
<li><a href="#" class="footer-link"><i data-lucide="heart"></i> 支持我们</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div class="footer-copyright">
© 2025 漫画风工具箱 版权所有
</div>
<div class="footer-bottom-links">
<a href="#" class="footer-bottom-link">隐私政策</a>
<a href="#" class="footer-bottom-link">使用条款</a>
<a href="#" class="footer-bottom-link">Cookie政策</a>
</div>
</div>
</div>
</footer>
</div>
<script src="https://unpkg.com/lucide@latest"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
// 初始化Lucide图标
lucide.createIcons();
// 工具数据
const toolsData = {
"image": [
{ id: "image-converter", name: "图片格式转换", description: "支持多种格式互转,快速简便,保持图片质量", icon: "image" },
{ id: "image-compressor", name: "图片压缩", description: "减小图片文件大小,保持图片质量", icon: "image-minus" },
{ id: "image-cropper", name: "图片裁剪", description: "调整图片尺寸和比例", icon: "scissors" },
{ id: "image-filter", name: "图片滤镜", description: "为图片添加各种滤镜效果", icon: "palette" },
{ id: "image-watermark", name: "图片水印", description: "为图片添加文字或图片水印", icon: "stamp" },
{ id: "image-background-remover", name: "背景移除", description: "自动移除图片背景", icon: "eraser" }
],
"text": [
{ id: "text-translator", name: "文本翻译", description: "多语言文本翻译工具,支持多种语言互译", icon: "file-text" },
{ id: "text-diff", name: "文本对比", description: "比较两段文本的差异", icon: "git-compare" },
{ id: "text-counter", name: "字数统计", description: "统计文本字数和行数", icon: "list-checks" },
{ id: "text-case-converter", name: "大小写转换", description: "文本大小写转换工具", icon: "type" },
{ id: "text-encoder", name: "文本编码", description: "支持多种编码格式转换", icon: "code" }
],
"video": [
{ id: "video-to-gif", name: "视频转GIF", description: "将视频转换为GIF动图", icon: "film" },
{ id: "video-compressor", name: "视频压缩", description: "减小视频文件大小", icon: "film" },
{ id: "video-trimmer", name: "视频剪辑", description: "简单的视频剪辑工具", icon: "scissors" },
{ id: "video-converter", name: "视频格式转换", description: "支持多种视频格式互转", icon: "film" }
],
"audio": [
{ id: "audio-converter", name: "音频格式转换", description: "转换音频文件格式", icon: "music" },
{ id: "audio-trimmer", name: "音频剪辑", description: "剪辑和编辑音频文件", icon: "scissors" },
{ id: "audio-to-text", name: "语音转文字", description: "将语音内容转换为文本", icon: "mic" },
{ id: "audio-mixer", name: "音频混合", description: "混合多个音频文件", icon: "layers" }
],
"dev": [
{ id: "json-formatter", name: "JSON格式化", description: "格式化和验证JSON数据", icon: "code" },
{ id: "code-beautifier", name: "代码美化", description: "美化HTML/CSS/JS代码", icon: "code" },
{ id: "regex-tester", name: "正则测试", description: "测试和验证正则表达式", icon: "code" },
{ id: "html-minifier", name: "HTML压缩", description: "压缩HTML代码,减小文件大小", icon: "code" },
{ id: "css-minifier", name: "CSS压缩", description: "压缩CSS代码,减小文件大小", icon: "code" },
{ id: "js-minifier", name: "JS压缩", description: "压缩JavaScript代码,减小文件大小", icon: "code" }
],
"utility": [
{ id: "qr-generator", name: "二维码生成器", description: "快速生成自定义二维码", icon: "qr-code" },
{ id: "password-generator", name: "密码生成器", description: "生成安全、强壮的随机密码", icon: "key" },
{ id: "color-picker", name: "颜色选择器", description: "选择、转换和复制颜色代码", icon: "palette" },
{ id: "unit-converter", name: "单位转换工具", description: "支持多种单位互转", icon: "ruler" },
{ id: "timer", name: "计时器", description: "简单易用的计时器和倒计时工具", icon: "timer" },
{ id: "calculator", name: "计算器", description: "功能强大的在线计算器", icon: "calculator" }
]
};
// 热门工具数据
const popularTools = [
{ id: "image-converter", category: "image" },
{ id: "text-translator", category: "text" },
{ id: "json-formatter", category: "dev" },
{ id: "qr-generator", category: "utility" },
{ id: "password-generator", category: "utility" },
{ id: "color-picker", category: "utility" },
{ id: "video-to-gif", category: "video" },
{ id: "audio-converter", category: "audio" }
];
// 特色工具数据
const featuredTools = [
{ id: "image-converter", category: "image" },
{ id: "text-translator", category: "text" },
{ id: "json-formatter", category: "dev" },
{ id: "qr-generator", category: "utility" },
{ id: "password-generator", category: "utility" },
{ id: "color-picker", category: "utility" }
];
// 本地存储键
const STORAGE_KEYS = {
FAVORITES: 'toolbox_favorites',
HISTORY: 'toolbox_history',
THEME: 'theme'
};
// 数据管理
const dataManager = {
// 获取收藏工具
getFavorites() {
const favorites = localStorage.getItem(STORAGE_KEYS.FAVORITES);
return favorites ? JSON.parse(favorites) : [];
},
// 添加收藏
addFavorite(toolId) {
const favorites = this.getFavorites();
if (!favorites.includes(toolId)) {
favorites.push(toolId);
localStorage.setItem(STORAGE_KEYS.FAVORITES, JSON.stringify(favorites));
return true;
}
return false;
},
// 移除收藏
removeFavorite(toolId) {
const favorites = this.getFavorites();
const index = favorites.indexOf(toolId);
if (index !== -1) {
favorites.splice(index, 1);
localStorage.setItem(STORAGE_KEYS.FAVORITES, JSON.stringify(favorites));
return true;
}
return false;
},
// 检查是否收藏
isFavorite(toolId) {
const favorites = this.getFavorites();
return favorites.includes(toolId);
},
// 获取使用历史
getHistory() {
const history = localStorage.getItem(STORAGE_KEYS.HISTORY);
return history ? JSON.parse(history) : [];
},
// 添加使用记录
addToHistory(toolId) {
const history = this.getHistory();
// 检查是否已存在
const existingIndex = history.findIndex(item => item.id === toolId);
// 当前时间
const now = new Date();
if (existingIndex !== -1) {
// 更新现有记录
history[existingIndex].lastUsed = now.toISOString();
history[existingIndex].useCount = (history[existingIndex].useCount || 0) + 1;
} else {
// 添加新记录
history.push({
id: toolId,
lastUsed: now.toISOString(),
useCount: 1
});
}
// 按最近使用时间排序
history.sort((a, b) => new Date(b.lastUsed) - new Date(a.lastUsed));
// 只保留最近的20条记录
const trimmedHistory = history.slice(0, 20);
localStorage.setItem(STORAGE_KEYS.HISTORY, JSON.stringify(trimmedHistory));
return true;
},
// 清除所有数据
clearAllData() {
localStorage.removeItem(STORAGE_KEYS.FAVORITES);
localStorage.removeItem(STORAGE_KEYS.HISTORY);
return true;
}
};
// 主题切换功能
const themeToggle = document.getElementById("theme-toggle");
const htmlElement = document.documentElement;
// 检查本地存储中的主题偏好
const savedTheme = localStorage.getItem(STORAGE_KEYS.THEME);
if (savedTheme) {
htmlElement.className = savedTheme;
} else {
// 检查系统偏好
const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
htmlElement.className = prefersDarkMode ? "dark-theme" : "light-theme";
}
// 主题切换按钮点击事件
themeToggle.addEventListener("click", () => {
if (htmlElement.classList.contains("light-theme")) {
htmlElement.classList.remove("light-theme");
htmlElement.classList.add("dark-theme");
localStorage.setItem(STORAGE_KEYS.THEME, "dark-theme");
} else {
htmlElement.classList.remove("dark-theme");
htmlElement.classList.add("light-theme");
localStorage.setItem(STORAGE_KEYS.THEME, "light-theme");
}
});
// 菜单切换
const menuToggle = document.getElementById("menu-toggle");
const sidebar = document.getElementById("sidebar");
menuToggle.addEventListener("click", () => {
sidebar.classList.toggle("open");
});
// 初始化下拉菜单
document.querySelectorAll(".dropdown-trigger").forEach((trigger) => {
trigger.addEventListener("click", function () {
this.closest(".dropdown").classList.toggle("active");
});
});
// 点击外部关闭下拉菜单
document.addEventListener("click", (event) => {
if (!event.target.closest(".dropdown")) {
document.querySelectorAll(".dropdown.active").forEach((dropdown) => {
dropdown.classList.remove("active");
});
}
});
// 通知功能
const notification = document.getElementById("notification");
const notificationTitle = document.getElementById("notification-title");
const notificationMessage = document.getElementById("notification-message");
const notificationClose = document.getElementById("notification-close");
// 显示通知
function showNotification(title, message, duration = 3000) {
notificationTitle.textContent = title;
notificationMessage.textContent = message;
notification.classList.add("show");
// 更新图标
const iconElement = notification.querySelector(".notification-icon i");
if (iconElement) {
iconElement.setAttribute("data-lucide", title.toLowerCase().includes("错误") ? "alert-circle" : "check-circle");
lucide.createIcons();
}
// 自动关闭
setTimeout(() => {
notification.classList.remove("show");
}, duration);
}
// 关闭通知
notificationClose.addEventListener("click", () => {
notification.classList.remove("show");
});
// 页面导航功能
const pages = document.querySelectorAll(".page-container");
const navButtons = document.querySelectorAll(".nav-button");
const breadcrumb = document.getElementById("breadcrumb");
// 设置当前活跃页面
function setActivePage(pageId, categoryId = null, toolId = null) {
// 添加过渡动画
pages.forEach(page => {
if (page.classList.contains("active")) {
page.classList.add("fade-out");
setTimeout(() => {
page.classList.remove("active");
page.classList.remove("fade-out");
// 显示目标页面
const targetPage = document.getElementById(pageId);
if (targetPage) {
targetPage.classList.add("active");
targetPage.classList.add("fade-in");
setTimeout(() => {
targetPage.classList.remove("fade-in");
}, 300);
}
}, 300);
}
});
// 如果没有活跃页面,直接显示目标页面
if (!document.querySelector(".page-container.active")) {
const targetPage = document.getElementById(pageId);
if (targetPage) {
targetPage.classList.add("active");
targetPage.classList.add("fade-in");
setTimeout(() => {
targetPage.classList.remove("fade-in");
}, 300);
}
}
// 更新导航按钮状态
navButtons.forEach(button => {
button.classList.remove("active");
if (button.dataset.page === pageId) {
if (!categoryId || !button.dataset.category || button.dataset.category === categoryId) {
button.classList.add("active");
}
}
});
// 更新面包屑导航
updateBreadcrumb(pageId, categoryId, toolId);
// 如果是分类页面,加载对应分类的工具
if (pageId === "category-page" && categoryId) {
loadCategoryTools(categoryId);
}
// 如果是工具详情页面,加载工具详情
if (pageId === "tool-detail-page" && toolId) {
loadToolDetail(toolId);
}
// 如果是收藏工具页面,加载收藏的工具
if (pageId === "favorite-tools-page") {
loadFavoriteTools();
}
// 如果是最近使用页面,加载最近使用的工具
if (pageId === "recent-tools-page") {
loadRecentTools();
}
// 如果是热门工具页面,加载热门工具
if (pageId === "popular-tools-page") {
loadPopularTools();
}
// 如果是首页,加载特色工具
if (pageId === "home-page") {
loadFeaturedTools();
}
// 如果是移动设备,点击后关闭侧边栏
if (window.innerWidth < 768) {
sidebar.classList.remove("open");
}
}
// 更新面包屑导航
function updateBreadcrumb(pageId, categoryId = null, toolId = null) {
let breadcrumbText = "";
switch (pageId) {
case "home-page":
breadcrumbText = "首页";
break;
case "popular-tools-page":
breadcrumbText = "首页 / 热门工具";
break;
case "favorite-tools-page":
breadcrumbText = "首页 / 收藏工具";
break;
case "recent-tools-page":
breadcrumbText = "首页 / 最近使用";
break;
case "category-page":
const categoryName = getCategoryName(categoryId);
breadcrumbText = `首页 / ${categoryName}`;
break;
case "tool-detail-page":
if (toolId) {
const toolInfo = getToolInfo(toolId);
if (toolInfo) {
const categoryName = getCategoryName(getToolCategory(toolId));
breadcrumbText = `首页 / ${categoryName} / ${toolInfo.name}`;
} else {
breadcrumbText = "首页 / 工具详情";
}
} else {
breadcrumbText = "首页 / 工具详情";
}
break;
default:
breadcrumbText = "首页";
}
breadcrumb.textContent = breadcrumbText;
}
// 获取分类名称
function getCategoryName(categoryId) {
const categoryMap = {
"image": "图片工具",
"text": "文本工具",
"video": "视频工具",
"audio": "音频工具",
"dev": "开发工具",
"utility": "实用工具"
};
return categoryMap[categoryId] || "工具分类";
}
// 获取分类描述
function getCategoryDescription(categoryId) {
const descriptionMap = {
"image": "各种图片处理工具,满足您的图片编辑需求。",
"text": "文本处理工具集合,帮助您高效处理各种文本内容。",
"video": "视频编辑和转换工具,让视频处理变得简单。",
"audio": "音频处理工具,支持格式转换、剪辑等功能。",
"dev": "为开发者提供的实用工具,提高开发效率。",
"utility": "日常实用工具集合,满足各种日常需求。"
};
return descriptionMap[categoryId] || "各种实用工具集合";
}
// 获取工具所属分类
function getToolCategory(toolId) {
for (const category in toolsData) {
const tool = toolsData[category].find(t => t.id === toolId);
if (tool) {
return category;
}
}
return null;
}
// 加载分类工具
function loadCategoryTools(categoryId) {
const categoryTitle = document.getElementById("category-title");
const categoryDescription = document.getElementById("category-description");
const categoryToolsGrid = document.getElementById("category-tools-grid");
// 更新分类标题和描述
categoryTitle.textContent = getCategoryName(categoryId);
categoryDescription.textContent = getCategoryDescription(categoryId);
// 清空工具网格
categoryToolsGrid.innerHTML = "";
// 根据分类加载工具
const tools = toolsData[categoryId] || [];
// 添加工具卡片
tools.forEach(tool => {
const isFavorite = dataManager.isFavorite(tool.id);
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = tool.id;
toolCard.innerHTML = `
<button class="favorite-button ${isFavorite ? 'active' : ''}" data-tool="${tool.id}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${tool.icon}"></i>
</div>
<h3 class="tool-card-title">${tool.name}</h3>
<p class="tool-card-description">${tool.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(tool.id);
setActivePage("tool-detail-page", null, tool.id);
// 添加使用记录
dataManager.addToHistory(tool.id);
}
});
categoryToolsGrid.appendChild(toolCard);
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 加载热门工具
function loadPopularTools() {
const popularToolsGrid = document.getElementById("popular-tools-grid");
// 清空工具网格
popularToolsGrid.innerHTML = "";
// 加载热门工具
popularTools.forEach(popularTool => {
const category = popularTool.category;
const toolId = popularTool.id;
// 查找工具信息
const tool = toolsData[category].find(t => t.id === toolId);
if (tool) {
const isFavorite = dataManager.isFavorite(tool.id);
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = tool.id;
toolCard.innerHTML = `
<button class="favorite-button ${isFavorite ? 'active' : ''}" data-tool="${tool.id}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${tool.icon}"></i>
</div>
<h3 class="tool-card-title">${tool.name}</h3>
<p class="tool-card-description">${tool.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(tool.id);
setActivePage("tool-detail-page", null, tool.id);
// 添加使用记录
dataManager.addToHistory(tool.id);
}
});
popularToolsGrid.appendChild(toolCard);
}
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 加载特色工具
function loadFeaturedTools() {
const featuredToolsGrid = document.getElementById("featured-tools-grid");
// 清空工具网格
featuredToolsGrid.innerHTML = "";
// 加载特色工具
featuredTools.forEach(featuredTool => {
const category = featuredTool.category;
const toolId = featuredTool.id;
// 查找工具信息
const tool = toolsData[category].find(t => t.id === toolId);
if (tool) {
const isFavorite = dataManager.isFavorite(tool.id);
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = tool.id;
toolCard.innerHTML = `
<button class="favorite-button ${isFavorite ? 'active' : ''}" data-tool="${tool.id}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${tool.icon}"></i>
</div>
<h3 class="tool-card-title">${tool.name}</h3>
<p class="tool-card-description">${tool.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(tool.id);
setActivePage("tool-detail-page", null, tool.id);
// 添加使用记录
dataManager.addToHistory(tool.id);
}
});
featuredToolsGrid.appendChild(toolCard);
}
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 加载收藏工具
function loadFavoriteTools() {
const favoriteToolsGrid = document.getElementById("favorite-tools-grid");
// 清空工具网格
favoriteToolsGrid.innerHTML = "";
// 获取收藏的工具
const favorites = dataManager.getFavorites();
if (favorites.length === 0) {
// 显示无收藏提示
favoriteToolsGrid.innerHTML = `
<div class="no-favorites">
<div class="no-favorites-icon">
<i data-lucide="heart-off"></i>
</div>
<h3 class="no-favorites-title">暂无收藏工具</h3>
<p class="no-favorites-text">您还没有收藏任何工具,浏览工具时点击心形图标即可收藏。</p>
<button class="comic-button" id="browse-tools-button">
<i data-lucide="search"></i> 浏览工具
</button>
</div>
`;
// 浏览工具按钮点击事件
const browseToolsButton = document.getElementById("browse-tools-button");
if (browseToolsButton) {
browseToolsButton.addEventListener("click", () => {
setActivePage("popular-tools-page");
});
}
// 重新初始化图标
lucide.createIcons();
return;
}
// 加载收藏的工具
favorites.forEach(toolId => {
// 查找工具信息
const toolInfo = getToolInfo(toolId);
if (toolInfo) {
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = toolId;
toolCard.innerHTML = `
<button class="favorite-button active" data-tool="${toolId}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${toolInfo.icon}"></i>
</div>
<h3 class="tool-card-title">${toolInfo.name}</h3>
<p class="tool-card-description">${toolInfo.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(toolId);
setActivePage("tool-detail-page", null, toolId);
// 添加使用记录
dataManager.addToHistory(toolId);
}
});
favoriteToolsGrid.appendChild(toolCard);
}
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 加载最近使用的工具
function loadRecentTools() {
const recentToolsList = document.getElementById("recent-tools-list");
// 清空列表
recentToolsList.innerHTML = "";
// 获取使用历史
const history = dataManager.getHistory();
if (history.length === 0) {
// 显示无历史记录提示
recentToolsList.innerHTML = `
<div class="no-history">
<div class="no-history-icon">
<i data-lucide="clock"></i>
</div>
<h3 class="no-history-title">暂无使用记录</h3>
<p class="no-history-text">您还没有使用过任何工具,使用工具后会自动记录在这里。</p>
<button class="comic-button" id="explore-tools-button">
<i data-lucide="search"></i> 探索工具
</button>
</div>
`;
// 探索工具按钮点击事件
const exploreToolsButton = document.getElementById("explore-tools-button");
if (exploreToolsButton) {
exploreToolsButton.addEventListener("click", () => {
setActivePage("popular-tools-page");
});
}
// 重新初始化图标
lucide.createIcons();
return;
}
// 加载最近使用的工具
history.forEach(historyItem => {
const toolId = historyItem.id;
const lastUsed = new Date(historyItem.lastUsed);
const useCount = historyItem.useCount || 1;
// 查找工具信息
const toolInfo = getToolInfo(toolId);
if (toolInfo) {
const isFavorite = dataManager.isFavorite(toolId);
// 格式化最后使用时间
const formattedDate = formatDate(lastUsed);
const toolItem = document.createElement("div");
toolItem.className = "recent-tool-item";
toolItem.dataset.tool = toolId;
toolItem.innerHTML = `
<div class="recent-tool-icon">
<i data-lucide="${toolInfo.icon}"></i>
</div>
<div class="recent-tool-info">
<div class="recent-tool-title">${toolInfo.name}</div>
<div class="recent-tool-date">最近使用:${formattedDate} · 使用次数:${useCount}次</div>
</div>
<div class="recent-tool-actions">
<button class="recent-tool-button favorite ${isFavorite ? 'active' : ''}" data-tool="${toolId}">
<i data-lucide="heart"></i>
</button>
<button class="recent-tool-button open" data-tool="${toolId}">
<i data-lucide="external-link"></i>
</button### 实现工具收藏和使用记录功能
我将为您的工具箱添加工具收藏功能和使用记录功能,并确保所有功能可以正常使用。以下是完整的实现代码:
```html
<!DOCTYPE html>
<html lang="zh-CN" class="light-theme">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>漫画风格工具箱 - 多功能工具集合</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lucide-icons@0.309.0/dist/umd/lucide-icons.min.css">
<style>
/* 导入字体 */
@import url('https://fonts.googleapis.com/css2?family=Bangers&family=ZCOOL+KuaiLe&display=swap');
/* 主题变量 - 浅色模式 */
:root {
--color-background: #ffffff;
--color-background-secondary: #f9f9f9;
--color-background-tertiary: #f0f0f0;
--color-foreground: #000000;
--color-foreground-muted: #333333;
--color-foreground-subtle: #666666;
--color-surface: #f0f0f0;
--color-surface-hover: #e0e0e0;
--color-surface-active: #d0d0d0;
--color-border: #000000;
--color-accent: #000000;
--color-accent-hover: #333333;
--color-accent-muted: #666666;
--color-header-bg: #ffffff;
--color-header-text: #000000;
--color-tool-header-bg: #000000;
--color-tool-header-text: #ffffff;
--color-card-bg: #ffffff;
--color-card-shadow: #000000;
--color-input-bg: #ffffff;
--color-input-border: #000000;
--color-button-bg: #000000;
--color-button-text: #ffffff;
--color-button-hover: #333333;
--color-progress-bg: #f0f0f0;
--color-progress-fill: #000000;
--color-success-bg: #f0f0f0;
--color-success-text: #000000;
--color-error-bg: #fff0f0;
--color-error-text: #ff0000;
--color-highlight: #ffff00;
--color-highlight-alt: #ff9900;
--color-favorite: #ff0000;
--shadow-comic: 5px 5px 0px var(--color-card-shadow);
--border-comic: 3px solid var(--color-border);
--border-comic-thin: 2px solid var(--color-border);
--border-comic-dashed: 3px dashed var(--color-border);
--font-comic: 'Bangers', 'ZCOOL KuaiLe', cursive, sans-serif;
--font-sans: 'Arial', sans-serif;
--font-mono: 'Courier New', monospace;
--pattern-dots: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23000000' fill-opacity='0.1' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E");
--pattern-lines: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23000000' fill-opacity='0.1' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 5v1H5z'/%3E%3Cpath d='M6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
--pattern-zigzag: url("data:image/svg+xml,%3Csvg width='40' height='12' viewBox='0 0 40 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 6.172L6.172 0h5.656L0 11.828V6.172zm40 5.656L28.172 0h5.656L40 6.172v5.656zM6.172 12l12-12h3.656l12 12h-5.656L20 3.828 11.828 12H6.172zm12 0L20 10.172 21.828 12h-3.656z' fill='%23000000' fill-opacity='0.1' fill-rule='evenodd'/%3E%3C/svg%3E");
--pattern-bg: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23000000' fill-opacity='0.03' fill-rule='evenodd'/%3E%3C/svg%3E");
}
/* 深色模式变量 */
.dark-theme {
--color-background: #121212;
--color-background-secondary: #1e1e1e;
--color-background-tertiary: #2a2a2a;
--color-foreground: #ffffff;
--color-foreground-muted: #cccccc;
--color-foreground-subtle: #999999;
--color-surface: #2a2a2a;
--color-surface-hover: #3a3a3a;
--color-surface-active: #4a4a4a;
--color-border: #ffffff;
--color-accent: #ffffff;
--color-accent-hover: #cccccc;
--color-accent-muted: #999999;
--color-header-bg: #1a1a1a;
--color-header-text: #ffffff;
--color-tool-header-bg: #ffffff;
--color-tool-header-text: #000000;
--color-card-bg: #1e1e1e;
--color-card-shadow: #ffffff;
--color-input-bg: #2a2a2a;
--color-input-border: #ffffff;
--color-button-bg: #ffffff;
--color-button-text: #000000;
--color-button-hover: #cccccc;
--color-progress-bg: #2a2a2a;
--color-progress-fill: #ffffff;
--color-success-bg: #2a2a2a;
--color-success-text: #ffffff;
--color-error-bg: #3a1a1a;
--color-error-text: #ff6666;
--color-highlight: #ffff00;
--color-highlight-alt: #ff9900;
--color-favorite: #ff5555;
--pattern-dots: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.1' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E");
--pattern-lines: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.1' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 5v1H5z'/%3E%3Cpath d='M6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
--pattern-zigzag: url("data:image/svg+xml,%3Csvg width='40' height='12' viewBox='0 0 40 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 6.172L6.172 0h5.656L0 11.828V6.172zm40 5.656L28.172 0h5.656L40 6.172v5.656zM6.172 12l12-12h3.656l12 12h-5.656L20 3.828 11.828 12H6.172zm12 0L20 10.172 21.828 12h-3.656z' fill='%23ffffff' fill-opacity='0.1' fill-rule='evenodd'/%3E%3C/svg%3E");
--pattern-bg: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23ffffff' fill-opacity='0.03' fill-rule='evenodd'/%3E%3C/svg%3E");
}
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-sans);
background-color: var(--color-background);
background-image: var(--pattern-bg);
color: var(--color-foreground);
line-height: 1.5;
min-height: 100vh;
transition: background-color 0.3s, color 0.3s;
}
button, input, select, textarea {
font-family: inherit;
font-size: inherit;
color: inherit;
}
button {
cursor: pointer;
background: none;
border: none;
}
a {
color: inherit;
text-decoration: none;
}
/* 漫画风格元素 */
.comic-title {
font-family: var(--font-comic);
text-transform: uppercase;
letter-spacing: 1px;
transform: rotate(-2deg);
display: inline-block;
position: relative;
z-index: 1;
}
.comic-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 10px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.comic-box {
border: var(--border-comic);
box-shadow: var(--shadow-comic);
position: relative;
background-color: var(--color-card-bg);
transform: rotate(0.5deg);
}
.comic-box-alt {
border: var(--border-comic);
box-shadow: var(--shadow-comic);
position: relative;
background-color: var(--color-card-bg);
transform: rotate(-0.5deg);
}
.comic-button {
font-family: var(--font-comic);
text-transform: uppercase;
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 8px 16px;
position: relative;
box-shadow: 3px 3px 0 var(--color-card-shadow);
transform: rotate(-1deg);
transition: all 0.1s;
}
.comic-button:hover {
transform: rotate(0deg) translate(-2px, -2px);
box-shadow: 5px 5px 0 var(--color-card-shadow);
}
.comic-button:active {
transform: rotate(0deg) translate(2px, 2px);
box-shadow: 1px 1px 0 var(--color-card-shadow);
}
.comic-input {
border: var(--border-comic-thin);
padding: 8px 12px;
background-color: var(--color-input-bg);
box-shadow: 3px 3px 0 rgba(var(--color-card-shadow), 0.2);
}
.comic-input:focus {
outline: none;
box-shadow: 3px 3px 0 rgba(var(--color-card-shadow), 0.5);
}
.comic-badge {
font-family: var(--font-comic);
background-color: var(--color-accent);
color: var(--color-background);
padding: 2px 8px;
transform: rotate(-3deg);
display: inline-block;
}
.comic-divider {
height: 3px;
background-image: var(--pattern-lines);
margin: 20px 0;
}
.comic-speech-bubble {
position: relative;
background-color: var(--color-card-bg);
border: var(--border-comic-thin);
padding: 15px;
border-radius: 30px;
box-shadow: 3px 3px 0 rgba(var(--color-card-shadow), 0.2);
}
.comic-speech-bubble::after {
content: '';
position: absolute;
bottom: -20px;
left: 30px;
width: 30px;
height: 30px;
background-color: var(--color-card-bg);
border-right: var(--border-comic-thin);
border-bottom: var(--border-comic-thin);
transform: rotate(45deg) skew(10deg, 10deg);
z-index: -1;
}
/* 布局 */
.app-container {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container {
width: 100%;
max-width: 1280px;
margin: 0 auto;
padding: 0 20px;
}
.main-content {
display: flex;
flex-direction: column;
gap: 24px;
padding-top: 24px;
padding-bottom: 24px;
}
@media (min-width: 768px) {
.main-content {
flex-direction: row;
}
}
/* 头部 */
.header {
position: sticky;
top: 0;
z-index: 10;
background-color: var(--color-header-bg);
border-bottom: var(--border-comic);
padding: 10px 0;
transition: background-color 0.3s;
}
.header-content {
display: flex;
align-items: center;
justify-content: space-between;
}
.logo-container {
display: flex;
align-items: center;
gap: 12px;
}
.logo-icon {
width: 50px;
height: 50px;
background-color: var(--color-accent);
border: var(--border-comic-thin);
display: flex;
align-items: center;
justify-content: center;
transform: rotate(-5deg);
}
.logo-icon svg {
width: 30px;
height: 30px;
color: var(--color-background);
}
.logo-title {
font-family: var(--font-comic);
font-size: 24px;
transform: rotate(-2deg);
}
.logo-subtitle {
font-size: 12px;
color: var(--color-foreground-muted);
transform: rotate(-2deg);
}
.header-actions {
display: none;
}
@media (min-width: 768px) {
.header-actions {
display: flex;
align-items: center;
gap: 8px;
}
}
.search-container {
position: relative;
width: 250px;
}
.search-icon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--color-foreground-muted);
width: 16px;
height: 16px;
}
.search-input {
width: 100%;
border: var(--border-comic-thin);
border-radius: 20px;
padding: 6px 16px 6px 32px;
background-color: var(--color-input-bg);
}
.icon-button {
width: 40px;
height: 40px;
border: var(--border-comic-thin);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.icon-button:hover {
transform: translate(-1px, -1px);
box-shadow: 3px 3px 0 var(--color-card-shadow);
}
.icon-button svg {
width: 20px;
height: 20px;
}
.menu-button {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.menu-button:hover {
transform: translate(-1px, -1px);
box-shadow: 3px 3px 0 var(--color-card-shadow);
}
.menu-button svg {
width: 24px;
height: 24px;
}
@media (min-width: 768px) {
.menu-button {
display: none;
}
}
/* 主题切换按钮 */
.theme-toggle {
position: relative;
width: 40px;
height: 40px;
border: var(--border-comic-thin);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
box-shadow: 2px 2px 0 var(--color-card-shadow);
overflow: hidden;
}
.theme-toggle:hover {
transform: translate(-1px, -1px);
box-shadow: 3px 3px 0 var(--color-card-shadow);
}
.theme-toggle svg {
width: 20px;
height: 20px;
position: absolute;
transition: transform 0.3s ease;
}
.theme-toggle .sun-icon {
transform: translateY(0);
}
.theme-toggle .moon-icon {
transform: translateY(40px);
}
.dark-theme .theme-toggle .sun-icon {
transform: translateY(-40px);
}
.dark-theme .theme-toggle .moon-icon {
transform: translateY(0);
}
/* 下拉菜单 */
.dropdown {
position: relative;
}
.dropdown-content {
position: absolute;
top: 100%;
right: 0;
margin-top: 8px;
background-color: var(--color-card-bg);
border: var(--border-comic);
box-shadow: var(--shadow-comic);
min-width: 160px;
z-index: 20;
display: none;
}
.dropdown.active .dropdown-content {
display: block;
}
.dropdown-item {
display: flex;
align-items: center;
padding: 8px 12px;
border-bottom: 1px solid var(--color-border);
}
.dropdown-item:last-child {
border-bottom: none;
}
.dropdown-item:hover {
background-color: var(--color-surface-hover);
}
.dropdown-item svg {
width: 16px;
height: 16px;
margin-right: 8px;
}
/* 侧边栏 */
.sidebar {
display: none;
flex-shrink: 0;
transition: all 0.3s ease-in-out;
overflow: hidden;
border: var(--border-comic);
background-color: var(--color-card-bg);
box-shadow: var(--shadow-comic);
transform: rotate(-0.5deg);
}
.sidebar.open {
display: block;
}
@media (min-width: 768px) {
.sidebar {
display: block;
width: 250px;
}
}
.sidebar-content {
display: flex;
flex-direction: column;
gap: 24px;
padding: 20px;
}
.main-nav,
.category-nav {
display: flex;
flex-direction: column;
gap: 4px;
}
.category-title {
font-family: var(--font-comic);
font-size: 18px;
margin-bottom: 8px;
text-transform: uppercase;
position: relative;
display: inline-block;
}
.category-title::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
background-color: var(--color-highlight);
z-index: -1;
}
.nav-button {
display: flex;
align-items: center;
padding: 8px 12px;
border: 1px solid transparent;
border-radius: 4px;
transition: all 0.2s;
text-align: left;
width: 100%;
font-weight: 500;
}
.nav-button:hover {
border-color: var(--color-border);
background-color: var(--color-surface-hover);
transform: translate(-2px, -2px);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.nav-button.active {
border: 1px solid var(--color-border);
background-color: var(--color-surface);
transform: translate(-2px, -2px);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.nav-button svg {
width: 16px;
height: 16px;
margin-right: 8px;
}
.sidebar-footer {
color: var(--color-foreground-muted);
font-size: 12px;
border-top: 1px dashed var(--color-border);
padding-top: 16px;
}
.footer-links {
display: flex;
gap: 16px;
margin-top: 8px;
}
.footer-links a {
text-decoration: underline;
}
.footer-links a:hover {
color: var(--color-foreground);
}
/* 主内容 */
.main {
flex: 1;
display: flex;
flex-direction: column;
gap: 24px;
}
.breadcrumb {
font-size: 14px;
color: var(--color-foreground-muted);
margin-bottom: 16px;
font-style: italic;
}
/* 页面容器 */
.page-container {
display: none;
}
.page-container.active {
display: block;
}
/* 首页样式 */
.hero-section {
position: relative;
padding: 60px 0;
overflow: hidden;
border: var(--border-comic);
background-color: var(--color-card-bg);
box-shadow: var(--shadow-comic);
margin-bottom: 40px;
}
.hero-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: var(--pattern-dots);
opacity: 0.5;
z-index: 0;
}
.hero-content {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 0 20px;
}
.hero-title {
font-family: var(--font-comic);
font-size: 48px;
margin-bottom: 16px;
text-transform: uppercase;
position: relative;
display: inline-block;
}
.hero-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 10px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.hero-subtitle {
font-size: 20px;
margin-bottom: 32px;
max-width: 600px;
}
.hero-buttons {
display: flex;
gap: 16px;
flex-wrap: wrap;
justify-content: center;
}
.hero-button {
font-family: var(--font-comic);
font-size: 18px;
padding: 12px 24px;
background-color: var(--color-button-bg);
color: var(--color-button-text);
border: var(--border-comic-thin);
box-shadow: 4px 4px 0 var(--color-card-shadow);
transform: rotate(-1deg);
transition: all 0.2s;
}
.hero-button:hover {
transform: rotate(0deg) translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.hero-button.secondary {
background-color: var(--color-card-bg);
color: var(--color-foreground);
transform: rotate(1deg);
}
.hero-button.secondary:hover {
transform: rotate(0deg) translate(-2px, -2px);
}
.hero-decoration {
position: absolute;
font-family: var(--font-comic);
font-size: 24px;
color: var(--color-accent);
transform: rotate(-15deg);
z-index: 2;
}
.hero-decoration.top-left {
top: 20px;
left: 40px;
}
.hero-decoration.bottom-right {
bottom: 20px;
right: 40px;
}
.hero-decoration::before {
content: '★';
margin-right: 8px;
}
.hero-decoration::after {
content: '★';
margin-left: 8px;
}
/* 特色工具部分 */
.featured-tools {
margin-bottom: 40px;
}
.section-title-container {
display: flex;
align-items: center;
margin-bottom: 24px;
}
.section-title {
font-family: var(--font-comic);
font-size: 32px;
text-transform: uppercase;
position: relative;
display: inline-block;
margin-right: 16px;
}
.section-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 8px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.section-line {
flex: 1;
height: 3px;
background-image: var(--pattern-lines);
}
.tools-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.tool-card {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 24px;
transition: all 0.2s;
cursor: pointer;
position: relative;
box-shadow: 4px 4px 0 var(--color-card-shadow);
}
.tool-card:hover {
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.tool-card.active {
background-color: var(--color-background-secondary);
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.tool-card-icon {
width: 50px;
height: 50px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
background-color: var(--color-background-tertiary);
}
.tool-card-icon svg {
width: 30px;
height: 30px;
}
.tool-card-title {
font-family: var(--font-comic);
font-size: 20px;
font-weight: 700;
margin-bottom: 8px;
}
.tool-card-description {
font-size: 14px;
color: var(--color-foreground-muted);
margin-bottom: 16px;
}
.tool-card-button {
font-size: 14px;
text-decoration: underline;
font-weight: 500;
color: var(--color-accent);
}
/* 收藏按钮 */
.favorite-button {
position: absolute;
top: 10px;
right: 10px;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
border: 1px solid var(--color-border);
box-shadow: 2px 2px 0 var(--color-card-shadow);
transition: all 0.2s;
z-index: 2;
}
.favorite-button:hover {
transform: scale(1.1);
}
.favorite-button svg {
width: 16px;
height: 16px;
color: var(--color-foreground-muted);
transition: all 0.2s;
}
.favorite-button.active svg {
color: var(--color-favorite);
fill: var(--color-favorite);
}
/* 分类部分 */
.categories-section {
margin-bottom: 40px;
}
.categories-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 24px;
}
.category-card {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 20px;
text-align: center;
transition: all 0.2s;
cursor: pointer;
box-shadow: 4px 4px 0 var(--color-card-shadow);
}
.category-card:hover {
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.category-card-icon {
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 16px;
background-color: var(--color-background-tertiary);
}
.category-card-icon svg {
width: 30px;
height: 30px;
}
.category-card-title {
font-family: var(--font-comic);
font-size: 18px;
font-weight: 700;
margin-bottom: 8px;
}
.category-card-count {
font-size: 14px;
color: var(--color-foreground-muted);
}
/* 统计部分 */
.stats-section {
margin-bottom: 40px;
}
.stats-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 24px;
}
.stat-card {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 24px;
text-align: center;
box-shadow: 4px 4px 0 var(--color-card-shadow);
position: relative;
overflow: hidden;
}
.stat-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: var(--pattern-dots);
opacity: 0.1;
z-index: 0;
}
.stat-value {
font-family: var(--font-comic);
font-size: 36px;
font-weight: 700;
margin-bottom: 8px;
position: relative;
z-index: 1;
}
.stat-label {
font-size: 16px;
color: var(--color-foreground-muted);
position: relative;
z-index: 1;
}
/* 评价部分 */
.testimonials-section {
margin-bottom: 40px;
}
.testimonials-container {
display: grid;
grid-template-columns: 1fr;
gap: 24px;
}
@media (min-width: 768px) {
.testimonials-container {
grid-template-columns: repeat(2, 1fr);
}
}
.testimonial-card {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 24px;
box-shadow: 4px 4px 0 var(--color-card-shadow);
position: relative;
}
.testimonial-content {
font-style: italic;
margin-bottom: 16px;
position: relative;
padding-left: 24px;
}
.testimonial-content::before {
content: '"';
position: absolute;
left: 0;
top: 0;
font-size: 48px;
line-height: 1;
font-family: var(--font-comic);
color: var(--color-accent-muted);
}
.testimonial-author {
display: flex;
align-items: center;
gap: 12px;
}
.testimonial-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: var(--color-background-tertiary);
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--color-border);
}
.testimonial-avatar svg {
width: 20px;
height: 20px;
}
.testimonial-info {
flex: 1;
}
.testimonial-name {
font-weight: 700;
}
.testimonial-role {
font-size: 14px;
color: var(--color-foreground-muted);
}
/* 底部区域 */
.bottom-sections {
display: grid;
grid-template-columns: 1fr;
gap: 24px;
}
@media (min-width: 768px) {
.bottom-sections {
grid-template-columns: 1fr 1fr;
}
}
.info-section {
border: var(--border-comic);
background-color: var(--color-card-bg);
box-shadow: var(--shadow-comic);
transform: rotate(-0.5deg);
}
.section-header {
padding: 16px 24px;
border-bottom: var(--border-comic-thin);
background-color: var(--color-background-secondary);
}
.section-content {
padding: 24px;
}
.tool-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 12px;
}
.tool-list-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px;
border: 1px solid var(--color-border);
background-color: var(--color-card-bg);
transition: all 0.2s;
}
.tool-list-item:hover {
background-color: var(--color-background-secondary);
transform: translate(-2px, -2px);
box-shadow: 2px 2px 0 var(--color-card-shadow);
}
.tool-indicator {
width: 8px;
height: 8px;
background-color: var(--color-accent);
border-radius: 50%;
margin-right: 12px;
}
.tool-meta {
display: flex;
align-items: center;
gap: 8px;
}
.tool-date {
font-size: 12px;
color: var(--color-foreground-subtle);
}
.tool-tag {
font-size: 10px;
background-color: var(--color-accent);
color: var(--color-background);
padding: 2px 8px;
text-transform: uppercase;
transform: rotate(-2deg);
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 24px;
}
.stat-card {
border: 2px solid var(--color-border);
background-color: var(--color-card-bg);
padding: 16px;
box-shadow: 3px 3px 0 var(--color-card-shadow);
}
.stat-value {
font-size: 32px;
font-weight: 700;
margin-bottom: 4px;
font-family: var(--font-comic);
}
.stat-label {
font-size: 14px;
color: var(--color-foreground-muted);
}
.progress-stats {
display: flex;
flex-direction: column;
gap: 16px;
}
.progress-item {
display: flex;
flex-direction: column;
gap: 4px;
}
.progress-header {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 14px;
margin-bottom: 4px;
}
.progress-bar {
width: 100%;
height: 10px;
background-color: var(--color-progress-bg);
border: 1px solid var(--color-border);
overflow: hidden;
}
.progress-fill {
height: 100%;
background-color: var(--color-progress-fill);
transition: width 0.3s ease;
}
.progress-fill-green {
background-color: var(--color-progress-fill);
background-image: var(--pattern-dots);
}
.progress-fill-yellow {
background-color: var(--color-progress-fill);
background-image: var(--pattern-zigzag);
}
/* 热门工具页面 */
.popular-tools-page {
padding: 20px 0;
}
.popular-tools-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
margin-bottom: 40px;
}
/* 收藏工具页面 */
.favorite-tools-page {
padding: 20px 0;
}
.favorite-tools-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
margin-bottom: 40px;
}
.no-favorites {
text-align: center;
padding: 40px;
border: var(--border-comic-dashed);
background-color: var(--color-card-bg);
}
.no-favorites-icon {
font-size: 48px;
margin-bottom: 16px;
}
.no-favorites-title {
font-family: var(--font-comic);
font-size: 24px;
margin-bottom: 8px;
}
.no-favorites-text {
color: var(--color-foreground-muted);
margin-bottom: 16px;
}
/* 最近使用页面 */
.recent-tools-page {
padding: 20px 0;
}
.recent-tools-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 16px;
margin-bottom: 40px;
}
.recent-tool-item {
border: var(--border-comic-thin);
background-color: var(--color-card-bg);
padding: 16px;
display: flex;
align-items: center;
gap: 16px;
box-shadow: 4px 4px 0 var(--color-card-shadow);
transition: all 0.2s;
cursor: pointer;
}
.recent-tool-item:hover {
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 var(--color-card-shadow);
}
.recent-tool-icon {
width: 40px;
height: 40px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-background-tertiary);
flex-shrink: 0;
}
.recent-tool-icon svg {
width: 24px;
height: 24px;
}
.recent-tool-info {
flex: 1;
}
.recent-tool-title {
font-weight: 700;
margin-bottom: 4px;
}
.recent-tool-date {
font-size: 12px;
color: var(--color-foreground-muted);
}
.recent-tool-actions {
display: flex;
gap: 8px;
}
.recent-tool-button {
width: 32px;
height: 32px;
border: 1px solid var(--color-border);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
transition: all 0.2s;
}
.recent-tool-button:hover {
background-color: var(--color-surface-hover);
}
.recent-tool-button svg {
width: 16px;
height: 16px;
}
.recent-tool-button.favorite.active svg {
color: var(--color-favorite);
fill: var(--color-favorite);
}
.no-history {
text-align: center;
padding: 40px;
border: var(--border-comic-dashed);
background-color: var(--color-card-bg);
}
.no-history-icon {
font-size: 48px;
margin-bottom: 16px;
}
.no-history-title {
font-family: var(--font-comic);
font-size: 24px;
margin-bottom: 8px;
}
.no-history-text {
color: var(--color-foreground-muted);
margin-bottom: 16px;
}
/* 分类页面 */
.category-page {
padding: 20px 0;
}
.category-header {
margin-bottom: 32px;
}
.category-header-title {
font-family: var(--font-comic);
font-size: 36px;
margin-bottom: 8px;
position: relative;
display: inline-block;
}
.category-header-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 10px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.category-header-description {
font-size: 18px;
color: var(--color-foreground-muted);
max-width: 800px;
}
/* 工具详情页面 */
.tool-detail-page {
padding: 20px 0;
}
.tool-detail-header {
margin-bottom: 32px;
}
.tool-detail-title {
font-family: var(--font-comic);
font-size: 36px;
margin-bottom: 8px;
position: relative;
display: inline-block;
}
.tool-detail-title::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 10px;
background-color: var(--color-highlight);
z-index: -1;
transform: rotate(1deg) skewX(-15deg);
}
.tool-detail-description {
font-size: 18px;
color: var(--color-foreground-muted);
max-width: 800px;
margin-bottom: 24px;
}
.tool-detail-actions {
display: flex;
gap: 16px;
margin-bottom: 32px;
}
.tool-detail-button {
font-family: var(--font-comic);
padding: 8px 16px;
background-color: var(--color-button-bg);
color: var(--color-button-text);
border: var(--border-comic-thin);
box-shadow: 3px 3px 0 var(--color-card-shadow);
transition: all 0.2s;
display: flex;
align-items: center;
gap: 8px;
}
.tool-detail-button:hover {
transform: translate(-2px, -2px);
box-shadow: 5px 5px 0 var(--color-card-shadow);
}
.tool-detail-button.secondary {
background-color: var(--color-card-bg);
color: var(--color-foreground);
}
.tool-detail-button.favorite.active {
background-color: var(--color-favorite);
color: white;
}
.tool-detail-button.favorite.active svg {
fill: white;
}
.tool-detail-content {
border: var(--border-comic);
background-color: var(--color-card-bg);
padding: 24px;
box-shadow: var(--shadow-comic);
}
/* 通知 */
.notification {
position: fixed;
bottom: 20px;
right: 20px;
padding: 12px 16px;
background-color: var(--color-card-bg);
border: var(--border-comic-thin);
box-shadow: var(--shadow-comic);
display: flex;
align-items: center;
gap: 12px;
z-index: 100;
transform: translateY(150%);
transition: transform 0.3s ease;
}
.notification.show {
transform: translateY(0);
}
.notification-icon {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}
.notification-content {
flex: 1;
}
.notification-title {
font-weight: 700;
margin-bottom: 4px;
}
.notification-message {
font-size: 14px;
color: var(--color-foreground-muted);
}
.notification-close {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
/* 页脚 */
.footer {
background-color: var(--color-background-secondary);
border-top: var(--border-comic);
padding: 40px 0;
margin-top: 40px;
}
.footer-content {
display: grid;
grid-template-columns: 1fr;
gap: 32px;
}
@media (min-width: 768px) {
.footer-content {
grid-template-columns: 2fr 1fr 1fr;
}
}
.footer-logo {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.footer-logo-icon {
width: 40px;
height: 40px;
background-color: var(--color-accent);
border: var(--border-comic-thin);
display: flex;
align-items: center;
justify-content: center;
transform: rotate(-5deg);
}
.footer-logo-icon svg {
width: 24px;
height: 24px;
color: var(--color-background);
}
.footer-logo-text {
font-family: var(--font-comic);
font-size: 20px;
}
.footer-description {
margin-bottom: 16px;
color: var(--color-foreground-muted);
}
.footer-social {
display: flex;
gap: 12px;
}
.footer-social-link {
width: 36px;
height: 36px;
border: var(--border-comic-thin);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-card-bg);
transition: all 0.2s;
}
.footer-social-link:hover {
transform: translateY(-3px);
box-shadow: 0 3px 0 var(--color-card-shadow);
}
.footer-social-link svg {
width: 18px;
height: 18px;
}
.footer-links-title {
font-family: var(--font-comic);
font-size: 18px;
margin-bottom: 16px;
position: relative;
display: inline-block;
}
.footer-links-title::after {
content: '';
position: absolute;
bottom: -3px;
left: 0;
width: 100%;
height: 3px;
background-color: var(--color-highlight);
z-index: -1;
}
.footer-links-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 8px;
}
.footer-link {
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s;
}
.footer-link:hover {
transform: translateX(5px);
color: var(--color-accent);
}
.footer-link svg {
width: 16px;
height: 16px;
}
.footer-bottom {
margin-top: 40px;
padding-top: 20px;
border-top: 1px dashed var(--color-border);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 12px;
}
@media (min-width: 768px) {
.footer-bottom {
flex-direction: row;
justify-content: space-between;
text-align: left;
}
}
.footer-copyright {
color: var(--color-foreground-muted);
font-size: 14px;
}
.footer-bottom-links {
display: flex;
gap: 16px;
}
.footer-bottom-link {
font-size: 14px;
color: var(--color-foreground-muted);
transition: all 0.2s;
}
.footer-bottom-link:hover {
color: var(--color-foreground);
text-decoration: underline;
}
/* 漫画风格装饰 */
.comic-dots {
background-image: var(--pattern-dots);
}
.comic-lines {
background-image: var(--pattern-lines);
}
.comic-zigzag {
background-image: var(--pattern-zigzag);
}
.comic-burst {
position: relative;
}
.comic-burst::before {
content: '';
position: absolute;
top: -10px;
right: -10px;
width: 60px;
height: 60px;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M50 0 L60 40 L100 50 L60 60 L50 100 L40 60 L0 50 L40 40 Z' fill='%23ffff00' stroke='%23000000' stroke-width='3'/%3E%3C/svg%3E");
background-size: contain;
background-repeat: no-repeat;
transform: rotate(15deg);
z-index: 1;
}
.comic-burst-text {
position: absolute;
top: 5px;
right: 5px;
font-family: var(--font-comic);
font-size: 12px;
transform: rotate(15deg);
z-index: 2;
}
/* 动画效果 */
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
.shake {
animation: shake 0.5s;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.bounce {
animation: bounce 0.5s;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.spin {
animation: spin 1s linear infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(-15deg); }
50% { transform: translateY(-10px) rotate(-12deg); }
}
.float {
animation: float 3s ease-in-out infinite;
}
/* 速度线效果 */
.speed-lines {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
z-index: 0;
opacity: 0.1;
}
.speed-line {
position: absolute;
height: 100%;
width: 1px;
background-color: var(--color-accent);
transform: skewX(-20deg);
}
.speed-line:nth-child(1) { left: 10%; }
.speed-line:nth-child(2) { left: 20%; }
.speed-line:nth-child(3) { left: 30%; }
.speed-line:nth-child(4) { left: 40%; }
.speed-line:nth-child(5) { left: 50%; }
.speed-line:nth-child(6) { left: 60%; }
.speed-line:nth-child(7) { left: 70%; }
.speed-line:nth-child(8) { left: 80%; }
.speed-line:nth-child(9) { left: 90%; }
/* 页面过渡动画 */
.page-transition {
transition: opacity 0.3s ease, transform 0.3s ease;
}
.page-transition.fade-out {
opacity: 0;
transform: translateY(10px);
}
.page-transition.fade-in {
opacity: 1;
transform: translateY(0);
}
</style>
<div class="app-container">
<!-- 顶部导航栏 -->
<header class="header">
<div class="container header-content">
<div class="logo-container">
<div class="logo-icon">
<i data-lucide="zap"></i>
</div>
<div>
<h1 class="logo-title comic-title">漫画风工具箱</h1>
<p class="logo-subtitle">多功能工具集合</p>
</div>
</div>
<div class="header-actions">
<div class="search-container">
<i data-lucide="search" class="search-icon"></i>
<input type="text" placeholder="搜索工具..." class="search-input comic-input" id="search-input">
</div>
<button class="theme-toggle" id="theme-toggle" aria-label="切换主题">
<i data-lucide="sun" class="sun-icon"></i>
<i data-lucide="moon" class="moon-icon"></i>
</button>
<div class="dropdown">
<button class="icon-button dropdown-trigger">
<i data-lucide="settings"></i>
</button>
<div class="dropdown-content">
<a href="#" class="dropdown-item">
<i data-lucide="info"></i> 关于我们
</a>
<a href="#" class="dropdown-item">
<i data-lucide="settings"></i> 设置
</a>
<a href="#" class="dropdown-item" id="clear-data">
<i data-lucide="trash-2"></i> 清除数据
</a>
</div>
</div>
</div>
<button class="menu-button" id="menu-toggle">
<i data-lucide="menu"></i>
</button>
</div>
</header>
<div class="container main-content">
<!-- 左侧边栏 -->
<aside class="sidebar" id="sidebar">
<div class="sidebar-content">
<!-- 主导航 -->
<nav class="main-nav">
<button class="nav-button" data-page="home-page">
<i data-lucide="home"></i> 首页
</button>
<button class="nav-button" data-page="popular-tools-page">
<i data-lucide="star"></i> 热门工具
</button>
<button class="nav-button" data-page="favorite-tools-page">
<i data-lucide="heart"></i> 收藏工具
</button>
<button class="nav-button" data-page="recent-tools-page">
<i data-lucide="clock"></i> 最近使用
</button>
</nav>
<!-- 工具分类 -->
<div class="category-nav">
<h3 class="category-title">工具分类</h3>
<div class="category-buttons">
<button class="nav-button" data-page="category-page" data-category="image">
<i data-lucide="image"></i> 图片工具
</button>
<button class="nav-button" data-page="category-page" data-category="text">
<i data-lucide="file-text"></i> 文本工具
</button>
<button class="nav-button" data-page="category-page" data-category="video">
<i data-lucide="film"></i> 视频工具
</button>
<button class="nav-button" data-page="category-page" data-category="audio">
<i data-lucide="music"></i> 音频工具
</button>
<button class="nav-button" data-page="category-page" data-category="dev">
<i data-lucide="code"></i> 开发工具
</button>
<button class="nav-button" data-page="category-page" data-category="utility">
<i data-lucide="tool"></i> 实用工具
</button>
</div>
</div>
<!-- 页脚 -->
<div class="sidebar-footer">
<p>© 漫画风工具箱 2025</p>
<div class="footer-links">
<a href="#">提交工具</a>
<a href="#">关于我们</a>
</div>
</div>
</div>
</aside>
<!-- 主内容区 -->
<main class="main">
<!-- 面包屑导航 -->
<div class="breadcrumb" id="breadcrumb">
首页
</div>
<!-- 首页 -->
<div id="home-page" class="page-container active page-transition">
<!-- 英雄区域 -->
<section class="hero-section">
<div class="hero-background"></div>
<div class="speed-lines">
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
<div class="speed-line"></div>
</div>
<div class="hero-decoration top-left float">超级工具</div>
<div class="hero-decoration bottom-right float">一站式解决</div>
<div class="hero-content">
<h1 class="hero-title">漫画风工具箱</h1>
<p class="hero-subtitle">一站式在线工具集合,提供100+种实用工具,满足您的各种需求。无需安装,随时随地使用!</p>
<div class="hero-buttons">
<button class="hero-button" id="explore-tools">
<i data-lucide="search"></i> 探索工具
</button>
<button class="hero-button secondary" id="popular-tools">
<i data-lucide="star"></i> 热门工具
</button>
</div>
</div>
</section>
<!-- 特色工具 -->
<section class="featured-tools">
<div class="section-title-container">
<h2 class="section-title">特色工具</h2>
<div class="section-line"></div>
</div>
<div class="tools-grid" id="featured-tools-grid">
<!-- 工具卡片将通过JavaScript动态加载 -->
</div>
</section>
<!-- 工具分类 -->
<section class="categories-section">
<div class="section-title-container">
<h2 class="section-title">工具分类</h2>
<div class="section-line"></div>
</div>
<div class="categories-grid">
<div class="category-card" data-category="image">
<div class="category-card-icon">
<i data-lucide="image"></i>
</div>
<h3 class="category-card-title">图片工具</h3>
<p class="category-card-count">15+ 工具</p>
</div>
<div class="category-card" data-category="text">
<div class="category-card-icon">
<i data-lucide="file-text"></i>
</div>
<h3 class="category-card-title">文本工具</h3>
<p class="category-card-count">12+ 工具</p>
</div>
<div class="category-card" data-category="video">
<div class="category-card-icon">
<i data-lucide="film"></i>
</div>
<h3 class="category-card-title">视频工具</h3>
<p class="category-card-count">8+ 工具</p>
</div>
<div class="category-card" data-category="audio">
<div class="category-card-icon">
<i data-lucide="music"></i>
</div>
<h3 class="category-card-title">音频工具</h3>
<p class="category-card-count">10+ 工具</p>
</div>
<div class="category-card" data-category="dev">
<div class="category-card-icon">
<i data-lucide="code"></i>
</div>
<h3 class="category-card-title">开发工具</h3>
<p class="category-card-count">20+ 工具</p>
</div>
<div class="category-card" data-category="utility">
<div class="category-card-icon">
<i data-lucide="tool"></i>
</div>
<h3 class="category-card-title">实用工具</h3>
<p class="category-card-count">25+ 工具</p>
</div>
</div>
</section>
<!-- 统计数据 -->
<section class="stats-section">
<div class="section-title-container">
<h2 class="section-title">统计数据</h2>
<div class="section-line"></div>
</div>
<div class="stats-container">
<div class="stat-card">
<div class="stat-value">100+</div>
<div class="stat-label">可用工具</div>
</div>
<div class="stat-card">
<div class="stat-value">10K+</div>
<div class="stat-label">每日用户</div>
</div>
<div class="stat-card">
<div class="stat-value">500K+</div>
<div class="stat-label">每月转换</div>
</div>
<div class="stat-card">
<div class="stat-value">98%</div>
<div class="stat-label">用户满意度</div>
</div>
</div>
</section>
<!-- 用户评价 -->
<section class="testimonials-section">
<div class="section-title-container">
<h2 class="section-title">用户评价</h2>
<div class="section-line"></div>
</div>
<div class="testimonials-container">
<div class="testimonial-card">
<div class="testimonial-content">
这个工具箱太棒了!我经常需要转换图片格式,这里的工具简单易用,而且完全免费。黑白漫画风格的界面也很有特色,让人眼前一亮。
</div>
<div class="testimonial-author">
<div class="testimonial-avatar">
<i data-lucide="user"></i>
</div>
<div class="testimonial-info">
<div class="testimonial-name">张小明</div>
<div class="testimonial-role">设计师</div>
</div>
</div>
</div>
<div class="testimonial-card">
<div class="testimonial-content">
作为一名开发者,我经常需要格式化JSON数据。这个工具箱的JSON格式化工具非常好用,而且还有很多其他实用工具。深色模式也很贴心!
</div>
<div class="testimonial-author">
<div class="testimonial-avatar">
<i data-lucide="user"></i>
</div>
<div class="testimonial-info">
<div class="testimonial-name">李程序</div>
<div class="testimonial-role">前端开发者</div>
</div>
</div>
</div>
<div class="testimonial-card">
<div class="testimonial-content">
密码生成器和二维码生成器是我最常用的两个工具。界面简洁明了,操作也很简单。最重要的是不需要安装任何软件,直接在浏览器中就能使用。
</div>
<div class="testimonial-author">
<div class="testimonial-avatar">
<i data-lucide="user"></i>
</div>
<div class="testimonial-info">
<div class="testimonial-name">王安全</div>
<div class="testimonial-role">IT管理员</div>
</div>
</div>
</div>
<div class="testimonial-card">
<div class="testimonial-content">
我喜欢这个工具箱的漫画风格设计,非常有趣!而且工具种类齐全,几乎涵盖了我所有的需求。单位转换工具对我的工作特别有帮助。
</div>
<div class="testimonial-author">
<div class="testimonial-avatar">
<i data-lucide="user"></i>
</div>
<div class="testimonial-info">
<div class="testimonial-name">赵工程</div>
<div class="testimonial-role">工程师</div>
</div>
</div>
</div>
</div>
</section>
<!-- 最新工具 -->
<div class="bottom-sections">
<section class="info-section">
<div class="section-header">
<h2 class="section-title">最新工具</h2>
</div>
<div class="section-content">
<ul class="tool-list">
<li class="tool-list-item">
<div class="tool-indicator"></div>
<span>二维码生成器</span>
<div class="tool-meta">
<span class="tool-date">2025-05-10</span>
<span class="tool-tag">新功能</span>
</div>
</li>
<li class="tool-list-item">
<div class="tool-indicator"></div>
<span>密码生成器</span>
<div class="tool-meta">
<span class="tool-date">2025-05-08</span>
<span class="tool-tag">新功能</span>
</div>
</li>
<li class="tool-list-item">
<div class="tool-indicator"></div>
<span>颜色选择器</span>
<div class="tool-meta">
<span class="tool-date">2025-05-05</span>
<span class="tool-tag">更新</span>
</div>
</li>
<li class="tool-list-item">
<div class="tool-indicator"></div>
<span>单位转换工具</span>
<div class="tool-meta">
<span class="tool-date">2025-05-01</span>
<span class="tool-tag">新功能</span>
</div>
</li>
</ul>
</div>
</section>
<!-- 统计数据 -->
<section class="info-section">
<div class="section-header">
<h2 class="section-title">统计数据</h2>
</div>
<div class="section-content">
<div class="stats-grid">
<div class="stat-card">
<h3 class="stat-value">100+</h3>
<p class="stat-label">可用工具</p>
</div>
<div class="stat-card">
<h3 class="stat-value">10K+</h3>
<p class="stat-label">每日用户</p>
</div>
</div>
<div class="progress-stats">
<div class="progress-item">
<div class="progress-header">
<span class="progress-label">免费工具</span>
<span class="progress-value">85%</span>
</div>
<div class="progress-bar">
<div class="progress-fill" style="width: 85%;"></div>
</div>
</div>
<div class="progress-item">
<div class="progress-header">
<span class="progress-label">每日转换</span>
<span class="progress-value">50,000+</span>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-green" style="width: 70%;"></div>
</div>
</div>
<div class="progress-item">
<div class="progress-header">
<span class="progress-label">用户满意度</span>
<span class="progress-value">98%</span>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-yellow" style="width: 98%;"></div>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
<!-- 热门工具页面 -->
<div id="popular-tools-page" class="page-container page-transition">
<div class="section-title-container">
<h2 class="section-title">热门工具</h2>
<div class="section-line"></div>
</div>
<p class="section-description">这些是我们用户最常使用的工具,快来试试吧!</p>
<div class="popular-tools-grid" id="popular-tools-grid">
<!-- 工具卡片将通过JavaScript动态加载 -->
</div>
</div>
<!-- 收藏工具页面 -->
<div id="favorite-tools-page" class="page-container page-transition">
<div class="section-title-container">
<h2 class="section-title">收藏工具</h2>
<div class="section-line"></div>
</div>
<p class="section-description">这里是您收藏的工具,方便您快速访问。</p>
<div class="favorite-tools-grid" id="favorite-tools-grid">
<!-- 收藏的工具卡片将通过JavaScript动态加载 -->
</div>
</div>
<!-- 最近使用页面 -->
<div id="recent-tools-page" class="page-container page-transition">
<div class="section-title-container">
<h2 class="section-title">最近使用</h2>
<div class="section-line"></div>
</div>
<p class="section-description">这里记录了您最近使用过的工具,方便您快速访问。</p>
<div class="recent-tools-list" id="recent-tools-list">
<!-- 最近使用的工具将通过JavaScript动态加载 -->
</div>
</div>
<!-- 分类页面 -->
<div id="category-page" class="page-container page-transition">
<div class="category-header">
<h2 class="category-header-title" id="category-title">图片工具</h2>
<p class="category-header-description" id="category-description">各种图片处理工具,满足您的图片编辑需求。</p>
</div>
<div class="tools-grid" id="category-tools-grid">
<!-- 工具卡片将通过JavaScript动态加载 -->
</div>
</div>
<!-- 工具详情页面 -->
<div id="tool-detail-page" class="page-container page-transition">
<div class="tool-detail-header">
<h2 class="tool-detail-title" id="tool-detail-title">图片格式转换</h2>
<p class="tool-detail-description" id="tool-detail-description">支持多种格式互转,快速简便,保持图片质量。</p>
<div class="tool-detail-actions">
<button class="tool-detail-button favorite" id="detail-favorite-button">
<i data-lucide="heart"></i> 收藏工具
</button>
<button class="tool-detail-button secondary">
<i data-lucide="share"></i> 分享工具
</button>
</div>
</div>
<div class="tool-detail-content" id="tool-detail-content">
<!-- 工具内容将通过JavaScript动态加载 -->
</div>
</div>
</main>
</div>
<!-- 通知 -->
<div class="notification" id="notification">
<div class="notification-icon">
<i data-lucide="info"></i>
</div>
<div class="notification-content">
<div class="notification-title" id="notification-title">通知标题</div>
<div class="notification-message" id="notification-message">通知内容</div>
</div>
<div class="notification-close" id="notification-close">
<i data-lucide="x"></i>
</div>
</div>
<!-- 页脚 -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-info">
<div class="footer-logo">
<div class="footer-logo-icon">
<i data-lucide="zap"></i>
</div>
<div class="footer-logo-text">漫画风工具箱</div>
</div>
<p class="footer-description">
一站式在线工具集合,提供100+种实用工具,满足您的各种需求。无需安装,随时随地使用!
</p>
<div class="footer-social">
<a href="#" class="footer-social-link">
<i data-lucide="github"></i>
</a>
<a href="#" class="footer-social-link">
<i data-lucide="twitter"></i>
</a>
<a href="#" class="footer-social-link">
<i data-lucide="instagram"></i>
</a>
<a href="#" class="footer-social-link">
<i data-lucide="facebook"></i>
</a>
</div>
</div>
<div class="footer-links">
<h3 class="footer-links-title">快速链接</h3>
<ul class="footer-links-list">
<li><a href="#" class="footer-link"><i data-lucide="home"></i> 首页</a></li>
<li><a href="#" class="footer-link"><i data-lucide="tool"></i> 所有工具</a></li>
<li><a href="#" class="footer-link"><i data-lucide="star"></i> 热门工具</a></li>
<li><a href="#" class="footer-link"><i data-lucide="clock"></i> 最近更新</a></li>
<li><a href="#" class="footer-link"><i data-lucide="help-circle"></i> 帮助中心</a></li>
</ul>
</div>
<div class="footer-links">
<h3 class="footer-links-title">联系我们</h3>
<ul class="footer-links-list">
<li><a href="#" class="footer-link"><i data-lucide="mail"></i> 联系我们</a></li>
<li><a href="#" class="footer-link"><i data-lucide="info"></i> 关于我们</a></li>
<li><a href="#" class="footer-link"><i data-lucide="message-square"></i> 反馈建议</a></li>
<li><a href="#" class="footer-link"><i data-lucide="plus-circle"></i> 提交工具</a></li>
<li><a href="#" class="footer-link"><i data-lucide="heart"></i> 支持我们</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div class="footer-copyright">
© 2025 漫画风工具箱 版权所有
</div>
<div class="footer-bottom-links">
<a href="#" class="footer-bottom-link">隐私政策</a>
<a href="#" class="footer-bottom-link">使用条款</a>
<a href="#" class="footer-bottom-link">Cookie政策</a>
</div>
</div>
</div>
</footer>
</div>
<script src="https://unpkg.com/lucide@latest"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
// 初始化Lucide图标
lucide.createIcons();
// 工具数据
const toolsData = {
"image": [
{ id: "image-converter", name: "图片格式转换", description: "支持多种格式互转,快速简便,保持图片质量", icon: "image" },
{ id: "image-compressor", name: "图片压缩", description: "减小图片文件大小,保持图片质量", icon: "image-minus" },
{ id: "image-cropper", name: "图片裁剪", description: "调整图片尺寸和比例", icon: "scissors" },
{ id: "image-filter", name: "图片滤镜", description: "为图片添加各种滤镜效果", icon: "palette" },
{ id: "image-watermark", name: "图片水印", description: "为图片添加文字或图片水印", icon: "stamp" },
{ id: "image-background-remover", name: "背景移除", description: "自动移除图片背景", icon: "eraser" }
],
"text": [
{ id: "text-translator", name: "文本翻译", description: "多语言文本翻译工具,支持多种语言互译", icon: "file-text" },
{ id: "text-diff", name: "文本对比", description: "比较两段文本的差异", icon: "git-compare" },
{ id: "text-counter", name: "字数统计", description: "统计文本字数和行数", icon: "list-checks" },
{ id: "text-case-converter", name: "大小写转换", description: "文本大小写转换工具", icon: "type" },
{ id: "text-encoder", name: "文本编码", description: "支持多种编码格式转换", icon: "code" }
],
"video": [
{ id: "video-to-gif", name: "视频转GIF", description: "将视频转换为GIF动图", icon: "film" },
{ id: "video-compressor", name: "视频压缩", description: "减小视频文件大小", icon: "film" },
{ id: "video-trimmer", name: "视频剪辑", description: "简单的视频剪辑工具", icon: "scissors" },
{ id: "video-converter", name: "视频格式转换", description: "支持多种视频格式互转", icon: "film" }
],
"audio": [
{ id: "audio-converter", name: "音频格式转换", description: "转换音频文件格式", icon: "music" },
{ id: "audio-trimmer", name: "音频剪辑", description: "剪辑和编辑音频文件", icon: "scissors" },
{ id: "audio-to-text", name: "语音转文字", description: "将语音内容转换为文本", icon: "mic" },
{ id: "audio-mixer", name: "音频混合", description: "混合多个音频文件", icon: "layers" }
],
"dev": [
{ id: "json-formatter", name: "JSON格式化", description: "格式化和验证JSON数据", icon: "code" },
{ id: "code-beautifier", name: "代码美化", description: "美化HTML/CSS/JS代码", icon: "code" },
{ id: "regex-tester", name: "正则测试", description: "测试和验证正则表达式", icon: "code" },
{ id: "html-minifier", name: "HTML压缩", description: "压缩HTML代码,减小文件大小", icon: "code" },
{ id: "css-minifier", name: "CSS压缩", description: "压缩CSS代码,减小文件大小", icon: "code" },
{ id: "js-minifier", name: "JS压缩", description: "压缩JavaScript代码,减小文件大小", icon: "code" }
],
"utility": [
{ id: "qr-generator", name: "二维码生成器", description: "快速生成自定义二维码", icon: "qr-code" },
{ id: "password-generator", name: "密码生成器", description: "生成安全、强壮的随机密码", icon: "key" },
{ id: "color-picker", name: "颜色选择器", description: "选择、转换和复制颜色代码", icon: "palette" },
{ id: "unit-converter", name: "单位转换工具", description: "支持多种单位互转", icon: "ruler" },
{ id: "timer", name: "计时器", description: "简单易用的计时器和倒计时工具", icon: "timer" },
{ id: "calculator", name: "计算器", description: "功能强大的在线计算器", icon: "calculator" }
]
};
// 热门工具数据
const popularTools = [
{ id: "image-converter", category: "image" },
{ id: "text-translator", category: "text" },
{ id: "json-formatter", category: "dev" },
{ id: "qr-generator", category: "utility" },
{ id: "password-generator", category: "utility" },
{ id: "color-picker", category: "utility" },
{ id: "video-to-gif", category: "video" },
{ id: "audio-converter", category: "audio" }
];
// 特色工具数据
const featuredTools = [
{ id: "image-converter", category: "image" },
{ id: "text-translator", category: "text" },
{ id: "json-formatter", category: "dev" },
{ id: "qr-generator", category: "utility" },
{ id: "password-generator", category: "utility" },
{ id: "color-picker", category: "utility" }
];
// 本地存储键
const STORAGE_KEYS = {
FAVORITES: 'toolbox_favorites',
HISTORY: 'toolbox_history',
THEME: 'theme'
};
// 数据管理
const dataManager = {
// 获取收藏工具
getFavorites() {
const favorites = localStorage.getItem(STORAGE_KEYS.FAVORITES);
return favorites ? JSON.parse(favorites) : [];
},
// 添加收藏
addFavorite(toolId) {
const favorites = this.getFavorites();
if (!favorites.includes(toolId)) {
favorites.push(toolId);
localStorage.setItem(STORAGE_KEYS.FAVORITES, JSON.stringify(favorites));
return true;
}
return false;
},
// 移除收藏
removeFavorite(toolId) {
const favorites = this.getFavorites();
const index = favorites.indexOf(toolId);
if (index !== -1) {
favorites.splice(index, 1);
localStorage.setItem(STORAGE_KEYS.FAVORITES, JSON.stringify(favorites));
return true;
}
return false;
},
// 检查是否收藏
isFavorite(toolId) {
const favorites = this.getFavorites();
return favorites.includes(toolId);
},
// 获取使用历史
getHistory() {
const history = localStorage.getItem(STORAGE_KEYS.HISTORY);
return history ? JSON.parse(history) : [];
},
// 添加使用记录
addToHistory(toolId) {
const history = this.getHistory();
// 检查是否已存在
const existingIndex = history.findIndex(item => item.id === toolId);
// 当前时间
const now = new Date();
if (existingIndex !== -1) {
// 更新现有记录
history[existingIndex].lastUsed = now.toISOString();
history[existingIndex].useCount = (history[existingIndex].useCount || 0) + 1;
} else {
// 添加新记录
history.push({
id: toolId,
lastUsed: now.toISOString(),
useCount: 1
});
}
// 按最近使用时间排序
history.sort((a, b) => new Date(b.lastUsed) - new Date(a.lastUsed));
// 只保留最近的20条记录
const trimmedHistory = history.slice(0, 20);
localStorage.setItem(STORAGE_KEYS.HISTORY, JSON.stringify(trimmedHistory));
return true;
},
// 清除所有数据
clearAllData() {
localStorage.removeItem(STORAGE_KEYS.FAVORITES);
localStorage.removeItem(STORAGE_KEYS.HISTORY);
return true;
}
};
// 主题切换功能
const themeToggle = document.getElementById("theme-toggle");
const htmlElement = document.documentElement;
// 检查本地存储中的主题偏好
const savedTheme = localStorage.getItem(STORAGE_KEYS.THEME);
if (savedTheme) {
htmlElement.className = savedTheme;
} else {
// 检查系统偏好
const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
htmlElement.className = prefersDarkMode ? "dark-theme" : "light-theme";
}
// 主题切换按钮点击事件
themeToggle.addEventListener("click", () => {
if (htmlElement.classList.contains("light-theme")) {
htmlElement.classList.remove("light-theme");
htmlElement.classList.add("dark-theme");
localStorage.setItem(STORAGE_KEYS.THEME, "dark-theme");
} else {
htmlElement.classList.remove("dark-theme");
htmlElement.classList.add("light-theme");
localStorage.setItem(STORAGE_KEYS.THEME, "light-theme");
}
});
// 菜单切换
const menuToggle = document.getElementById("menu-toggle");
const sidebar = document.getElementById("sidebar");
menuToggle.addEventListener("click", () => {
sidebar.classList.toggle("open");
});
// 初始化下拉菜单
document.querySelectorAll(".dropdown-trigger").forEach((trigger) => {
trigger.addEventListener("click", function () {
this.closest(".dropdown").classList.toggle("active");
});
});
// 点击外部关闭下拉菜单
document.addEventListener("click", (event) => {
if (!event.target.closest(".dropdown")) {
document.querySelectorAll(".dropdown.active").forEach((dropdown) => {
dropdown.classList.remove("active");
});
}
});
// 通知功能
const notification = document.getElementById("notification");
const notificationTitle = document.getElementById("notification-title");
const notificationMessage = document.getElementById("notification-message");
const notificationClose = document.getElementById("notification-close");
// 显示通知
function showNotification(title, message, duration = 3000) {
notificationTitle.textContent = title;
notificationMessage.textContent = message;
notification.classList.add("show");
// 更新图标
const iconElement = notification.querySelector(".notification-icon i");
if (iconElement) {
iconElement.setAttribute("data-lucide", title.toLowerCase().includes("错误") ? "alert-circle" : "check-circle");
lucide.createIcons();
}
// 自动关闭
setTimeout(() => {
notification.classList.remove("show");
}, duration);
}
// 关闭通知
notificationClose.addEventListener("click", () => {
notification.classList.remove("show");
});
// 页面导航功能
const pages = document.querySelectorAll(".page-container");
const navButtons = document.querySelectorAll(".nav-button");
const breadcrumb = document.getElementById("breadcrumb");
// 设置当前活跃页面
function setActivePage(pageId, categoryId = null, toolId = null) {
// 添加过渡动画
pages.forEach(page => {
if (page.classList.contains("active")) {
page.classList.add("fade-out");
setTimeout(() => {
page.classList.remove("active");
page.classList.remove("fade-out");
// 显示目标页面
const targetPage = document.getElementById(pageId);
if (targetPage) {
targetPage.classList.add("active");
targetPage.classList.add("fade-in");
setTimeout(() => {
targetPage.classList.remove("fade-in");
}, 300);
}
}, 300);
}
});
// 如果没有活跃页面,直接显示目标页面
if (!document.querySelector(".page-container.active")) {
const targetPage = document.getElementById(pageId);
if (targetPage) {
targetPage.classList.add("active");
targetPage.classList.add("fade-in");
setTimeout(() => {
targetPage.classList.remove("fade-in");
}, 300);
}
}
// 更新导航按钮状态
navButtons.forEach(button => {
button.classList.remove("active");
if (button.dataset.page === pageId) {
if (!categoryId || !button.dataset.category || button.dataset.category === categoryId) {
button.classList.add("active");
}
}
});
// 更新面包屑导航
updateBreadcrumb(pageId, categoryId, toolId);
// 如果是分类页面,加载对应分类的工具
if (pageId === "category-page" && categoryId) {
loadCategoryTools(categoryId);
}
// 如果是工具详情页面,加载工具详情
if (pageId === "tool-detail-page" && toolId) {
loadToolDetail(toolId);
}
// 如果是收藏工具页面,加载收藏的工具
if (pageId === "favorite-tools-page") {
loadFavoriteTools();
}
// 如果是最近使用页面,加载最近使用的工具
if (pageId === "recent-tools-page") {
loadRecentTools();
}
// 如果是热门工具页面,加载热门工具
if (pageId === "popular-tools-page") {
loadPopularTools();
}
// 如果是首页,加载特色工具
if (pageId === "home-page") {
loadFeaturedTools();
}
// 如果是移动设备,点击后关闭侧边栏
if (window.innerWidth < 768) {
sidebar.classList.remove("open");
}
}
// 更新面包屑导航
function updateBreadcrumb(pageId, categoryId = null, toolId = null) {
let breadcrumbText = "";
switch (pageId) {
case "home-page":
breadcrumbText = "首页";
break;
case "popular-tools-page":
breadcrumbText = "首页 / 热门工具";
break;
case "favorite-tools-page":
breadcrumbText = "首页 / 收藏工具";
break;
case "recent-tools-page":
breadcrumbText = "首页 / 最近使用";
break;
case "category-page":
const categoryName = getCategoryName(categoryId);
breadcrumbText = `首页 / ${categoryName}`;
break;
case "tool-detail-page":
if (toolId) {
const toolInfo = getToolInfo(toolId);
if (toolInfo) {
const categoryName = getCategoryName(getToolCategory(toolId));
breadcrumbText = `首页 / ${categoryName} / ${toolInfo.name}`;
} else {
breadcrumbText = "首页 / 工具详情";
}
} else {
breadcrumbText = "首页 / 工具详情";
}
break;
default:
breadcrumbText = "首页";
}
breadcrumb.textContent = breadcrumbText;
}
// 获取分类名称
function getCategoryName(categoryId) {
const categoryMap = {
"image": "图片工具",
"text": "文本工具",
"video": "视频工具",
"audio": "音频工具",
"dev": "开发工具",
"utility": "实用工具"
};
return categoryMap[categoryId] || "工具分类";
}
// 获取分类描述
function getCategoryDescription(categoryId) {
const descriptionMap = {
"image": "各种图片处理工具,满足您的图片编辑需求。",
"text": "文本处理工具集合,帮助您高效处理各种文本内容。",
"video": "视频编辑和转换工具,让视频处理变得简单。",
"audio": "音频处理工具,支持格式转换、剪辑等功能。",
"dev": "为开发者提供的实用工具,提高开发效率。",
"utility": "日常实用工具集合,满足各种日常需求。"
};
return descriptionMap[categoryId] || "各种实用工具集合";
}
// 获取工具所属分类
function getToolCategory(toolId) {
for (const category in toolsData) {
const tool = toolsData[category].find(t => t.id === toolId);
if (tool) {
return category;
}
}
return null;
}
// 加载分类工具
function loadCategoryTools(categoryId) {
const categoryTitle = document.getElementById("category-title");
const categoryDescription = document.getElementById("category-description");
const categoryToolsGrid = document.getElementById("category-tools-grid");
// 更新分类标题和描述
categoryTitle.textContent = getCategoryName(categoryId);
categoryDescription.textContent = getCategoryDescription(categoryId);
// 清空工具网格
categoryToolsGrid.innerHTML = "";
// 根据分类加载工具
const tools = toolsData[categoryId] || [];
// 添加工具卡片
tools.forEach(tool => {
const isFavorite = dataManager.isFavorite(tool.id);
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = tool.id;
toolCard.innerHTML = `
<button class="favorite-button ${isFavorite ? 'active' : ''}" data-tool="${tool.id}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${tool.icon}"></i>
</div>
<h3 class="tool-card-title">${tool.name}</h3>
<p class="tool-card-description">${tool.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(tool.id);
setActivePage("tool-detail-page", null, tool.id);
// 添加使用记录
dataManager.addToHistory(tool.id);
}
});
categoryToolsGrid.appendChild(toolCard);
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 加载热门工具
function loadPopularTools() {
const popularToolsGrid = document.getElementById("popular-tools-grid");
// 清空工具网格
popularToolsGrid.innerHTML = "";
// 加载热门工具
popularTools.forEach(popularTool => {
const category = popularTool.category;
const toolId = popularTool.id;
// 查找工具信息
const tool = toolsData[category].find(t => t.id === toolId);
if (tool) {
const isFavorite = dataManager.isFavorite(tool.id);
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = tool.id;
toolCard.innerHTML = `
<button class="favorite-button ${isFavorite ? 'active' : ''}" data-tool="${tool.id}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${tool.icon}"></i>
</div>
<h3 class="tool-card-title">${tool.name}</h3>
<p class="tool-card-description">${tool.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(tool.id);
setActivePage("tool-detail-page", null, tool.id);
// 添加使用记录
dataManager.addToHistory(tool.id);
}
});
popularToolsGrid.appendChild(toolCard);
}
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 加载特色工具
function loadFeaturedTools() {
const featuredToolsGrid = document.getElementById("featured-tools-grid");
// 清空工具网格
featuredToolsGrid.innerHTML = "";
// 加载特色工具
featuredTools.forEach(featuredTool => {
const category = featuredTool.category;
const toolId = featuredTool.id;
// 查找工具信息
const tool = toolsData[category].find(t => t.id === toolId);
if (tool) {
const isFavorite = dataManager.isFavorite(tool.id);
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = tool.id;
toolCard.innerHTML = `
<button class="favorite-button ${isFavorite ? 'active' : ''}" data-tool="${tool.id}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${tool.icon}"></i>
</div>
<h3 class="tool-card-title">${tool.name}</h3>
<p class="tool-card-description">${tool.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(tool.id);
setActivePage("tool-detail-page", null, tool.id);
// 添加使用记录
dataManager.addToHistory(tool.id);
}
});
featuredToolsGrid.appendChild(toolCard);
}
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 加载收藏工具
function loadFavoriteTools() {
const favoriteToolsGrid = document.getElementById("favorite-tools-grid");
// 清空工具网格
favoriteToolsGrid.innerHTML = "";
// 获取收藏的工具
const favorites = dataManager.getFavorites();
if (favorites.length === 0) {
// 显示无收藏提示
favoriteToolsGrid.innerHTML = `
<div class="no-favorites">
<div class="no-favorites-icon">
<i data-lucide="heart-off"></i>
</div>
<h3 class="no-favorites-title">暂无收藏工具</h3>
<p class="no-favorites-text">您还没有收藏任何工具,浏览工具时点击心形图标即可收藏。</p>
<button class="comic-button" id="browse-tools-button">
<i data-lucide="search"></i> 浏览工具
</button>
</div>
`;
// 浏览工具按钮点击事件
const browseToolsButton = document.getElementById("browse-tools-button");
if (browseToolsButton) {
browseToolsButton.addEventListener("click", () => {
setActivePage("popular-tools-page");
});
}
// 重新初始化图标
lucide.createIcons();
return;
}
// 加载收藏的工具
favorites.forEach(toolId => {
// 查找工具信息
const toolInfo = getToolInfo(toolId);
if (toolInfo) {
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = toolId;
toolCard.innerHTML = `
<button class="favorite-button active" data-tool="${toolId}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${toolInfo.icon}"></i>
</div>
<h3 class="tool-card-title">${toolInfo.name}</h3>
<p class="tool-card-description">${toolInfo.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(toolId);
setActivePage("tool-detail-page", null, toolId);
// 添加使用记录
dataManager.addToHistory(toolId);
}
});
favoriteToolsGrid.appendChild(toolCard);
}
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 加载最近使用的工具
function loadRecentTools() {
const recentToolsList = document.getElementById("recent-tools-list");
// 清空列表
recentToolsList.innerHTML = "";
// 获取使用历史
const history = dataManager.getHistory();
if (history.length === 0) {
// 显示无历史记录提示
recentToolsList.innerHTML = `
<div class="no-history">
<div class="no-history-icon">
<i data-lucide="clock"></i>
</div>
<h3 class="no-history-title">暂无使用记录</h3>
<p class="no-history-text">您还没有使用过任何工具,使用工具后会自动记录在这里。</p>
<button class="comic-button" id="explore-tools-button">
<i data-lucide="search"></i> 探索工具
</button>
</div>
`;
// 探索工具按钮点击事件
const exploreToolsButton = document.getElementById("explore-tools-button");
if (exploreToolsButton) {
exploreToolsButton.addEventListener("click", () => {
setActivePage("popular-tools-page");
});
}
// 重新初始化图标
lucide.createIcons();
return;
}
// 加载最近使用的工具
history.forEach(historyItem => {
const toolId = historyItem.id;
const lastUsed = new Date(historyItem.lastUsed);
const useCount = historyItem.useCount || 1;
// 查找工具信息
const toolInfo = getToolInfo(toolId);
if (toolInfo) {
const isFavorite = dataManager.isFavorite(toolId);
// 格式化最后使用时间
const formattedDate = formatDate(lastUsed);
const toolItem = document.createElement("div");
toolItem.className = "recent-tool-item";
toolItem.dataset.tool = toolId;
toolItem.innerHTML = `
<div class="recent-tool-icon">
<i data-lucide="${toolInfo.icon}"></i>
</div>
<div class="recent-tool-info">
<div class="recent-tool-title">${toolInfo.name}</div>
<div class="recent-tool-date">最近使用:${formattedDate} · 使用次数:${useCount}次</div>
</div>
<div class="recent-tool-actions">
<button class="recent-tool-button favorite ${isFavorite ? 'active' : ''}" data-tool="${toolId}">
<i data-lucide="heart"></i>
</button>
<button class="recent-tool-button open" data-tool="${toolId}">
<i data-lucide="external-link"></i>
</button>
</div>
`;
// 打开工具按钮点击事件
toolItem.querySelector('.open').addEventListener("click", () => {
loadToolDetail(toolId);
setActivePage("tool-detail-page", null, toolId);
// 添加使用记录
dataManager.addToHistory(toolId);
});
// 整个条目点击事件(除了按钮区域)
toolItem.addEventListener("click", (e) => {
// 如果点击的是按钮区域,不触发
if (!e.target.closest('.recent-tool-actions')) {
loadToolDetail(toolId);
setActivePage("tool-detail-page", null, toolId);
// 添加使用记录
dataManager.addToHistory(toolId);
}
});
recentToolsList.appendChild(toolItem);
}
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
}
// 格式化日期
function formatDate(date) {
const now = new Date();
const diff = now - date;
// 小于1分钟
if (diff < 60 * 1000) {
return "刚刚";
}
// 小于1小时
if (diff < 60 * 60 * 1000) {
const minutes = Math.floor(diff / (60 * 1000));
return `${minutes}分钟前`;
}
// 小于24小时
if (diff < 24 * 60 * 60 * 1000) {
const hours = Math.floor(diff / (60 * 60 * 1000));
return `${hours}小时前`;
}
// 小于7天
if (diff < 7 * 24 * 60 * 60 * 1000) {
const days = Math.floor(diff / (24 * 60 * 60 * 1000));
return `${days}天前`;
}
// 大于7天,显示具体日期
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
}
// 获取工具信息
function getToolInfo(toolId) {
for (const category in toolsData) {
const tool = toolsData[category].find(t => t.id === toolId);
if (tool) {
return tool;
}
}
return null;
}
// 加载工具详情
function loadToolDetail(toolId) {
const toolDetailTitle = document.getElementById("tool-detail-title");
const toolDetailDescription = document.getElementById("tool-detail-description");
const toolDetailContent = document.getElementById("tool-detail-content");
const detailFavoriteButton = document.getElementById("detail-favorite-button");
// 查找工具信息
const toolInfo = getToolInfo(toolId);
if (!toolInfo) {
toolDetailTitle.textContent = "工具不存在";
toolDetailDescription.textContent = "抱歉,您请求的工具不存在或已被移除。";
toolDetailContent.innerHTML = `
<div class="no-tool">
<div class="no-tool-icon">
<i data-lucide="alert-triangle"></i>
</div>
<h3 class="no-tool-title">工具不存在</h3>
<p class="no-tool-text">抱歉,您请求的工具不存在或已被移除。</p>
<button class="comic-button" id="back-to-home-button">
<i data-lucide="home"></i> 返回首页
</button>
</div>
`;
// 返回首页按钮点击事件
const backToHomeButton = document.getElementById("back-to-home-button");
if (backToHomeButton) {
backToHomeButton.addEventListener("click", () => {
setActivePage("home-page");
});
}
// 重新初始化图标
lucide.createIcons();
return;
}
// 更新工具详情
toolDetailTitle.textContent = toolInfo.name;
toolDetailDescription.textContent = toolInfo.description;
// 检查是否收藏
const isFavorite = dataManager.isFavorite(toolId);
// 更新收藏按钮状态
detailFavoriteButton.classList.toggle("active", isFavorite);
detailFavoriteButton.innerHTML = `
<i data-lucide="heart"></i> ${isFavorite ? '取消收藏' : '收藏工具'}
`;
// 收藏按钮点击事件
detailFavoriteButton.dataset.tool = toolId;
detailFavoriteButton.onclick = function() {
toggleFavorite(this);
};
// 加载工具内容
loadToolContent(toolId, toolDetailContent);
// 重新初始化图标
lucide.createIcons();
}
// 加载工具内容
function loadToolContent(toolId, container) {
// 这里根据工具ID加载对应的工具内容
// 在实际应用中,可能需要从服务器加载或使用预定义的模板
switch (toolId) {
case "image-converter":
container.innerHTML = `
<div class="tool-section image-converter">
<div class="conversion-steps">
<div class="steps-container">
<div class="step-item" id="step-upload">
<div class="step-icon">
<i data-lucide="check"></i>
</div>
<div class="step-line"></div>
</div>
<div class="step-item" id="step-convert">
<div class="step-icon">
<i data-lucide="refresh-cw"></i>
</div>
<div class="step-line"></div>
</div>
<div class="step-item" id="step-download">
<div class="step-icon">
<i data-lucide="download"></i>
</div>
</div>
</div>
<button class="reset-button" id="reset-conversion">
<i data-lucide="refresh-cw"></i> 重置
</button>
</div>
<div class="upload-area" id="upload-area">
<div class="upload-content">
<div class="upload-icon">
<i data-lucide="upload"></i>
</div>
<div class="upload-text">
<p class="upload-primary">拖放图片到这里,或点击上传</p>
<p class="upload-secondary">支持 JPG, PNG, WEBP, GIF, SVG 等格式</p>
</div>
<button class="comic-button">
选择文件
<input type="file" id="file-input" accept="image/*" class="file-input">
</button>
</div>
</div>
<div class="conversion-area" id="conversion-area" style="display: none;">
<div class="conversion-grid">
<div class="preview-container">
<div class="image-preview" id="image-preview">
<!-- 图片预览将在这里显示 -->
</div>
<div class="file-info" id="file-info">
<!-- 文件信息将在这里显示 -->
</div>
</div>
<div class="conversion-settings">
<div class="settings-group">
<div class="form-group">
<label class="form-label">转换为</label>
<select class="comic-input" id="format-select">
<option value="png">PNG</option>
<option value="jpg">JPG</option>
<option value="webp">WEBP</option>
<option value="gif">GIF</option>
<option value="svg">SVG</option>
</select>
</div>
<div class="form-group">
<div class="slider-header">
<label class="form-label">图片质量</label>
<span class="slider-value" id="quality-value">80%</span>
</div>
<input type="range" min="10" max="100" value="80" class="slider" id="quality-slider">
</div>
<div class="options-group">
<div class="option-item">
<input type="checkbox" id="maintain-ratio" class="checkbox">
<label for="maintain-ratio" class="checkbox-label">保持宽高比</label>
</div>
<div class="option-item">
<input type="checkbox" id="optimize" class="checkbox">
<label for="optimize" class="checkbox-label">优化大小</label>
</div>
</div>
</div>
<div class="conversion-progress" id="conversion-progress" style="display: none;">
<div class="progress-bar">
<div class="progress-fill" id="progress-bar-fill" style="width: 0%;"></div>
</div>
<p class="progress-text" id="progress-text">转换中... 0%</p>
</div>
<div class="conversion-success" id="conversion-success" style="display: none;">
<div class="success-message">
<i data-lucide="check"></i>
<span>转换完成!</span>
</div>
<button class="comic-button" id="download-button">
<i data-lucide="download"></i> 下载 <span id="download-format">PNG</span> 文件
</button>
</div>
<button class="comic-button" id="convert-button">
<i data-lucide="refresh-cw"></i> 开始转换
</button>
</div>
</div>
</div>
</div>
`;
// 初始化图片转换工具
initImageConverter();
break;
case "text-translator":
container.innerHTML = `
<div class="tool-section text-translator">
<div class="language-controls">
<div class="language-selector-group">
<select class="comic-input" id="source-language">
<option value="zh">中文</option>
<option value="en">英语</option>
<option value="ja">日语</option>
<option value="ko">韩语</option>
<option value="fr">法语</option>
<option value="de">德语</option>
<option value="es">西班牙语</option>
<option value="ru">俄语</option>
</select>
<button class="swap-button" id="swap-languages">
<i data-lucide="arrow-right"></i>
</button>
<select class="comic-input" id="target-language">
<option value="zh">中文</option>
<option value="en" selected>英语</option>
<option value="ja">日语</option>
<option value="ko">韩语</option>
<option value="fr">法语</option>
<option value="de">德语</option>
<option value="es">西班牙语</option>
<option value="ru">俄语</option>
</select>
</div>
<button class="comic-button" id="clear-text">
清空
</button>
</div>
<div class="translator-grid">
<div class="text-area-container">
<label class="text-area-label">输入文本</label>
<textarea class="comic-input" id="source-text" placeholder="请输入要翻译的文本..."></textarea>
<div class="text-area-footer">
<span class="character-count" id="source-count">0</span> 个字符
</div>
</div>
<div class="text-area-container">
<div class="text-area-header">
<label class="text-area-label">翻译结果</label>
<button class="copy-button" id="copy-result" style="display: none;">
<i data-lucide="copy"></i>
<span>复制</span>
</button>
</div>
<textarea class="comic-input" id="translated-text" placeholder="翻译结果将显示在这里..." readonly></textarea>
</div>
</div>
<div class="translation-progress" id="translation-progress" style="display: none;">
<div class="progress-bar">
<div class="progress-fill" id="translation-progress-bar" style="width: 0%;"></div>
</div>
<p class="progress-text" id="translation-progress-text">翻译中... 0%</p>
</div>
<button class="comic-button" id="translate-button">
<i data-lucide="languages"></i> 开始翻译
</button>
</div>
`;
// 初始化文本翻译工具
initTextTranslator();
break;
case "json-formatter":
container.innerHTML = `
<div class="tool-section json-formatter">
<div class="json-controls">
<div class="json-options">
<div class="indent-selector">
<label for="indent-size" class="option-label">缩进大小:</label>
<select id="indent-size" class="comic-input">
<option value="2">2</option>
<option value="4">4</option>
<option value="8">8</option>
</select>
</div>
<div class="sort-option">
<input type="checkbox" id="sort-keys" class="checkbox">
<label for="sort-keys" class="checkbox-label">排序键名</label>
</div>
</div>
<button class="comic-button" id="sample-data">
示例数据
</button>
</div>
<div class="json-grid">
<div class="json-area-container">
<label class="json-area-label">输入 JSON</label>
<textarea class="comic-input" id="json-input" placeholder="请输入 JSON 数据..."></textarea>
</div>
<div class="json-area-container">
<div class="json-area-header">
<label class="json-area-label">格式化结果</label>
<div class="json-actions" id="json-actions" style="display: none;">
<button class="json-action-button" id="copy-json">
<i data-lucide="copy"></i>
<span>复制</span>
</button>
<button class="json-action-button" id="download-json">
<i data-lucide="download"></i>
<span>下载</span>
</button>
</div>
</div>
<textarea class="comic-input" id="json-output" placeholder="格式化结果将显示在这里..." readonly></textarea>
<div class="json-error" id="json-error" style="display: none;"></div>
</div>
</div>
<button class="comic-button" id="format-json">
<i data-lucide="code"></i> 格式化 JSON
</button>
</div>
`;
// 初始化JSON格式化工具
initJsonFormatter();
break;
default:
// 对于其他工具,显示开发中提示
container.innerHTML = `
<div class="tool-section">
<div class="tool-content" style="text-align: center; padding: 3rem 1rem;">
<div class="comic-burst" style="display: inline-block; position: relative; margin-bottom: 20px;">
<i data-lucide="construction" style="width: 64px; height: 64px;"></i>
<div class="comic-burst-text">即将推出</div>
</div>
<h2 class="comic-title" style="margin-bottom: 16px;">工具开发中</h2>
<p style="margin-bottom: 24px;">该工具正在开发中,敬请期待!我们正在努力为您带来更多实用功能。</p>
<button class="comic-button" id="back-button">
<i data-lucide="arrow-left"></i> 返回
</button>
</div>
</div>
`;
// 返回按钮点击事件
const backButton = document.getElementById("back-button");
if (backButton) {
backButton.addEventListener("click", () => {
window.history.back();
});
}
}
// 重新初始化图标
lucide.createIcons();
}
// 初始化图片转换工具
function initImageConverter() {
const uploadArea = document.getElementById("upload-area");
const conversionArea = document.getElementById("conversion-area");
const fileInput = document.getElementById("file-input");
const imagePreview = document.getElementById("image-preview");
const fileInfo = document.getElementById("file-info");
const formatSelect = document.getElementById("format-select");
const qualitySlider = document.getElementById("quality-slider");
const qualityValue = document.getElementById("quality-value");
const convertButton = document.getElementById("convert-button");
const resetButton = document.getElementById("reset-conversion");
const conversionProgress = document.getElementById("conversion-progress");
const progressBarFill = document.getElementById("progress-bar-fill");
const progressText = document.getElementById("progress-text");
const conversionSuccess = document.getElementById("conversion-success");
const downloadButton = document.getElementById("download-button");
const downloadFormat = document.getElementById("download-format");
const stepUpload = document.getElementById("step-upload");
const stepConvert = document.getElementById("step-convert");
const stepDownload = document.getElementById("step-download");
let selectedFile = null;
let previewUrl = null;
let convertedUrl = null;
// 拖放上传
uploadArea.addEventListener("dragover", function (e) {
e.preventDefault();
this.style.borderColor = "var(--color-accent)";
});
uploadArea.addEventListener("dragleave", function () {
this.style.borderColor = "var(--color-border)";
});
uploadArea.addEventListener("drop", function (e) {
e.preventDefault();
this.style.borderColor = "var(--color-border)";
if (e.dataTransfer.files && e.dataTransfer.files[0]) {
const file = e.dataTransfer.files[0];
if (!file.type.startsWith("image/")) {
showNotification("上传错误", "请选择图片文件");
return;
}
handleFileSelect(file);
}
});
// 点击上传
uploadArea.addEventListener("click", () => {
fileInput.click();
});
fileInput.addEventListener("change", function () {
if (this.files && this.files[0]) {
const file = this.files[0];
if (!file.type.startsWith("image/")) {
showNotification("上传错误", "请选择图片文件");
return;
}
handleFileSelect(file);
}
});
// 处理文件选择
function handleFileSelect(file) {
selectedFile = file;
// 创建预览URL
previewUrl = URL.createObjectURL(file);
// 显示预览
imagePreview.innerHTML = `<img src="${previewUrl}" alt="预览" style="max-width: 100%; max-height: 100%;">`;
fileInfo.innerHTML = `
<p>文件名: ${file.name}</p>
<p>大小: ${(file.size / 1024).toFixed(2)} KB</p>
`;
// 切换显示
uploadArea.style.display = "none";
conversionArea.style.display = "block";
// 更新步骤
stepUpload.querySelector(".step-icon").classList.add("completed");
stepUpload.querySelector(".step-line").classList.add("active");
// 显示通知
showNotification("上传成功", "图片已上传,请选择转换格式");
}
// 质量滑块
qualitySlider.addEventListener("input", function () {
qualityValue.textContent = `${this.value}%`;
});
// 格式选择
formatSelect.addEventListener("change", function () {
downloadFormat.textContent = this.value.toUpperCase();
});
// 转换按钮
convertButton.addEventListener("click", function () {
if (!selectedFile) return;
// 隐藏转换按钮,显示进度
this.style.display = "none";
conversionProgress.style.display = "block";
// 更新步骤
stepConvert.querySelector(".step-icon").classList.add("active");
// 模拟转换进度
let progress = 0;
const interval = setInterval(() => {
progress += 5;
progressBarFill.style.width = `${progress}%`;
progressText.textContent = `转换中... ${progress}%`;
if (progress >= 100) {
clearInterval(interval);
// 模拟转换完成
setTimeout(() => {
// 隐藏进度,显示成功
conversionProgress.style.display = "none";
conversionSuccess.style.display = "block";
// 更新步骤
stepConvert.querySelector(".step-icon").classList.remove("active");
stepConvert.querySelector(".step-icon").classList.add("completed");
stepConvert.querySelector(".step-line").classList.add("active");
stepDownload.querySelector(".step-icon").classList.add("completed");
// 设置转换后的URL(实际应用中这里应该是转换后的图片)
convertedUrl = previewUrl;
// 显示通知
showNotification("转换成功", `图片已成功转换为${formatSelect.value.toUpperCase()}格式`);
}, 500);
}
}, 100);
});
// 下载按钮
downloadButton.addEventListener("click", () => {
if (!convertedUrl || !selectedFile) return;
// 创建下载链接
const link = document.createElement("a");
link.href = convertedUrl;
const fileName = selectedFile.name.split(".")[0];
link.download = `${fileName}.${formatSelect.value}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 显示通知
showNotification("下载开始", "文件下载已开始,请检查您的下载文件夹");
});
// 重置按钮
resetButton.addEventListener("click", () => {
// 重置状态
selectedFile = null;
previewUrl = null;
convertedUrl = null;
// 重置UI
uploadArea.style.display = "block";
conversionArea.style.display = "none";
convertButton.style.display = "block";
conversionProgress.style.display = "none";
conversionSuccess.style.display = "none";
progressBarFill.style.width = "0%";
// 重置步骤
stepUpload.querySelector(".step-icon").classList.remove("completed");
stepUpload.querySelector(".step-line").classList.remove("active");
stepConvert.querySelector(".step-icon").classList.remove("active", "completed");
stepConvert.querySelector(".step-line").classList.remove("active");
stepDownload.querySelector(".step-icon").classList.remove("completed");
// 重置文件输入
fileInput.value = "";
// 显示通知
showNotification("已重置", "工具已重置,您可以上传新的图片");
});
}
// 初始化文本翻译工具
function initTextTranslator() {
const sourceText = document.getElementById("source-text");
const translatedText = document.getElementById("translated-text");
const sourceLanguage = document.getElementById("source-language");
const targetLanguage = document.getElementById("target-language");
const translateButton = document.getElementById("translate-button");
const clearButton = document.getElementById("clear-text");
const swapButton = document.getElementById("swap-languages");
const copyButton = document.getElementById("copy-result");
const sourceCount = document.getElementById("source-count");
const translationProgress = document.getElementById("translation-progress");
const translationProgressBar = document.getElementById("translation-progress-bar");
const translationProgressText = document.getElementById("translation-progress-text");
// 字符计数
sourceText.addEventListener("input", function () {
sourceCount.textContent = this.value.length;
// 启用/禁用翻译按钮
if (this.value.trim()) {
translateButton.disabled = false;
} else {
translateButton.disabled = true;
}
});
// 清空按钮
clearButton.addEventListener("click", () => {
sourceText.value = "";
translatedText.value = "";
sourceCount.textContent = "0";
copyButton.style.display = "none";
translateButton.disabled = true;
// 显示通知
showNotification("已清空", "文本已清空");
});
// 交换语言
swapButton.addEventListener("click", () => {
const tempLang = sourceLanguage.value;
sourceLanguage.value = targetLanguage.value;
targetLanguage.value = tempLang;
const tempText = sourceText.value;
sourceText.value = translatedText.value;
translatedText.value = tempText;
sourceCount.textContent = sourceText.value.length;
// 显示通知
showNotification("语言已交换", "源语言和目标语言已交换");
});
// 翻译按钮
translateButton.addEventListener("click", function () {
if (!sourceText.value.trim()) return;
// 显示进度
this.style.display = "none";
translationProgress.style.display = "block";
// 模拟翻译进度
let progress = 0;
const interval = setInterval(() => {
progress += 10;
translationProgressBar.style.width = `${progress}%`;
translationProgressText.textContent = `翻译中... ${progress}%`;
if (progress >= 100) {
clearInterval(interval);
// 模拟翻译结果
setTimeout(() => {
// 简单模拟翻译结果
if (targetLanguage.value === "en" && sourceLanguage.value === "zh") {
translatedText.value = sourceText.value
.replace(/你好/g, "Hello")
.replace(/世界/g, "World")
.replace(/翻译/g, "Translation")
.replace(/工具/g, "Tool")
.replace(/文本/g, "Text");
} else if (targetLanguage.value === "zh" && sourceLanguage.value === "en") {
translatedText.value = sourceText.value
.replace(/Hello/g, "你好")
.replace(/World/g, "世界")
.replace(/Translation/g, "翻译")
.replace(/Tool/g, "工具")
.replace(/Text/g, "文本");
} else {
// 对于其他语言对,简单地添加目标语言标记
translatedText.value = `[${targetLanguage.value.toUpperCase()}] ${sourceText.value}`;
}
// 隐藏进度,显示翻译按钮
translationProgress.style.display = "none";
translateButton.style.display = "block";
// 显示复制按钮
copyButton.style.display = "flex";
// 显示通知
showNotification("翻译完成", "文本已成功翻译");
// 添加使用记录
dataManager.addToHistory("text-translator");
}, 1000);
}
}, 100);
});
// 复制按钮
copyButton.addEventListener("click", function () {
if (!translatedText.value) return;
navigator.clipboard.writeText(translatedText.value);
// 显示复制成功
const originalText = this.innerHTML;
this.innerHTML = '<i data-lucide="check"></i><span>已复制</span>';
lucide.createIcons();
setTimeout(() => {
this.innerHTML = originalText;
lucide.createIcons();
}, 2000);
// 显示通知
showNotification("已复制", "翻译结果已复制到剪贴板");
});
}
// 初始化JSON格式化工具
function initJsonFormatter() {
const jsonInput = document.getElementById("json-input");
const jsonOutput = document.getElementById("json-output");
const indentSize = document.getElementById("indent-size");
const sortKeys = document.getElementById("sort-keys");
const formatButton = document.getElementById("format-json");
const sampleButton = document.getElementById("sample-data");
const jsonError = document.getElementById("json-error");
const jsonActions = document.getElementById("json-actions");
const copyJson = document.getElementById("copy-json");
const downloadJson = document.getElementById("download-json");
// 格式化按钮
formatButton.addEventListener("click", () => {
if (!jsonInput.value.trim()) return;
try {
// 解析JSON
const parsedJson = JSON.parse(jsonInput.value);
// 根据选项格式化
const formatted = JSON.stringify(
parsedJson,
sortKeys.checked ? Object.keys(parsedJson).sort() : null,
Number(indentSize.value)
);
// 显示格式化结果
jsonOutput.value = formatted;
jsonError.style.display = "none";
jsonActions.style.display = "flex";
// 显示通知
showNotification("格式化成功", "JSON数据已成功格式化");
// 添加使用记录
dataManager.addToHistory("json-formatter");
} catch (err) {
// 显示错误
jsonError.textContent = `JSON 解析错误: ${err.message}`;
jsonError.style.display = "block";
jsonOutput.value = "";
jsonActions.style.display = "none";
// 显示通知
showNotification("格式化错误", "JSON数据解析失败,请检查输入");
}
});
// 示例数据
sampleButton.addEventListener("click", () => {
const sample = {
name: "漫画风工具箱",
version: "1.0.0",
description: "多功能在线工具集合",
tools: [
{ id: 1, name: "图片转换", category: "图片" },
{ id: 2, name: "文本翻译", category: "文本" },
{ id: 3, name: "JSON格式化", category: "开发" }
],
settings: {
theme: "dark",
language: "zh-CN"
}
};
jsonInput.value = JSON.stringify(sample);
// 显示通知
showNotification("示例数据", "示例数据已加载");
});
// 复制按钮
copyJson.addEventListener("click", function () {
if (!jsonOutput.value) return;
navigator.clipboard.writeText(jsonOutput.value);
// 显示复制成功
const originalText = this.innerHTML;
this.innerHTML = '<i data-lucide="check"></i><span>已复制</span>';
lucide.createIcons();
setTimeout(() => {
this.innerHTML = originalText;
lucide.createIcons();
}, 2000);
// 显示通知
showNotification("已复制", "格式化结果已复制到剪贴板");
});
// 下载按钮
downloadJson.addEventListener("click", () => {
if (!jsonOutput.value) return;
const blob = new Blob([jsonOutput.value], { type: "application/json" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = "formatted.json";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 显示通知
showNotification("下载开始", "JSON文件下载已开始");
});
}
// 初始化收藏按钮
function initFavoriteButtons() {
document.querySelectorAll('.favorite-button').forEach(button => {
button.addEventListener('click', function(e) {
e.stopPropagation();
toggleFavorite(this);
});
});
}
// 切换收藏状态
function toggleFavorite(button) {
const toolId = button.dataset.tool;
const isFavorite = button.classList.contains('active');
if (isFavorite) {
// 取消收藏
dataManager.removeFavorite(toolId);
button.classList.remove('active');
// 更新按钮文本(如果是详情页面的按钮)
if (button.textContent.includes('取消收藏')) {
button.innerHTML = '<i data-lucide="heart"></i> 收藏工具';
lucide.createIcons();
}
// 显示通知
const toolInfo = getToolInfo(toolId);
showNotification("已取消收藏", `${toolInfo ? toolInfo.name : '工具'}已从收藏中移除`);
// 如果在收藏页面,需要刷新列表
if (document.getElementById('favorite-tools-page').classList.contains('active')) {
loadFavoriteTools();
}
} else {
// 添加收藏
dataManager.addFavorite(toolId);
button.classList.add('active');
// 更新按钮文本(如果是详情页面的按钮)
if (button.textContent.includes('收藏工具')) {
button.innerHTML = '<i data-lucide="heart"></i> 取消收藏';
lucide.createIcons();
}
// 显示通知
const toolInfo = getToolInfo(toolId);
showNotification("已收藏", `${toolInfo ? toolInfo.name : '工具'}已添加到收藏`);
// 如果在收藏页面,需要刷新列表
if (document.getElementById('favorite-tools-page').classList.contains('active')) {
loadFavoriteTools();
}
}
// 添加动画效果
button.classList.add('bounce');
setTimeout(() => {
button.classList.remove('bounce');
}, 500);
}
// 清除所有数据
document.getElementById('clear-data').addEventListener('click', () => {
if (confirm('确定要清除所有收藏和使用记录吗?此操作不可撤销。')) {
dataManager.clearAllData();
showNotification("数据已清除", "所有收藏和使用记录已清除");
// 如果在收藏页面或最近使用页面,需要刷新列表
if (document.getElementById('favorite-tools-page').classList.contains('active')) {
loadFavoriteTools();
} else if (document.getElementById('recent-tools-page').classList.contains('active')) {
loadRecentTools();
}
}
});
// 导航按钮点击事件
navButtons.forEach(button => {
button.addEventListener('click', function() {
const pageId = this.dataset.page;
const categoryId = this.dataset.category;
setActivePage(pageId, categoryId);
});
});
// 分类卡片点击事件
document.querySelectorAll('.category-card').forEach(card => {
card.addEventListener('click', function() {
const categoryId = this.dataset.category;
setActivePage('category-page', categoryId);
});
});
// 首页按钮点击事件
document.getElementById('explore-tools').addEventListener('click', () => {
setActivePage('popular-tools-page');
});
document.getElementById('popular-tools').addEventListener('click', () => {
setActivePage('popular-tools-page');
});
// 搜索功能
const searchInput = document.getElementById('search-input');
searchInput.addEventListener('keyup', function(e) {
if (e.key === 'Enter') {
const searchTerm = this.value.trim().toLowerCase();
if (searchTerm) {
searchTools(searchTerm);
}
}
});
// 搜索工具
function searchTools(searchTerm) {
// 创建搜索结果数组
const searchResults = [];
// 遍历所有工具
for (const category in toolsData) {
toolsData[category].forEach(tool => {
// 检查工具名称和描述是否包含搜索词
if (
tool.name.toLowerCase().includes(searchTerm) ||
tool.description.toLowerCase().includes(searchTerm)
) {
searchResults.push({
...tool,
category
});
}
});
}
// 显示搜索结果
displaySearchResults(searchResults, searchTerm);
}
// 显示搜索结果
function displaySearchResults(results, searchTerm) {
// 切换到分类页面
setActivePage('category-page', 'search');
// 更新分类标题和描述
const categoryTitle = document.getElementById("category-title");
const categoryDescription = document.getElementById("category-description");
const categoryToolsGrid = document.getElementById("category-tools-grid");
categoryTitle.textContent = `搜索结果: "${searchTerm}"`;
categoryDescription.textContent = `找到 ${results.length} 个相关工具`;
// 清空工具网格
categoryToolsGrid.innerHTML = "";
if (results.length === 0) {
// 显示无结果提示
categoryToolsGrid.innerHTML = `
<div class="no-results" style="grid-column: 1 / -1; text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">
<i data-lucide="search-x"></i>
</div>
<h3 style="font-family: var(--font-comic); font-size: 24px; margin-bottom: 8px;">未找到结果</h3>
<p style="color: var(--color-foreground-muted); margin-bottom: 16px;">没有找到与"${searchTerm}"相关的工具,请尝试其他关键词。</p>
<button class="comic-button" id="back-to-home-button">
<i data-lucide="home"></i> 返回首页
</button>
</div>
`;
// 返回首页按钮点击事件
const backToHomeButton = document.getElementById("back-to-home-button");
if (backToHomeButton) {
backToHomeButton.addEventListener("click", () => {
setActivePage("home-page");
});
}
// 重新初始化图标
lucide.createIcons();
return;
}
// 添加搜索结果
results.forEach(tool => {
const isFavorite = dataManager.isFavorite(tool.id);
const toolCard = document.createElement("div");
toolCard.className = "tool-card";
toolCard.dataset.tool = tool.id;
toolCard.innerHTML = `
<button class="favorite-button ${isFavorite ? 'active' : ''}" data-tool="${tool.id}">
<i data-lucide="heart"></i>
</button>
<div class="tool-card-icon">
<i data-lucide="${tool.icon}"></i>
</div>
<h3 class="tool-card-title">${tool.name}</h3>
<p class="tool-card-description">${tool.description}</p>
<button class="tool-card-button">使用工具</button>
`;
toolCard.addEventListener("click", (e) => {
// 如果点击的是收藏按钮,不跳转到工具详情
if (!e.target.closest('.favorite-button')) {
loadToolDetail(tool.id);
setActivePage("tool-detail-page", null, tool.id);
// 添加使用记录
dataManager.addToHistory(tool.id);
}
});
categoryToolsGrid.appendChild(toolCard);
});
// 初始化收藏按钮
initFavoriteButtons();
// 重新初始化图标
lucide.createIcons();
// 更新面包屑
breadcrumb.textContent = `首页 / 搜索结果: "${searchTerm}"`;
}
// 初始化页面
loadFeaturedTools();
initFavoriteButtons();
});
</script>
</head>
<body>
</body>
</html>
index.html
style.css
index.js