|
@@ -1,84 +1,47 @@
|
|
<template>
|
|
<template>
|
|
- <div ref="containerRef" class="absolute inset-0 overflow-hidden">
|
|
|
|
|
|
+ <div ref="containerRef" class="fixed inset-0 overflow-hidden">
|
|
|
|
+
|
|
<Motion
|
|
<Motion
|
|
- v-for="(image, index) in images"
|
|
|
|
- :key="index"
|
|
|
|
- class="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
|
|
|
- :style="getImageStyle(image, index)"
|
|
|
|
|
|
+ class="absolute inset-0 bg-cover bg-no-repeat"
|
|
|
|
+ :style="backgroundStyle"
|
|
|
|
+ />
|
|
|
|
+
|
|
|
|
+ <div
|
|
|
|
+ class="absolute inset-0 bg-gradient-to-b from-c via-transparent to-white z-0"
|
|
/>
|
|
/>
|
|
-
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
import { useScroll, useTransform, Motion } from 'motion-v';
|
|
import { useScroll, useTransform, Motion } from 'motion-v';
|
|
import { ref, computed } from 'vue';
|
|
import { ref, computed } from 'vue';
|
|
-import bg1 from '@/assets/imgs/home/bg1.png';
|
|
|
|
|
|
+import bg2 from '@/assets/imgs/home/bg2.png';
|
|
|
|
|
|
defineOptions({
|
|
defineOptions({
|
|
name: 'ParallaxBackground',
|
|
name: 'ParallaxBackground',
|
|
});
|
|
});
|
|
|
|
|
|
-interface ParallaxBackgroundProps {
|
|
|
|
- images: string[];
|
|
|
|
-}
|
|
|
|
-//内容容器
|
|
|
|
|
|
+// 内容容器
|
|
const containerRef = ref<HTMLElement | null>(null);
|
|
const containerRef = ref<HTMLElement | null>(null);
|
|
|
|
|
|
-//照片地址后期换cdn
|
|
|
|
-const images = ref<string[]>([bg1]);
|
|
|
|
-
|
|
|
|
-//vue-motion
|
|
|
|
|
|
+// 滚动监听,监控整个文档的滚动
|
|
const { scrollYProgress } = useScroll({
|
|
const { scrollYProgress } = useScroll({
|
|
- target: containerRef,
|
|
|
|
offset: ['start start', 'end start'],
|
|
offset: ['start start', 'end start'],
|
|
});
|
|
});
|
|
|
|
|
|
-// 获取视差百分比,实现阶梯式效果
|
|
|
|
-const getParallaxPercentage = (index: number): string => {
|
|
|
|
- // 预定义的阶梯式百分比
|
|
|
|
- const percentages = ['50%', '30%', '10%'];
|
|
|
|
-
|
|
|
|
- // 如果索引在预定义范围内,直接返回对应百分比
|
|
|
|
- if (index < percentages.length) {
|
|
|
|
- return percentages[index];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 对于超出预定义范围的索引,使用递减公式
|
|
|
|
- // 从10%开始,每增加一个索引,减少2%,但不低于0%
|
|
|
|
- const percentage = Math.max(10 - (index - 2) * 2, 0);
|
|
|
|
- return `${percentage}%`;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-// 创建图片样式对象
|
|
|
|
-const imageStyles = ref<Record<number, any>>({});
|
|
|
|
-
|
|
|
|
-// 初始化每个图片的样式
|
|
|
|
-images.value.forEach((image, index) => {
|
|
|
|
- // 为每个图层创建不同的变换速度,使用阶梯式百分比
|
|
|
|
- const yTransform = useTransform(
|
|
|
|
- scrollYProgress,
|
|
|
|
- [0, 1],
|
|
|
|
- ['0%', getParallaxPercentage(index)]
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- // 将变换值存储到样式对象中
|
|
|
|
- imageStyles.value[index] = {
|
|
|
|
- backgroundImage: `url(${image})`,
|
|
|
|
- y: yTransform,
|
|
|
|
- height: `${100 - index * 10}%`,
|
|
|
|
- zIndex: -index - 1,
|
|
|
|
- filter: 'brightness(0.7) contrast(1.1)',
|
|
|
|
- backgroundSize: 'contain',
|
|
|
|
- backgroundPosition: 'center',
|
|
|
|
- };
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-// 获取特定图片的样式
|
|
|
|
-const getImageStyle = (image: string, index: number) => {
|
|
|
|
- return (
|
|
|
|
- imageStyles.value[index] || {
|
|
|
|
- backgroundImage: `url(${image})`,
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
-};
|
|
|
|
|
|
+// 视差效果 - 大幅增加位移距离,向上移动
|
|
|
|
+const parallaxY = useTransform(
|
|
|
|
+ scrollYProgress,
|
|
|
|
+ [0, 1],
|
|
|
|
+ ['0%', '-50%'], // 增大位移距离到50%
|
|
|
|
+);
|
|
|
|
+
|
|
|
|
+// 背景图样式
|
|
|
|
+const backgroundStyle = computed(() => ({
|
|
|
|
+ backgroundImage: `url(${bg2})`,
|
|
|
|
+ y: parallaxY,
|
|
|
|
+ backgroundPosition: 'center top',
|
|
|
|
+ backgroundSize: 'cover',
|
|
|
|
+ height: '140%', // 图片高度超过容器
|
|
|
|
+}));
|
|
</script>
|
|
</script>
|
|
|
|
+<style lang="scss" scoped></style>
|