绽放奇迹:探索如何为您的UI添加令人惊叹的动效
Start
大家好,我是TalexDreamSoul,一个个人开发者,也是高中生。今天我想跟大家分享一个我开发的项目,它叫做TalexTouch。
TalexTouch是一个基于Electron制作的全客户端,旨在提供更完美的UI体验。它支持在Windows、MacOS和Linux等主流平台上运行,让用户能够在各种设备上享受一致的使用体验。 TalexTouch的源码地址
这是一个非常强大的项目,集成了多种实用的功能,让你的桌面更智能、更高效。同时,它还支持自定义插件,让用户可以根据自己的需求进行定制化操作。
TalexTouch的UI设计非常优美,参考了TDesignS的设计风格,简洁美观。所有的主题、字体和图标都经过精心调整,以使用户获得更佳的使用体验。操作也非常简单易用,用户可以轻松地完成各种任务。
我们非常注重用户的安全和隐私,保证用户的数据不会被泄露或滥用,同时提供了多种安全机制来保护用户的使用安全。如果你正在寻找一款全平台支持、优美易用的桌面软件,TalexTouch将是你的不二选择。它不仅提供了丰富的功能,还有着良好的用户体验和开放的社区生态。
欢迎使用TalexTouch,体验全新的桌面体验!
Tutorial
本教程将介绍如何实现一个输入框联想功能,当用户输入文字时,会自动弹出与输入内容匹配的联想选项,用户可以从选项中选择一个。
效果预览
在这个教程中,我们将使用Vue 3和SCSS编写代码,并且使用Teleport组件实现将联想选项移动到页面的body元素。
我们的组件将具有以下功能:
- 自动弹出联想选项
- 点击联想选项时填充输入框
- 点击输入框外部的任何区域,关闭联想选项
- 限制联想选项的数量不超过8项
- 动态计算联想选项的位置,确保联想选项在输入框下方,并且不会超出视窗范围
以下是我们组件的模板代码:
<template>
<div class="FlatInput-Container" ref="completionInput">
<FlatInput v-model="value" :icon="icon" />
</div>
<teleport to="body">
<div @click="value = ''" class="FlatInput-Completion" ref="completionWrapper">
<div v-wave class="FlatInput-Completion-Item fake-background" :style="`--d: ${index * 0.125}s`" v-for="(item, index) in _res" :key="item">
<slot :item="item">
{{ item }}
</slot>
</div>
</div>
</teleport>
</template>
在上面的代码中,我们定义了一个FlatInput组件和一个Teleport组件,FlatInput是我们自己定义的一个输入框组件,Teleport可以将FlatInput-Completion组件移动到body元素中。
接下来是我们组件的逻辑代码:
<script setup name="FlatCompletion">
import FlatInput from "@comp/input/FlatInput.vue";
import { sleep, useModelWrapper } from "@modules/utils";
import { useFloating, autoUpdate, flip, shift, computePosition } from '@floating-ui/vue'
const props = defineProps({
icon: {
type: String,
default: "search",
},
fetch: {
type: Function,
require: true
}
});
const _res = ref([])
const res = ref([]);
const completionInput = ref()
const completionWrapper = ref()
const value = ref()
watch(() => value.value, () => {
nextTick(blur)
}, { deep: true, immediate: true });
watch(() => res.value, async () => {
const el = completionWrapper.value
for ( const item of [ ...el.children ].reverse() ) {
setTimeout(async () => {
item.classList.add('remove')
await sleep(500)
item?.remove()
})
await sleep(125)
}
await sleep(600)
_res.value = res.value
})
function blur() { if ( !value.value ) value.value = "" res.value = props.fetch(value.value) if ( res.value.length > 8 ) res.value = res.value.slice(0, 8) nextTick(async() => { const floating = await computePosition(completionInput.value, completionWrapper.value) Object.assign(completionWrapper.value.style, { top: `${floating.y}px`, left: `${floating.x}px` }) }) } </script>
- 监听数据变化
为了实时获取用户输入的内容,我们需要在 watch
函数中监听 value
数据的变化,并调用 blur
函数进行处理。代码如下:
watch(() => value.value, () => {
nextTick(blur)
}, { deep: true, immediate: true });
其中,deep: true
表示深度监听 value
的变化,immediate: true
表示在监听之前立即触发一次回调函数。
- 处理用户输入
在 blur
函数中,我们需要对用户输入进行处理,并根据输入的内容动态展示下拉框中的选项。
具体处理流程如下:
- 获取用户输入的内容,如果为空,则直接清空下拉框。
- 调用
fetch
函数获取用户输入所对应的选项列表。 - 对选项列表进行截取,最多展示 8 个选项。
- 获取下拉框的浮动位置,并设置到下拉框元素的样式中。
function blur() {
if ( !value.value ) value.value = ""
res.value = props.fetch(value.value)
if ( res.value.length > 8 )
res.value = res.value.slice(0, 8)
nextTick(async() => {
const floating = await computePosition(completionInput.value, completionWrapper.value)
Object.assign(completionWrapper.value.style, {
top: `${floating.y}px`,
left: `${floating.x}px`
})
})
}
- 渲染下拉框
在模板中,我们使用 teleport
将下拉框挂载到页面的 body
元素上,实现了下拉框的浮动效果。同时,我们使用 v-for
指令遍历选项列表,生成下拉框中的选项元素,并使用插槽 slot
将每个选项的内容作为插槽内容进行渲染。
<teleport to="body">
<div @click="value = ''" class="FlatInput-Completion" ref="completionWrapper">
<div v-wave class="FlatInput-Completion-Item fake-background" :style="`--d: ${index * 0.125}s`" v-for="(item, index) in _res" :key="item">
<slot :item="item">
{{ item }}
</slot>
</div>
</div>
</teleport>
在样式中,我们使用 position: absolute
将下拉框定位到合适的位置,并使用 max-height
控制下拉框的最大高度。同时,我们还使用了一些动画效果,实现了选项元素的渐入渐出效果。
- 最后补充所有的样式即可
<style lang="scss" scoped>
.FlatInput-Completion {
z-index: 100;
position: absolute;
display: flex;
padding: 10px;
flex-direction: column;
justify-content: center;
align-items: center;
max-height: 380px;
overflow: hidden;
transition: .5s cubic-bezier(0.785, 0.135, 0.150, 0.860);
.FlatInput-Completion-Item {
position: relative;
margin: 5px 0;
padding: 10px;
cursor: pointer;
width: max-content;
opacity: 0;
animation: fade-in .5s var(--d) cubic-bezier(0.785, 0.135, 0.150, 0.860) forwards;
transition: .5s cubic-bezier(0.785, 0.135, 0.150, 0.860);
--fake-opacity: 0.5;
--fake-radius: 4px;
border-radius: var(--fake-radius);
box-sizing: border-box;
backdrop-filter: blur(16px) saturate(180%);
&:hover {
--fake-opacity: 0.8;
}
&.remove {
animation: fade-out .5s cubic-bezier(0.785, 0.135, 0.150, 0.860) forwards;
}
}
}
@keyframes fade-out {
from {
opacity: 1;
filter: blur(0);
transform: translateY(0) scaleY(1);
}
to {
opacity: 0;
filter: blur(10px);
transform: translateY(10px) scaleY(1.1);
}
}
@keyframes fade-in {
from {
opacity: 0;
filter: blur(10px);
transform: translateY(10px) scaleY(1.1);
}
to {
opacity: 1;
filter: blur(0);
transform: translateY(0) scaleY(1);
}
}
</style>
结语
完整的代码地址:github.com/talex-touch…
在本篇技术博客中,我向大家介绍了我开发的桌面软件TalexTouch里面的自动补全输入框。作为一个个人开发者,我花费了很多时间和精力来打磨这个项目,让它变得更加完美和实用。我相信TalexTouch可以成为你工作和生活中的得力助手,让你的桌面体验变得更加优美和高效。同时,我也希望这篇博客可以为其他开发者提供一些参考和启发,让我们一起为技术的进步和创新而努力!
Tip: 本篇文章部分内容由 GPT 引领而入
(「创新引领未来」——让我们一起探索人工智能的奥秘!)
转载自:https://juejin.cn/post/7225206098692472891