768 investor 财务数据 滑动效果
This commit is contained in:
parent
af90a49f35
commit
e8c74caab7
@ -112,11 +112,30 @@
|
||||
委托书
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-2/3 font-normal text-[#9F9F9F]">
|
||||
<div
|
||||
class="bg-[#C6ACFF] color-[#fff] ma-[6px] px-[25px] py-[30px] font-semibold"
|
||||
class="w-2/3 font-normal text-[#9F9F9F] year-content-animation"
|
||||
ref="yearContent"
|
||||
@mouseenter="pauseYearInterval"
|
||||
@mouseleave="resumeYearInterval"
|
||||
@touchstart="handleTouchStart"
|
||||
@touchend="handleTouchEnd"
|
||||
@touchmove="handleTouchMove"
|
||||
@mousedown="handleMouseDown"
|
||||
@mouseup="handleMouseUp"
|
||||
@mousemove="handleMouseMove"
|
||||
>
|
||||
<div>2023年</div>
|
||||
<div
|
||||
class="color-[#fff] ma-[6px] px-[25px] py-[30px] font-semibold"
|
||||
:class="
|
||||
state.activeYear === 2021
|
||||
? 'bg-[#6520FA]'
|
||||
: state.activeYear === 2022
|
||||
? 'bg-[#8B59F7]'
|
||||
: 'bg-[#C6ACFF]'
|
||||
"
|
||||
>
|
||||
<div v-if="!isAnimating">{{ state.activeYear }}年</div>
|
||||
<div v-else> </div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-[#F8F9FF] ma-[6px] px-[25px] py-[30px] flex justify-between"
|
||||
@ -151,13 +170,13 @@
|
||||
<div>Q4</div>
|
||||
</div>
|
||||
<div class="bg-[#F8F9FF] ma-[6px] px-[25px] py-[30px]">
|
||||
<div>2023年</div>
|
||||
<div>{{ state.activeYear }}年</div>
|
||||
</div>
|
||||
<div class="bg-[#F8F9FF] ma-[6px] px-[25px] py-[30px]">
|
||||
<div>2023年</div>
|
||||
<div>{{ state.activeYear }}年</div>
|
||||
</div>
|
||||
<div class="bg-[#F8F9FF] ma-[6px] px-[25px] py-[30px]">
|
||||
<div>2023年</div>
|
||||
<div>{{ state.activeYear }}年</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -399,8 +418,233 @@ const state = reactive({
|
||||
link: "",
|
||||
},
|
||||
],
|
||||
activeYear: 2023,
|
||||
});
|
||||
|
||||
// 添加年份内容区域的引用
|
||||
const yearContent = ref(null);
|
||||
|
||||
// 添加动画状态控制变量
|
||||
const isAnimating = ref(false);
|
||||
|
||||
// 添加滑动方向变量
|
||||
const slideDirection = ref("left"); // 默认向左滑动
|
||||
|
||||
// 添加当前年份索引
|
||||
const currentYearIndex = ref(0);
|
||||
const yearArray = [2021, 2022, 2023];
|
||||
|
||||
// 添加触摸和鼠标事件相关变量
|
||||
const isPaused = ref(false);
|
||||
const touchStartX = ref(0);
|
||||
const mouseStartX = ref(0);
|
||||
const isMouseDown = ref(false);
|
||||
let interval = null;
|
||||
let pauseTimeout = null;
|
||||
|
||||
// 根据滑动方向创建动画并在完成后更新年份
|
||||
const animateYearChange = (direction, targetYear) => {
|
||||
if (!yearContent.value) return;
|
||||
|
||||
// 设置动画状态为进行中
|
||||
isAnimating.value = true;
|
||||
|
||||
const tl = gsap.timeline();
|
||||
|
||||
if (direction === "left") {
|
||||
// 向左滑动效果:从右向左
|
||||
tl.to(yearContent.value, {
|
||||
opacity: 0,
|
||||
x: -50,
|
||||
duration: 0.3,
|
||||
ease: "power2.inOut",
|
||||
})
|
||||
.set(yearContent.value, {
|
||||
x: 50,
|
||||
})
|
||||
.add(() => {
|
||||
// 在动画中间点更新年份值
|
||||
state.activeYear = targetYear;
|
||||
})
|
||||
.to(yearContent.value, {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
duration: 0.3,
|
||||
ease: "power2.out",
|
||||
onComplete: () => {
|
||||
// 动画完成后,设置动画状态为完成
|
||||
isAnimating.value = false;
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// 向右滑动效果:从左向右
|
||||
tl.to(yearContent.value, {
|
||||
opacity: 0,
|
||||
x: 50,
|
||||
duration: 0.3,
|
||||
ease: "power2.inOut",
|
||||
})
|
||||
.set(yearContent.value, {
|
||||
x: -50,
|
||||
})
|
||||
.add(() => {
|
||||
// 在动画中间点更新年份值
|
||||
state.activeYear = targetYear;
|
||||
})
|
||||
.to(yearContent.value, {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
duration: 0.3,
|
||||
ease: "power2.out",
|
||||
onComplete: () => {
|
||||
// 动画完成后,设置动画状态为完成
|
||||
isAnimating.value = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 开始年份切换定时器
|
||||
const startYearInterval = () => {
|
||||
if (interval) clearInterval(interval);
|
||||
interval = setInterval(() => {
|
||||
if (!isPaused.value) {
|
||||
nextYear();
|
||||
}
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
// 切换到下一个年份
|
||||
const nextYear = () => {
|
||||
slideDirection.value = "left"; // 设置滑动方向为左滑
|
||||
const nextIndex = (currentYearIndex.value + 1) % yearArray.length;
|
||||
const nextYearValue = yearArray[nextIndex];
|
||||
|
||||
// 先执行动画,动画完成后会更新 activeYear
|
||||
animateYearChange("left", nextYearValue);
|
||||
|
||||
// 更新索引
|
||||
currentYearIndex.value = nextIndex;
|
||||
};
|
||||
|
||||
// 切换到上一个年份
|
||||
const prevYear = () => {
|
||||
slideDirection.value = "right"; // 设置滑动方向为右滑
|
||||
const prevIndex =
|
||||
(currentYearIndex.value - 1 + yearArray.length) % yearArray.length;
|
||||
const prevYearValue = yearArray[prevIndex];
|
||||
|
||||
// 先执行动画,动画完成后会更新 activeYear
|
||||
animateYearChange("right", prevYearValue);
|
||||
|
||||
// 更新索引
|
||||
currentYearIndex.value = prevIndex;
|
||||
};
|
||||
|
||||
// 暂停年份切换
|
||||
const pauseYearInterval = () => {
|
||||
isPaused.value = true;
|
||||
};
|
||||
|
||||
// 恢复年份切换
|
||||
const resumeYearInterval = () => {
|
||||
isPaused.value = false;
|
||||
};
|
||||
|
||||
// 暂停一段时间后恢复
|
||||
const pauseForDuration = (duration = 3000) => {
|
||||
pauseYearInterval();
|
||||
|
||||
// 清除之前的定时器(如果存在)
|
||||
if (pauseTimeout) {
|
||||
clearTimeout(pauseTimeout);
|
||||
}
|
||||
|
||||
// 设置新的定时器
|
||||
pauseTimeout = setTimeout(() => {
|
||||
resumeYearInterval();
|
||||
}, duration);
|
||||
};
|
||||
|
||||
// 处理触摸开始事件
|
||||
const handleTouchStart = (event) => {
|
||||
pauseYearInterval();
|
||||
touchStartX.value = event.touches[0].clientX;
|
||||
};
|
||||
|
||||
// 处理触摸结束事件
|
||||
const handleTouchEnd = () => {
|
||||
// 不立即恢复,而是等待一段时间
|
||||
// resumeYearInterval();
|
||||
};
|
||||
|
||||
// 处理触摸移动事件
|
||||
const handleTouchMove = (event) => {
|
||||
if (touchStartX.value === 0) return;
|
||||
|
||||
const touchEndX = event.touches[0].clientX;
|
||||
const diffX = touchEndX - touchStartX.value;
|
||||
|
||||
// 如果滑动距离足够大,切换年份
|
||||
if (Math.abs(diffX) > 50) {
|
||||
if (diffX < 0) {
|
||||
// 向左滑动,下一年
|
||||
slideDirection.value = "left";
|
||||
nextYear();
|
||||
} else {
|
||||
// 向右滑动,上一年
|
||||
slideDirection.value = "right";
|
||||
prevYear();
|
||||
}
|
||||
touchStartX.value = 0; // 重置起始位置,防止连续触发
|
||||
|
||||
// 滑动切换后暂停一段时间
|
||||
pauseForDuration();
|
||||
}
|
||||
};
|
||||
|
||||
// 处理鼠标按下事件
|
||||
const handleMouseDown = (event) => {
|
||||
isMouseDown.value = true;
|
||||
mouseStartX.value = event.clientX;
|
||||
pauseYearInterval();
|
||||
};
|
||||
|
||||
// 处理鼠标抬起事件
|
||||
const handleMouseUp = () => {
|
||||
isMouseDown.value = false;
|
||||
// 不立即恢复,等待一段时间后恢复
|
||||
// resumeYearInterval();
|
||||
};
|
||||
|
||||
// 处理鼠标移动事件
|
||||
const handleMouseMove = (event) => {
|
||||
if (!isMouseDown.value || mouseStartX.value === 0) return;
|
||||
|
||||
const mouseEndX = event.clientX;
|
||||
const diffX = mouseEndX - mouseStartX.value;
|
||||
|
||||
// 如果滑动距离足够大,切换年份
|
||||
if (Math.abs(diffX) > 50) {
|
||||
if (diffX < 0) {
|
||||
// 向左滑动,下一年
|
||||
slideDirection.value = "left";
|
||||
nextYear();
|
||||
} else {
|
||||
// 向右滑动,上一年
|
||||
slideDirection.value = "right";
|
||||
prevYear();
|
||||
}
|
||||
mouseStartX.value = 0; // 重置起始位置,防止连续触发
|
||||
|
||||
// 滑动切换后暂停一段时间
|
||||
pauseForDuration();
|
||||
}
|
||||
};
|
||||
|
||||
// 启动年份切换定时器
|
||||
startYearInterval();
|
||||
|
||||
const carouselTrack = ref(null);
|
||||
let carouselAnimation = null; // 存储 GSAP 动画实例
|
||||
|
||||
@ -477,6 +721,12 @@ onUnmounted(() => {
|
||||
if (carouselAnimation) {
|
||||
carouselAnimation.kill();
|
||||
}
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
if (pauseTimeout) {
|
||||
clearTimeout(pauseTimeout);
|
||||
}
|
||||
});
|
||||
|
||||
import { useRouter } from "vue-router";
|
||||
@ -655,4 +905,10 @@ const handleLink = (url) => {
|
||||
border-radius: 20px 0 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加过渡样式
|
||||
.year-content-animation {
|
||||
position: relative;
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user