浏览代码

更新ESLint配置以关闭属性换行规则;修改index.html文件以移除动态标题;更新rspack配置以使用package.json中的项目名称作为页面标题;替换ParallaxBackground组件中的背景图;重构首页组件,增加滚动监听和动画效果,优化导航栏样式以适应滚动状态。

xbx 1 周之前
父节点
当前提交
3093831583

+ 2 - 1
config/rspack.base.config.ts

@@ -7,6 +7,7 @@ import sassEmbedded from 'sass-embedded';
 import ESLintPlugin from 'eslint-rspack-plugin';
 // import Components from 'unplugin-vue-components/rspack';
 import AutoImportPlugin from 'unplugin-auto-import/rspack';
+import packageJson from '../package.json';
 
 // 目标浏览器配置
 const targets = ['last 2 versions', '> 0.2%', 'not dead', 'Firefox ESR'];
@@ -126,7 +127,7 @@ export const baseConfig = {
     }),
     new rspack.HtmlRspackPlugin({
       template: './index.html',
-      title: '声音AI平台',
+      title: packageJson.name || '声音AI平台',
       // favicon: path.resolve(__dirname, '../public/favicon.ico'),
       meta: {
         description: '声音AI平台 - 专业的声音处理与分析工具',

+ 2 - 0
eslint.config.mjs

@@ -95,6 +95,7 @@ export default defineConfigWithVueTs(
     rules: {
       // Vue特定规则
       'vue/multi-word-component-names': 'off', // 关闭组件名必须是多词的规则
+      'vue/first-attribute-linebreak': 'off', // 关闭属性换行规则
       'vue/no-unused-vars': 'off', // 关闭未使用变量的警告
       'vue/html-self-closing': ['warn', {
         html: {
@@ -107,6 +108,7 @@ export default defineConfigWithVueTs(
         singleline: 3,
         multiline: 1
       }],
+      'vue/first-attribute-linebreak': 'off', // 关闭属性换行规则
       // 通用规则
       'no-console': 'off', // 关闭控制台语句的警告
       'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',

+ 0 - 2
index.html

@@ -9,8 +9,6 @@
 		<meta name="apple-mobile-web-app-capable" content="yes" />
 		<meta name="apple-mobile-web-app-status-bar-style" content="black" />
 		<meta name="theme-color" content="#ffffff" />
-		
-		<title><%= htmlWebpackPlugin.options.title %></title>
 	</head>
 	<body>
 		<div id="app"></div>

二进制
src/assets/imgs/home/bg1.png


二进制
src/assets/imgs/home/bg2.png


+ 27 - 64
src/views/home/components/ParallaxBackground.vue

@@ -1,84 +1,47 @@
 <template>
-  <div ref="containerRef" class="absolute inset-0 overflow-hidden">
+  <div ref="containerRef" class="fixed inset-0 overflow-hidden">
+    
     <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>
 </template>
 <script setup lang="ts">
 import { useScroll, useTransform, Motion } from 'motion-v';
 import { ref, computed } from 'vue';
-import bg1 from '@/assets/imgs/home/bg1.png';
+import bg2 from '@/assets/imgs/home/bg2.png';
 
 defineOptions({
   name: 'ParallaxBackground',
 });
 
-interface ParallaxBackgroundProps {
-  images: string[];
-}
-//内容容器
+// 内容容器
 const containerRef = ref<HTMLElement | null>(null);
 
-//照片地址后期换cdn
-const images = ref<string[]>([bg1]);
-
-//vue-motion
+// 滚动监听,监控整个文档的滚动
 const { scrollYProgress } = useScroll({
-  target: containerRef,
   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>
+<style lang="scss" scoped></style>

+ 39 - 9
src/views/home/components/nav.vue

@@ -1,16 +1,26 @@
 <template>
   <nav
-    class="home-nav fixed top-0 left-0 right-0 z-50 bg-white/80 backdrop-blur-md shadow-sm"
+    ref="navRef"
+    :class="[
+      'home-nav fixed top-0 left-0 right-0 z-50 transition-all duration-300',
+      isScrolled ? 'bg-white/40 backdrop-blur-lg shadow-sm  border-white/20' : 'bg-transparent'
+    ]"
   >
     <div class="container mx-auto px-6 py-4 flex justify-between items-center">
-      <div class="text-xl font-bold text-blue-600">ZW多人语音合成</div>
+      <div class="text-xl font-bold" :class="isScrolled ? 'text-blue-600' : 'text-white'">ZW多人语音合成</div>
 
       <ul class="flex items-center space-x-6">
-        <li class="text-gray-600 hover:text-blue-500 transition cursor-pointer">
+        <li :class="[
+          'transition cursor-pointer', 
+          isScrolled ? 'text-gray-800 hover:text-blue-500' : 'text-white/90 hover:text-white'
+        ]">
           产品列表
         </li>
 
-        <li class="text-gray-600 hover:text-blue-500 transition cursor-pointer">
+        <li :class="[
+          'transition cursor-pointer', 
+          isScrolled ? 'text-gray-800 hover:text-blue-500' : 'text-white/90 hover:text-white'
+        ]">
           关于我们
         </li>
 
@@ -18,18 +28,38 @@
       </ul>
     </div>
   </nav>
-
-  <div>  我是导航栏</div>
 </template>
 <script lang="ts" setup>
 import { Button } from 'ant-design-vue';
+import { ref, onMounted, onUnmounted } from 'vue';
 
 defineOptions({
   name: 'HomeNav',
 });
-</script>
-<style lang="sass" scoped>
-.home-nav{
 
+const navRef = ref<HTMLElement | null>(null);
+const isScrolled = ref(false);
+const scrollThreshold = 60; // 滚动阈值,超过60px后改变样式
+
+// 监听滚动事件
+const handleScroll = () => {
+  isScrolled.value = window.scrollY > scrollThreshold;
+};
+
+onMounted(() => {
+  // 监听滚动事件
+  window.addEventListener('scroll', handleScroll);
+  // 初始检查
+  handleScroll();
+});
+
+onUnmounted(() => {
+  // 移除滚动监听
+  window.removeEventListener('scroll', handleScroll);
+});
+</script>
+<style lang="scss" scoped>
+.home-nav {
+  transition: all 0.3s ease;
 }
 </style>

+ 130 - 0
src/views/home/components/topAnime.vue

@@ -0,0 +1,130 @@
+<template>
+  <section class="h-[100vh] flex items-center w-full">
+    <Motion
+      class="top-anime flex flex-col items-center justify-center text-center w-full h-full"
+      as="div"
+      :initial="{
+        opacity: 0,
+        y: 30,
+      }"
+      :animate="isLoaded ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }"
+      :transition="{
+        duration: 1.2,
+        ease: 'easeOut',
+        delay: 0.3,
+      }"
+    >
+      <h1
+        class="text-5xl md:text-6xl font-bold text-center text-white mb-8 drop-shadow-lg"
+      >
+        让文字自然发声
+      </h1>
+      
+      <!-- 波浪特效 -->
+      <div
+        class="relative h-52 w-full max-w-2xl flex items-end justify-center space-x-1.5 mb-12"
+      >
+        <Motion
+          v-for="(bar, index) in waveConfig"
+          :key="index"
+          class="rounded-t-lg"
+          :animate="bar.animateState"
+          :transition="{
+            duration: bar.duration,
+            repeat: Infinity,
+            repeatType: 'mirror',
+            delay: bar.delay,
+            ease: 'easeInOut'
+          }"
+          :style="{
+            width: `${bar.width}px`,
+            height: '30%',
+            backgroundColor: `rgba(255, 255, 255, ${0.7 + (index % 5) * 0.06})`,
+          }"
+        />
+      </div>
+      <h1 class="text-5xl md:text-6xl font-bold text-center text-white mb-8 drop-shadow-lg" mt-6>为您提供自然流畅的语音合成服务</h1>
+    </Motion>
+  </section>
+</template>
+
+<script setup lang="ts">
+import { Motion } from 'motion-v';
+import { ref, onMounted, computed } from 'vue';
+
+defineOptions({
+  name: 'TopAnime',
+});
+
+const containerRef = ref<HTMLElement | null>(null);
+const isLoaded = ref(false);
+
+// 生成波形配置
+const waveConfig = computed(() => {
+  const bars = [];
+  const totalBars = 45;
+  
+  for (let i = 0; i < totalBars; i++) {
+    // 生成不同高度的随机值,使波形看起来更自然
+    const minHeight = 20 + (i % 3) * 5; // 基础最小高度
+    const maxHeight = 65 + (i % 5) * 8; // 增加最大高度
+    
+    // 在中间位置创建一个波峰
+    const positionFactor = Math.abs((i - totalBars / 2) / (totalBars / 2));
+    const heightModifier = 1 - positionFactor * 0.5; // 中间高,两边低
+    
+    // 波形宽度,中间的柱子更宽一些
+    const width = 6 + (1 - positionFactor) * 3;
+    
+    bars.push({
+      // 自动动画状态
+      animateState: {
+        height: [
+          `${minHeight * heightModifier}%`,
+          `${maxHeight * heightModifier}%`,
+          `${minHeight * heightModifier}%`,
+        ],
+      },
+      // 动画参数
+      duration: 1.0 + Math.random() * 0.8,
+      delay: i * 0.02,
+      width: width
+    });
+  }
+  
+  return bars;
+});
+
+// 页面加载完成后触发动画
+onMounted(() => {
+  // 等待资源加载完成
+  window.addEventListener('load', startAnimation);
+
+  // 如果页面已经加载完毕,或者2秒后仍未触发load事件,则直接开始动画
+  if (document.readyState === 'complete') {
+    startAnimation();
+  } else {
+    setTimeout(startAnimation, 2000);
+  }
+});
+
+function startAnimation() {
+  // 移除可能重复的监听器
+  window.removeEventListener('load', startAnimation);
+
+  // 开始动画
+  isLoaded.value = true;
+}
+</script>
+
+<style lang="scss" scoped>
+.top-anime {
+  h1 {
+    background: linear-gradient(135deg, #ffffff, #e0e0ff);
+    -webkit-background-clip: text;
+    background-clip: text;
+    -webkit-text-fill-color: transparent;
+    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
+  }
+}
+</style>

+ 128 - 2
src/views/home/index.vue

@@ -1,10 +1,136 @@
 <template>
-  <div class="min-h-screen flex flex-col relative w-full" style="height: 300vh;">
+  <div class="relative w-full home-page">
+    <!-- 导航栏 -->
     <HomeNav />
+    <!-- 视差背景 -->
     <ParallaxBackground />
-  </div>
+   
+     <!-- 第一屏动画-->
+     <TopAnime />
+
+      <!-- 第一个section - 主视觉区域 -->
+     <!--  <section class="min-h-screen flex items-center">
+        <div class="container mx-auto px-6">
+          <div class="text-4xl font-bold text-white mb-4">声音AI平台</div>
+          <div class="text-xl text-white/80 max-w-2xl mb-8">
+            专业的声音处理与分析工具,为您提供高质量的音频解决方案
+          </div>
+          <button
+            class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg font-medium transition"
+          >
+            了解更多
+          </button>
+        </div>
+      </section> -->
+
+      <!-- 第二个section - 半透明过渡区 -->
+     <!--  <section
+        class="min-h-screen flex items-center bg-white/10 backdrop-blur-sm"
+      >
+        <div class="container mx-auto px-6">
+          <div class="max-w-4xl">
+            <div class="text-3xl font-bold text-white mb-6">
+              多人语音合成技术
+            </div>
+            <div class="text-lg text-white/80 mb-10">
+              我们的多人语音合成技术采用先进的AI算法,能够精准模拟多种声音特征和语气,为您的项目提供自然、流畅的语音合成服务。无论是需要多角色对话、情感丰富的表达,还是特定场景的语音应用,我们都能满足您的需求。
+            </div>
+            <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
+              <div class="bg-white/20 backdrop-blur p-6 rounded-lg">
+                <div class="text-xl font-bold text-white mb-3">高质量合成</div>
+                <div class="text-white/70">
+                  采用最新深度学习技术,声音自然真实
+                </div>
+              </div>
+              <div class="bg-white/20 backdrop-blur p-6 rounded-lg">
+                <div class="text-xl font-bold text-white mb-3">多语言支持</div>
+                <div class="text-white/70">支持中英文等多种语言的语音合成</div>
+              </div>
+              <div class="bg-white/20 backdrop-blur p-6 rounded-lg">
+                <div class="text-xl font-bold text-white mb-3">个性化定制</div>
+                <div class="text-white/70">可根据需求定制专属声音</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section> -->
+
+      <!-- 第三个section - 白底部分 -->
+     <!--  <section class="min-h-screen bg-white relative z-20 pt-24">
+        <div class="container mx-auto px-6">
+          <div class="max-w-4xl">
+            <div class="text-3xl font-bold text-gray-800 mb-6">
+              先进的技术框架
+            </div>
+            <div class="text-lg text-gray-600 mb-8">
+              我们的平台采用最先进的技术栈构建,确保高效、稳定的性能表现。从前端到后端,每一个环节都经过精心优化,为用户提供极致的体验。
+            </div>
+            <div class="grid grid-cols-2 gap-4 mb-10">
+              <div
+                class="flex items-center space-x-3 bg-gray-100 p-4 rounded-lg"
+              >
+                <div class="w-3 h-3 bg-blue-500 rounded-full"></div>
+                <div class="text-gray-800">先进的神经网络模型</div>
+              </div>
+              <div
+                class="flex items-center space-x-3 bg-gray-100 p-4 rounded-lg"
+              >
+                <div class="w-3 h-3 bg-blue-500 rounded-full"></div>
+                <div class="text-gray-800">高效的声音处理算法</div>
+              </div>
+              <div
+                class="flex items-center space-x-3 bg-gray-100 p-4 rounded-lg"
+              >
+                <div class="w-3 h-3 bg-blue-500 rounded-full"></div>
+                <div class="text-gray-800">低延迟实时合成</div>
+              </div>
+              <div
+                class="flex items-center space-x-3 bg-gray-100 p-4 rounded-lg"
+              >
+                <div class="w-3 h-3 bg-blue-500 rounded-full"></div>
+                <div class="text-gray-800">云端API服务</div>
+              </div>
+            </div>
+            <button
+              class="border border-blue-500 text-blue-500 hover:bg-blue-50 px-6 py-3 rounded-lg font-medium transition"
+            >
+              技术详情
+            </button>
+          </div>
+        </div>
+      </section> -->
+    </div>
+  
 </template>
 <script setup lang="ts">
 import HomeNav from './components/nav.vue';
 import ParallaxBackground from './components/ParallaxBackground.vue';
+import TopAnime from './components/topAnime.vue';
+import { onMounted, onUnmounted } from 'vue';
+
+// 页面进入时隐藏滚动条
+onMounted(() => {
+  // 保存原始滚动条样式
+  const originalStyle = document.body.style.overflow;
+
+  // 隐藏滚动条
+  document.documentElement.style.setProperty('scrollbar-width', 'none'); // Firefox
+
+  document.body.style.overflow = 'auto'; // 保持可以滚动
+
+  // 在组件销毁时恢复滚动条
+  onUnmounted(() => {
+    // 恢复原始滚动条样式
+    document.body.style.overflow = originalStyle;
+    document.documentElement.style.removeProperty('scrollbar-width');
+  });
+});
 </script>
+<style lang="scss" scoped>
+.home-page {
+  /* 组件级别的滚动条隐藏 */
+  &::-webkit-scrollbar {
+    display: none;
+  }
+}
+</style>