320 lines
12 KiB
Vue
320 lines
12 KiB
Vue
<script setup>
|
||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||
import { RouterLink } from 'vue-router'
|
||
import { ArrowLeft, ArrowRight, Calendar, CheckCircle2, Clock3, Play, ShieldCheck, Sparkles, Star } from 'lucide-vue-next'
|
||
import { homeCaseCards, homeMarqueeItems, homeServiceItems, metrics, siteConfig } from '@/site.config'
|
||
import AnimatedContent from '@/components/vue-bits/AnimatedContent.vue'
|
||
import DecryptedText from '@/components/vue-bits/DecryptedText.vue'
|
||
import BlurText from '@/components/vue-bits/BlurText.vue'
|
||
import Magnet from '@/components/vue-bits/Magnet.vue'
|
||
import Silk from '@/components/vue-bits/Silk.vue'
|
||
import SplitText from '@/components/vue-bits/SplitText.vue'
|
||
|
||
const aboutRef = ref(null)
|
||
const aboutProgress = ref(0)
|
||
|
||
const aboutSegments = [
|
||
'萧康云医把患者、医生、机构和运营管理连接成同一个实时协作系统。',
|
||
'我们服务医共体、医疗集团、互联网医院与连锁诊所,',
|
||
'让复杂的医疗流程在云端变得更轻、更稳、更可信。'
|
||
]
|
||
|
||
const marqueeRowOne = computed(() => homeMarqueeItems.slice(0, 3))
|
||
const marqueeRowTwo = computed(() => homeMarqueeItems.slice(3))
|
||
const repeatedRowOne = computed(() => [...marqueeRowOne.value, ...marqueeRowOne.value, ...marqueeRowOne.value])
|
||
const repeatedRowTwo = computed(() => [...marqueeRowTwo.value, ...marqueeRowTwo.value, ...marqueeRowTwo.value])
|
||
|
||
let ticking = false
|
||
let reduceMotion = false
|
||
|
||
function updateScrollMotion() {
|
||
ticking = false
|
||
if (reduceMotion) return
|
||
|
||
if (aboutRef.value) {
|
||
const rect = aboutRef.value.getBoundingClientRect()
|
||
const distance = window.innerHeight * 0.78 - rect.top
|
||
const range = rect.height + window.innerHeight * 0.2
|
||
aboutProgress.value = Math.min(1, Math.max(0, distance / range))
|
||
}
|
||
}
|
||
|
||
function requestScrollUpdate() {
|
||
if (ticking) return
|
||
ticking = true
|
||
window.requestAnimationFrame(updateScrollMotion)
|
||
}
|
||
|
||
function segmentOpacity(index) {
|
||
if (reduceMotion) return 1
|
||
const start = index / aboutSegments.length
|
||
const progress = (aboutProgress.value - start) * 2.6
|
||
return Math.min(1, Math.max(0.5, progress))
|
||
}
|
||
|
||
onMounted(() => {
|
||
reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||
updateScrollMotion()
|
||
window.addEventListener('scroll', requestScrollUpdate, { passive: true })
|
||
window.addEventListener('resize', requestScrollUpdate)
|
||
})
|
||
|
||
onBeforeUnmount(() => {
|
||
window.removeEventListener('scroll', requestScrollUpdate)
|
||
window.removeEventListener('resize', requestScrollUpdate)
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<main class="home-page">
|
||
<section class="cinematic-hero">
|
||
<video
|
||
class="cinematic-video"
|
||
autoplay
|
||
muted
|
||
loop
|
||
playsinline
|
||
:poster="siteConfig.hero.video.poster"
|
||
>
|
||
<source :src="siteConfig.hero.video.src" type="video/mp4">
|
||
</video>
|
||
<div class="hero-silk-layer" aria-hidden="true">
|
||
<Silk color="#14B8A6" :speed="2.6" :scale="1.2" :noise-intensity="0.78" :rotation="0.16" />
|
||
</div>
|
||
<div class="bottom-blur-overlay" aria-hidden="true"></div>
|
||
|
||
<div class="cinematic-content">
|
||
<div class="hero-copy">
|
||
<div class="hero-meta animate-blur-fade-up" style="animation-delay: 300ms">
|
||
<span>
|
||
<Star :size="16" fill="currentColor" aria-hidden="true" />
|
||
99.95% SLA
|
||
</span>
|
||
<span>
|
||
<Clock3 :size="16" aria-hidden="true" />
|
||
7x24 医疗级运维
|
||
</span>
|
||
<span>
|
||
<Calendar :size="16" aria-hidden="true" />
|
||
2026 云医协同平台
|
||
</span>
|
||
</div>
|
||
|
||
<BlurText
|
||
:text="siteConfig.brand.name"
|
||
tag="h1"
|
||
class-name="cinematic-title"
|
||
animate-by="chars"
|
||
direction="bottom"
|
||
:delay="90"
|
||
:duration="980"
|
||
:threshold="0.05"
|
||
root-margin="0px"
|
||
/>
|
||
<p class="cinematic-subtitle animate-blur-fade-up" style="animation-delay: 500ms">
|
||
<DecryptedText
|
||
text="Step Through. Work Smarter."
|
||
animate-on="view"
|
||
reveal-direction="center"
|
||
:speed="34"
|
||
:max-iterations="12"
|
||
encrypted-class-name="decrypted-ghost"
|
||
class-name="decrypted-final"
|
||
/>
|
||
<span> 让区域诊疗、慢病随访、远程会诊和运营治理在云端自然协作。</span>
|
||
</p>
|
||
|
||
<div class="hero-actions">
|
||
<Magnet :padding="80" :magnet-strength="5" wrapper-class-name="animate-blur-fade-up" style="animation-delay: 600ms">
|
||
<RouterLink to="/product#contact" class="watch-button">
|
||
<Play :size="18" fill="currentColor" aria-hidden="true" />
|
||
免费试用
|
||
</RouterLink>
|
||
</Magnet>
|
||
<Magnet :padding="72" :magnet-strength="5.5" wrapper-class-name="animate-blur-fade-up" style="animation-delay: 700ms">
|
||
<RouterLink to="/product#demo" class="learn-button liquid-glass">
|
||
观看演示
|
||
</RouterLink>
|
||
</Magnet>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hero-arrows">
|
||
<Magnet :padding="64" :magnet-strength="6" wrapper-class-name="animate-blur-fade-up" style="animation-delay: 800ms">
|
||
<RouterLink to="/#business" class="arrow-pill liquid-glass">
|
||
<ArrowLeft :size="18" aria-hidden="true" />
|
||
业务介绍
|
||
</RouterLink>
|
||
</Magnet>
|
||
<Magnet :padding="64" :magnet-strength="6" wrapper-class-name="animate-blur-fade-up" style="animation-delay: 900ms">
|
||
<RouterLink to="/product" class="arrow-pill liquid-glass">
|
||
产品页
|
||
<ArrowRight :size="18" aria-hidden="true" />
|
||
</RouterLink>
|
||
</Magnet>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="business" class="home-marquee-section">
|
||
<AnimatedContent class-name="marquee-heading" :distance="44" :duration="0.9" ease="power3.out">
|
||
<span>Business Flow</span>
|
||
<h2 class="mega-heading home-heading-cn">云端医疗协同现场</h2>
|
||
</AnimatedContent>
|
||
|
||
<div class="marquee-rows" aria-label="萧康云医业务场景">
|
||
<div class="marquee-track marquee-track-forward">
|
||
<article v-for="(item, index) in repeatedRowOne" :key="`${item.title}-top-${index}`" class="marquee-card glare-card">
|
||
<img :src="item.image" :alt="item.title" loading="lazy">
|
||
<div>
|
||
<span>{{ item.meta }}</span>
|
||
<strong>{{ item.title }}</strong>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
<div class="marquee-track marquee-track-reverse">
|
||
<article v-for="(item, index) in repeatedRowTwo" :key="`${item.title}-bottom-${index}`" class="marquee-card glare-card">
|
||
<img :src="item.image" :alt="item.title" loading="lazy">
|
||
<div>
|
||
<span>{{ item.meta }}</span>
|
||
<strong>{{ item.title }}</strong>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="intro" ref="aboutRef" class="creator-about-section">
|
||
<div class="floating-medical-chip chip-a">
|
||
<Sparkles :size="20" aria-hidden="true" />
|
||
AI Alert
|
||
</div>
|
||
<div class="floating-medical-chip chip-b">
|
||
<ShieldCheck :size="20" aria-hidden="true" />
|
||
Data Safe
|
||
</div>
|
||
<div class="floating-medical-chip chip-c">
|
||
<CheckCircle2 :size="20" aria-hidden="true" />
|
||
Follow-up
|
||
</div>
|
||
<div class="floating-medical-chip chip-d">
|
||
<Star :size="20" aria-hidden="true" />
|
||
99.95%
|
||
</div>
|
||
|
||
<AnimatedContent class-name="about-inner" :distance="52" :duration="1" ease="power4.out">
|
||
<SplitText
|
||
text="关于萧康云医"
|
||
tag="h2"
|
||
class-name="mega-heading home-heading-cn"
|
||
split-type="lines"
|
||
:delay="80"
|
||
:duration="1"
|
||
ease="power3.out"
|
||
:from="{ opacity: 0, y: 34, filter: 'blur(12px)' }"
|
||
:to="{ opacity: 1, y: 0, filter: 'blur(0px)' }"
|
||
/>
|
||
<p class="animated-copy" aria-label="萧康云医介绍">
|
||
<span
|
||
v-for="(segment, index) in aboutSegments"
|
||
:key="segment"
|
||
class="about-segment"
|
||
:style="{ opacity: segmentOpacity(index) }"
|
||
>{{ segment }}</span>
|
||
</p>
|
||
<Magnet :padding="90" :magnet-strength="5">
|
||
<RouterLink to="/product#contact" class="creator-contact-button">联系顾问</RouterLink>
|
||
</Magnet>
|
||
</AnimatedContent>
|
||
</section>
|
||
|
||
<section class="creator-services-section">
|
||
<SplitText
|
||
text="Services"
|
||
tag="h2"
|
||
class-name="services-heading"
|
||
split-type="chars"
|
||
:delay="42"
|
||
:duration="0.9"
|
||
ease="power3.out"
|
||
:from="{ opacity: 0, y: 46, filter: 'blur(12px)' }"
|
||
:to="{ opacity: 1, y: 0, filter: 'blur(0px)' }"
|
||
/>
|
||
<div class="services-list">
|
||
<AnimatedContent
|
||
v-for="(item, index) in homeServiceItems"
|
||
:key="item.number"
|
||
class-name="service-reveal"
|
||
:distance="56"
|
||
direction="horizontal"
|
||
:reverse="index % 2 === 1"
|
||
:delay="index * 0.08"
|
||
:duration="0.85"
|
||
>
|
||
<article class="service-item">
|
||
<span>{{ item.number }}</span>
|
||
<div>
|
||
<h3>{{ item.name }}</h3>
|
||
<p>{{ item.description }}</p>
|
||
</div>
|
||
</article>
|
||
</AnimatedContent>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="cases" class="creator-projects-section">
|
||
<AnimatedContent class-name="case-section-heading" :distance="48" :duration="0.9">
|
||
<span>Case Study</span>
|
||
<h2 class="mega-heading home-heading-cn">客户案例</h2>
|
||
</AnimatedContent>
|
||
|
||
<div class="stable-case-list">
|
||
<article
|
||
v-for="(item, index) in homeCaseCards"
|
||
:key="item.name"
|
||
class="stable-case-card"
|
||
:style="{ top: `${104 + index * 18}px` }"
|
||
>
|
||
<div class="case-card-head">
|
||
<span>{{ item.number }}</span>
|
||
<div class="case-card-copy">
|
||
<small>{{ item.category }}</small>
|
||
<h3>{{ item.name }}</h3>
|
||
<p>{{ item.summary }}</p>
|
||
</div>
|
||
<Magnet :padding="64" :magnet-strength="6" wrapper-class-name="case-card-action">
|
||
<RouterLink to="/product#contact" class="live-project-button">预约演示</RouterLink>
|
||
</Magnet>
|
||
</div>
|
||
|
||
<div class="case-image-grid">
|
||
<div>
|
||
<img :src="item.images[0]" :alt="`${item.name} 业务图一`" loading="lazy">
|
||
<img :src="item.images[1]" :alt="`${item.name} 业务图二`" loading="lazy">
|
||
</div>
|
||
<img :src="item.images[2]" :alt="`${item.name} 场景图`" loading="lazy">
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="contact" class="home-contact-section">
|
||
<AnimatedContent class-name="home-contact-copy" :distance="50" :duration="0.9">
|
||
<span>Contact</span>
|
||
<h2 class="mega-heading home-heading-cn">让医疗协同真正跑起来</h2>
|
||
<p>告诉我们你的机构规模、系统现状和重点场景,萧康云医团队会给出一份可落地的演示方案。</p>
|
||
<Magnet :padding="90" :magnet-strength="5" wrapper-class-name="contact-action">
|
||
<RouterLink to="/product#contact" class="creator-contact-button">立即咨询</RouterLink>
|
||
</Magnet>
|
||
</AnimatedContent>
|
||
|
||
<AnimatedContent class-name="contact-metrics" :distance="50" direction="horizontal" :reverse="true" :duration="0.9">
|
||
<div v-for="item in metrics" :key="item.label">
|
||
<strong>{{ item.value }}</strong>
|
||
<span>{{ item.label }}</span>
|
||
</div>
|
||
</AnimatedContent>
|
||
</section>
|
||
</main>
|
||
</template>
|