Files
lanecarford_front/src/views/asistant/components/GenerateLoading.vue
X1627315083 1b7694cee0
All checks were successful
git提交控制 AiDA WEB-Node.js main 分支构建部署 / build (20.19.0) (push) Has been skipped
Merge branch 'main' of ssh://18.167.251.121:10002/aidlab/lanecarford_front
2025-12-23 14:20:11 +08:00

157 lines
2.8 KiB
Vue

<template>
<div class="chat-loading">
<div class="loading-container flex flex-column flex-align-center">
<img src="@/assets/images/chat_loading.png" alt="Loading" class="loading-image" />
<!-- 阴影效果 -->
<div class="loading-shadow"></div>
<div class="loading-text" ref="textBox">
<span>{{ text }}</span>
<div class="loading-dot" ref="dotBox"></div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, watch, reactive, toRefs, nextTick, ref } from "vue";
import { gsap, TweenMax } from "gsap";
// 这个组件只负责显示loading动画
// 定义组件props类型
const props = defineProps({
title: {
type: String,
default: 'Analyzing the Outfit...'
}
})
const dotBox = ref(null)
const textBox = ref(null)
let tl1 = null;
const text = ref('')
watch(() => props.title, (newVal, oldVal) => {
if (newVal !== oldVal) {
destroyAnimation()
fadeOut(newVal)
}
})
function fadeOut(newVal) {
gsap.to(textBox.value,.5, {
opacity: 0,
duration: 1,
ease: "power2.in",
onComplete: () => {
// 消失后更换文字
text.value = newVal
// 然后出现
fadeIn();
}
});
}
// 出现动画
function fadeIn() {
gsap.to(textBox.value,.5, {
opacity: 1,
duration: 1,
onComplete:()=>{
setTl1();
}
});
}
const setTl1 = ()=>{
nextTick(()=>{
let el = dotBox.value
let width = el.offsetWidth + el.parentElement.offsetWidth
let time = el.parentElement.offsetWidth / 35
console.log(time,width)
tl1 = gsap.timeline();
tl1.to(el,time,
{
ease: "power1.in",
left:width,
onComplete:()=>{
setTimeout(() => {
tl1.restart()
}, 1000)
}
},
)
tl1.progress(0);
})
}
function destroyAnimation() {
if (tl1) {
tl1.progress(0);
tl1.kill();
tl1 = null;
}
}
onMounted(() => {
text.value = props.title
setTl1()
})
</script>
<style lang="less" scoped>
.chat-loading {
display: flex;
justify-content: flex-start;
}
.loading-container {
position: relative;
}
.loading-image {
width: 36.4rem;
height: 36.4rem;
animation: rotate 1s linear infinite;
}
.loading-shadow {
width: 19.6rem;
height: 5.2rem;
background-color: #d9d9d9;
border-radius: 50%;
filter: blur(35.5px);
margin-top: 5.1rem;
margin-bottom: 6.4rem;
}
.loading-text{
font-family: 'satoshiRegular';
font-size: 4.8rem;
letter-spacing: 0.02em;
line-height: 124%;
position: relative;
}
.loading-dot{
height: 100%;
aspect-ratio: 1/1;
background: radial-gradient(ellipse 150% 150% at center, #ffffff,rgba(255,255,255,.4), transparent);
border-radius: 50%;
position: absolute;
top: 50%;
left: 0;
transform: translate(-100%, -50%);
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>