diff --git a/static/img/loading.gif b/static/img/loading.gif new file mode 100644 index 0000000..e652d1e Binary files /dev/null and b/static/img/loading.gif differ diff --git a/static/index.css b/static/index.css new file mode 100644 index 0000000..df36bae --- /dev/null +++ b/static/index.css @@ -0,0 +1,78 @@ +body { + font-family: Arial, sans-serif; + background-color: #f5f5f5; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + background-image: url("../static/img/bg_circles.png"); +background-repeat: repeat; +} +#chat-container { + width: 80%; /* 使用百分比宽度 */ + max-width: 1300px; /* 最大宽度,防止界面变得过宽 */ + background-color: #fff; + border: 1px solid #ccc; + border-radius: 10px; + padding: 20px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} +#chat-messages { + max-height: 500px; + overflow-y: auto; + border: 1px solid #ddd; + border-radius: 5px; + padding: 10px; + background-color: #f9f9f9; + word-wrap: break-word; /* 自动换行 */ + white-space: pre-wrap; /* 保留空格并自动换行 */ +} +.message-divider { + border-top: 1px solid #ccc; + margin: 10px 0; +} +#user-input { + width: 97%; + padding: 10px; + border: 1px solid #ccc; + border-radius: 5px; + margin-top: 10px; +} +#user-input:focus { + outline: none; +} +#user-input::placeholder { + color: #999; +} +#user-input-button { + background-color: #007bff; + color: #fff; + border: none; + border-radius: 5px; + padding: 10px 20px; + margin-top: 10px; + cursor: pointer; +} +#user-input-button:disabled { + background-color: #ccc; + cursor: not-allowed; +} +/* 新增样式 */ +#additional-controls { + display: flex; + align-items: center; + justify-content: space-between; /* 左右对齐 */ + margin-top: 10px; +} +#additional-controls input[type="checkbox"] { + margin-right: 10px; +} +#additional-controls button { + background-color: #466d2b; + color: #fff; + border: none; + border-radius: 5px; + padding: 10px 20px; + cursor: pointer; +} \ No newline at end of file diff --git a/static/loading.css b/static/loading.css new file mode 100644 index 0000000..510ec4a --- /dev/null +++ b/static/loading.css @@ -0,0 +1,270 @@ +.loading { + width: 100%; + height: 100vh; + opacity: 1; + position: fixed; + display: flex; + justify-content: center; + align-items: center; + z-index: 3; + background-color: #fbfbfb; + transition: opacity 1s ease; + pointer-events: none; /* 确保遮罩不影响下方元素的交互 */ +} + +.typewriter { + --blue: #5C86FF; + --blue-dark: #275EFE; + --key: #fff; + --paper: #EEF0FD; + --text: #D3D4EC; + --tool: #FBC56C; + --duration: 3s; + position: relative; + -webkit-animation: bounce05 var(--duration) linear infinite; + animation: bounce05 var(--duration) linear infinite; +} + +.typewriter .slide { + width: 92px; + height: 20px; + border-radius: 3px; + margin-left: 14px; + transform: translateX(14px); + background: linear-gradient(var(--blue), var(--blue-dark)); + -webkit-animation: slide05 var(--duration) ease infinite; + animation: slide05 var(--duration) ease infinite; +} + +.typewriter .slide:before, +.typewriter .slide:after, +.typewriter .slide i:before { + content: ""; + position: absolute; + background: var(--tool); +} + +.typewriter .slide:before { + width: 2px; + height: 8px; + top: 6px; + left: 100%; +} + +.typewriter .slide:after { + left: 94px; + top: 3px; + height: 14px; + width: 6px; + border-radius: 3px; +} + +.typewriter .slide i { + display: block; + position: absolute; + right: 100%; + width: 6px; + height: 4px; + top: 4px; + background: var(--tool); +} + +.typewriter .slide i:before { + right: 100%; + top: -2px; + width: 4px; + border-radius: 2px; + height: 14px; +} + +.typewriter .paper { + position: absolute; + left: 24px; + top: -26px; + width: 40px; + height: 46px; + border-radius: 5px; + background: var(--paper); + transform: translateY(46px); + -webkit-animation: paper05 var(--duration) linear infinite; + animation: paper05 var(--duration) linear infinite; +} + +.typewriter .paper:before { + content: ""; + position: absolute; + left: 6px; + right: 6px; + top: 7px; + border-radius: 2px; + height: 4px; + transform: scaleY(0.8); + background: var(--text); + box-shadow: 0 12px 0 var(--text), 0 24px 0 var(--text), 0 36px 0 var(--text); +} + +.typewriter .keyboard { + width: 120px; + height: 56px; + margin-top: -10px; + z-index: 1; + position: relative; +} + +.typewriter .keyboard:before, +.typewriter .keyboard:after { + content: ""; + position: absolute; +} + +.typewriter .keyboard:before { + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 7px; + background: linear-gradient(135deg, var(--blue), var(--blue-dark)); + transform: perspective(10px) rotateX(2deg); + transform-origin: 50% 100%; +} + +.typewriter .keyboard:after { + left: 2px; + top: 25px; + width: 11px; + height: 4px; + border-radius: 2px; + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + -webkit-animation: keyboard05 var(--duration) linear infinite; + animation: keyboard05 var(--duration) linear infinite; +} + +@keyframes bounce05 { + + 85%, + 92%, + 100% { + transform: translateY(0); + } + + 89% { + transform: translateY(-4px); + } + + 95% { + transform: translateY(2px); + } +} + +@keyframes slide05 { + 5% { + transform: translateX(14px); + } + + 15%, + 30% { + transform: translateX(6px); + } + + 40%, + 55% { + transform: translateX(0); + } + + 65%, + 70% { + transform: translateX(-4px); + } + + 80%, + 89% { + transform: translateX(-12px); + } + + 100% { + transform: translateX(14px); + } +} + +@keyframes paper05 { + 5% { + transform: translateY(46px); + } + + 20%, + 30% { + transform: translateY(34px); + } + + 40%, + 55% { + transform: translateY(22px); + } + + 65%, + 70% { + transform: translateY(10px); + } + + 80%, + 85% { + transform: translateY(0); + } + + 92%, + 100% { + transform: translateY(46px); + } +} + +@keyframes keyboard05 { + + 5%, + 12%, + 21%, + 30%, + 39%, + 48%, + 57%, + 66%, + 75%, + 84% { + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + } + + 9% { + box-shadow: 15px 2px 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + } + + 18% { + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 2px 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + } + + 27% { + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 12px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + } + + 36% { + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 12px 0 var(--key), 60px 12px 0 var(--key), 68px 12px 0 var(--key), 83px 10px 0 var(--key); + } + + 45% { + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 2px 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + } + + 54% { + box-shadow: 15px 0 0 var(--key), 30px 2px 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + } + + 63% { + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 12px 0 var(--key); + } + + 72% { + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 2px 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 10px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + } + + 81% { + box-shadow: 15px 0 0 var(--key), 30px 0 0 var(--key), 45px 0 0 var(--key), 60px 0 0 var(--key), 75px 0 0 var(--key), 90px 0 0 var(--key), 22px 10px 0 var(--key), 37px 12px 0 var(--key), 52px 10px 0 var(--key), 60px 10px 0 var(--key), 68px 10px 0 var(--key), 83px 10px 0 var(--key); + } +} \ No newline at end of file diff --git a/static/popup.css b/static/popup.css index fed8e77..6a26990 100644 --- a/static/popup.css +++ b/static/popup.css @@ -1,26 +1,34 @@ -#popup-container { +#global-blur { + background-color: rgba(255, 255, 255, 0); position: fixed; top: 0; - right: -100%; + left: 0; width: 100%; height: 100%; - background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(8px); /* 模糊度可以根据需要调整 */ + transition: display; + z-index: 1; /* 保证遮罩在页面上方 */ + pointer-events: none; /* 确保遮罩不影响下方元素的交互 */ + opacity: 0; + transition: opacity 0.3s ease } -#popup { - position: absolute; +#popup-container { + background-color: #f1f1f1; + height: 100%; + width: 250px; + position: fixed; top: 0; right: 0; - height: 100%; - width: 20%; - min-width: 150px; - min-width: 200px; - background: white; - padding: 20px; + overflow-x: hidden; + padding-top: 60px; + z-index: 2; + transition: transform 0.4s ease; + transform: translateX(250px); } -.hidden { - display: none; +#popup-container.show { + transform: translateX(0); } #close-popup { @@ -31,17 +39,84 @@ #dropdown { margin: auto; - width: 80%; /* 让元素宽度占满容器 */ + margin-bottom: 10px; + /* 添加一些底部间距 */ } #buttons { margin: auto; width: 50%; display: flex; - flex-direction: column; /* 设置按钮垂直排列 */ + flex-direction: column; + /* 设置按钮垂直排列 */ } #buttons button { - margin: 10px 0; /* 添加按钮之间的垂直间距 */ + margin: 10px 0; + /* 添加按钮之间的垂直间距 */ +} + +/* 弹窗消息框CSS */ + +/* 定义通知框的样式 */ +.notification { + display: none; + /* 初始状态下通知框不显示 */ + position: fixed; + top: 10px; + right: 10px; + width: 300px; + background-color: #f1f1f1; + padding: 10px; + border: 1px solid #ddd; + border-radius: 5px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + opacity: 0; + /* 初始透明度为 0,即不可见 */ + transform: translateY(-20px); + /* 初始向上平移20px,用于动画效果 */ + transition: opacity 0.3s ease, transform 0.3s ease; + /* 添加过渡效果 */ +} + +/* 定义显示状态下的通知框样式 */ +.notification.show { + opacity: 1; + /* 显示状态下透明度为 1,即完全可见 */ + transform: translateY(0); + /* 平移恢复到原位,显示的过渡效果 */ +} + +/* 定义通知框内的内容容器样式 */ +.notification-content { + position: relative; +} + +/* 定义关闭按钮的样式 */ +.close { + position: absolute; + top: 0; + right: 0; + font-size: 18px; + cursor: pointer; +} + +/* 定义进度条样式 */ +.progress-bar { + height: 10px; + background-color: #ddd; + border-radius: 5px; + margin-top: 10px; + overflow: hidden; +} + +/* 定义进度条内部样式 */ +.progress-bar-inner { + height: 100%; + width: 100%; + background-color: #4caf50; + transition: width 0.3s linear; + /* 添加进度条宽度变化的线性过渡效果 */ } \ No newline at end of file diff --git a/static/popupMessagesBox.js b/static/popupMessagesBox.js new file mode 100644 index 0000000..94d0f7e --- /dev/null +++ b/static/popupMessagesBox.js @@ -0,0 +1,59 @@ +// 消息框的js代码 + +// 获取页面元素 +var notification = document.getElementById('notification'); +var showNotificationBtn = document.getElementById('showNotificationBtn'); +var notificationText = document.getElementById('notificationText'); +var progressBarInner = document.getElementById('progressBarInner'); + +// 显示通知函数 +function showNotification(message) { + // 设置通知文本 + notificationText.innerText = message; + // 显示通知框 + notification.style.display = 'block'; + + // 触发回流(reflow)以启用动画效果 + notification.offsetHeight; + + // 添加显示状态的类,触发过渡效果 + notification.classList.add('show'); + + // 启动倒计时 + startCountdown(5); // 延迟时间 +} + +// 倒计时函数 +function startCountdown(duration) { + var startTime = Date.now(); + var interval = setInterval(function () { + var currentTime = Date.now(); + var elapsedTime = currentTime - startTime; + var remainingTime = duration * 1000 - elapsedTime; + + if (remainingTime <= 0) { + clearInterval(interval); + closeNotification(); + } else { + var progressPercent = (remainingTime / (duration * 1000)) * 100; + updateProgressBar(progressPercent); + } + }, 100); +} + +// 更新进度条函数 +function updateProgressBar(percent) { + progressBarInner.style.width = percent + '%'; +} + +// 关闭通知函数 +function closeNotification() { + // 移除显示状态的类,触发过渡效果 + notification.classList.remove('show'); + // 延时等待动画完成后隐藏通知框 + setTimeout(function () { + notification.style.display = 'none'; + // 重置进度条宽度为 100% + progressBarInner.style.width = '100%'; + }, 300); // 等待动画完成再隐藏 +} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 28db85c..4ac2ed2 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,99 +1,48 @@ + KakuAI - + + - + + +
+
+
+
+
+
+
+ +
+ +
+ +
+ + × + +

这是一条通知。

+ +
+ +
+
+
+
- +