院长
院长
发布于 2023-10-20 / 98 阅读 / 0 评论 / 0 点赞

Mio-Chat 笔记 [一] —— CSS 动效

在开发 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. 参数1:属性名。即想要设置过渡效果的属性。

  2. 参数2:过渡时长。即播放过渡动画所需的时间。

  3. 参数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 的帮助解决了一些问题。这是一个很好的实现方式,可以让你的应用程序具有更好的用户体验。如果你有其他问题或需要进一步的帮助,请随时提问!


评论