在开发 mio-chat-nt 的过程中,发现我需要一个提示框来标识一下各种状态,想来想去觉得还是抄 next-web 的从底部向上淡入再淡出比较美观。于是想自己实现一下类似的功能。
1. 编写模板文件
新建一个 index.html ,通过 code 打开。!+ tab 回车,生成了html的模板。body 上div个弹窗元素,然后是重头戏,给它写<style>
先来搞定大体位置——使用 position : fixed 让它相对于窗口定位,left:50% ; transform : translateX(50%); 让它水平居中对齐
然后自身形状——display:flex; justify-content:center;aligen-items:center flex;1 0 64px 搞定形状,白色背景和50%的圆角,再加点阴影,完美。
然后是重点:动效。即如何让它完成向上下运动以及淡入淡出的效果。虽然用过很多了,但是自己还是完全不了解。先去问了下gpt,给出的答复是
当然可以!CSS过渡(Transition)动画是一种在元素状态发生变化时,为元素提供平滑过渡效果的技术。你可以使用CSS属性`transition`来定义这些过渡效果。
这是一个基本的CSS过渡动画的例子,假设你有一个`<div>`元素,当鼠标悬停在上面时,背景色会发生变化:
```css
/* 定义过渡属性 */
div {
width: 200px;
height: 200px;
background-color: blue;
transition: background-color 0.3s ease;
}
/* 当鼠标悬停时改变背景色 */
div:hover {
background-color: red;
}
```
在这个例子中,`transition`属性定义了过渡的属性(这里是`background-color`),过渡持续的时间(0.3秒),以及过渡的速度曲线(`ease`表示以慢-快-慢的速度进行过渡)。
你可以根据需要修改过渡的属性和持续时间,创建各种各样的过渡动画效果。希望这对你有所帮助!如果你有其他问题,请随时问我。
学到了 transition 属性,即样式的属性因为各种原因发生改变时,过渡的效果。
参数1:属性名。即想要设置过渡效果的属性。
参数2:过渡时长。即播放过渡动画所需的时间。
参数3:动画样式,这里变化很多,去问下AI
淡入淡出的具体效果无非就是控制透明度与高度,使用opacity 与 height 轻松拿捏。
总之使用transition属性配合js,能够实现基本的淡入淡出了。
2. 实现方法
模板文件有了,下面得插入到我的网页里面去。首先想到的是以 vue 组件的形式添加到我的项目中,但是遇到了很多问题。
如果用 v-if,如何处理并发问题?
如果用 v-for 如何处理回收问题?
........
因为动效还需要通过js实现,也是遇到了不少问题。一番思索后,我想能不能抛开js让它自己播放个动效然后两秒后自己消失?再次询问AI,他给出了解决思路——关键帧动画。
3.编写模板文件 2.0
先问AI
了解了基本定义,那么我们可以抛开js那冗杂的代码了。向上淡入和向下淡出,关键帧自己都能解决了。最终成品如下
.fade-in {
z-index: 99999;
align-items: center;
justify-content: center;
background-color: rgb(247, 247, 247);
border-radius: 100px;
position: fixed;
bottom: 20px;
display: flex;
min-width: 100px;
height: 32px;
opacity: 0.1;
animation: fade 2s forwards;
left: 50%;
/* 将元素的左边缘定位到视口的水平中心 */
transform: translateX(-50%);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* 添加阴影效果 */
}
@keyframes fade {
0% {
opacity: 0.1;
}
30% {
opacity: 1;
bottom: 70px;
}
100% {
opacity: 0;
bottom: 20px;
}
}
.tip {
white-space: nowrap;
}
实现方法 2.0
一开始我的想法是写一个函数,接受两个参数 type 与 info 。type 控制弹窗的类型(警告 或者 调试) info 控制弹窗内容。但是后来想了想好像不够优雅,就问了下 AI 怎么能更优雅。AI的思路是export出去一个对象,含有 info 和 warn 方法,接收 info 参数。雀氏,这样便有也了许多。再使用模板语法将参数填充至 html 里,一个简单的弹窗就完成了。分为css与js,css在上面了,js完整源码如下
function appendTip(tip) {
console.log(tip)
var icon = tip.type == 'warn' ? `
<svg style="padding-left: 16px;" t="1697450824459" class="icon" viewBox="0 0 1024 1024"
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6147" width="16" height="16">
<path
d="M512.165 0.315a511.835 511.835 0 1 0 511.52 511.835A512.229 512.229 0 0 0 512.165 0.315z m208.671 669.323a36.537 36.537 0 1 1-51.734 51.616L512.008 563.767 354.52 719.797a36.537 36.537 0 1 1-51.38-51.97l157.487-155.834L303.77 354.505a36.537 36.537 0 1 1 51.734-51.617L512.56 460.376l157.488-156.07a36.537 36.537 0 0 1 51.38 52.01L563.939 512.11z m0 0"
fill="#d81e06" p-id="6148"></path>
</svg>
` : `
<svg style="padding-left: 16px;" t="1697458918486" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="4007" width="16" height="16">
<path
d="M512.000002 0a512 512 0 1 0 512 512A512 512 0 0 0 512.000002 0z m223.654358 412.798124l-206.634849 275.527422a64.305451 64.305451 0 0 1-96.92975 6.859248L294.304615 557.313908c-60.018421-60.018421 30.866616-151.032069 90.970778-90.927908l85.311898 85.311898 162.178348-216.194926c51.058528-67.949426 153.904379 9.302855 102.888721 77.295152z"
fill="#00D66A" p-id="4008"></path>
</svg>
`
var html = `
<div ref="box" class="tipsbox">
<div class="fade-in">
${icon}
<div class="tip" style="padding: 0px 16px;">
${tip.info}
</div>
</div>
</div>
`;
document.body.insertAdjacentHTML("beforeend", html);
// 延迟两秒后移除提示框
setTimeout(function () {
var box = document.querySelector('.tipsbox');
if (box) {
box.remove();
}
}, 2000);
}
const makeTips = {
warn: function (msg) {
const data = {
type: "warn",
info: msg
}
appendTip(data)
},
info: function (msg) {
const data = {
type: "info",
info: msg
}
appendTip(data)
}
}
export default makeTips;
这样就能在外部文件通过 import 导入了。导入makeTips对象后,使用后 makeTAips.info() &&
makeTAips.warn() 就可以形成弹窗了。
总结
最后让ChatGPT出个总结吧~
通过上述推文,你描述了在开发 `mio-chat-nt` 过程中的需求,以及你如何使用 HTML、CSS 和 JavaScript 实现一个类似 `next-web` 的提示框功能。
首先,你创建了一个模板文件 `index.html`,并在其中定义了弹窗的样式。你使用了 `position: fixed` 让弹窗相对于窗口定位,并使用 `flex` 布局使其居中对齐。然后,你介绍了如何使用 CSS 过渡动画来实现淡入淡出的效果,使用 `transition` 属性定义过渡的属性和持续时间,以及使用关键帧动画 `@keyframes` 定义具体的动画效果。
接下来,你提到了实现方法。最初的想法是通过编写一个函数,接受类型(`type`)和信息(`info`)作为参数来控制弹窗的显示。然后,你向 ChatGPT 提问如何更优雅地实现,得到的答案是导出一个对象,包含 `info` 和 `warn` 方法,以及使用模板语法将参数填充到 HTML 中。这样,你就可以通过导入该对象并调用 `makeTips.info()` 和 `makeTips.warn()` 来显示弹窗。
最后,你总结了整个过程,并希望 ChatGPT能为你提供一个结尾。
总的来说,你展示了如何使用 HTML、CSS 和 JavaScript 实现一个从底部向上淡入再淡出的提示框功能,并通过 ChatGPT 的帮助解决了一些问题。这是一个很好的实现方式,可以让你的应用程序具有更好的用户体验。如果你有其他问题或需要进一步的帮助,请随时提问!