feat: 增加教师桌面端的内容

This commit is contained in:
阿梦 2026-05-18 15:50:48 +09:00
parent e9dd96a620
commit adce307e67
9 changed files with 469 additions and 10 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 825 KiB

View File

@ -67,7 +67,7 @@ const features = [
class="lg:col-span-5 lg:sticky lg:top-28 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
>
<p class="text-sm font-semibold text-primary tracking-wider uppercase mb-3">体验</p>
<p class="text-sm font-semibold text-primary tracking-wider uppercase mb-3">学生</p>
<h2 class="text-3xl sm:text-4xl lg:text-[2.75rem] font-extrabold text-text-heading leading-tight">
趣味互动<br />
<span class="gradient-text">探索不止</span>
@ -83,7 +83,7 @@ const features = [
<img :src="tabletImg" alt="灵犀学体验端界面" class="w-full h-full object-cover" />
</div>
</div>
<div class="absolute -right-6 top-6 glass-card rounded-xl px-3 py-2 shadow-lg animate-float-slow hidden sm:block">
<div class="absolute -right-6 top-13 glass-card rounded-xl px-3 py-2 shadow-lg animate-float-slow hidden sm:block">
<div class="flex items-center gap-1.5">
<svg class="w-4 h-4 text-amber-500" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
<span class="text-xs font-bold text-amber-600">+100 积分</span>

View File

@ -0,0 +1,302 @@
<script setup lang="ts">
import {
Monitor, MonitorPlay, History, Image,
Share2, Radio, Clock, Layers,
Presentation, Users, Zap,
} from 'lucide-vue-next'
import { useScrollReveal } from '@/composables/useScrollReveal'
import ClassroomMonitorMockup from '@/components/new/illustrations/ClassroomMonitorMockup.vue'
import TeacherScreenShareMockup from '@/components/new/illustrations/TeacherScreenShareMockup.vue'
const screenSharePoints = [
{ icon: Presentation, text: '管理端一键唤起,教师桌面端独立窗口推流' },
{ icon: Users, text: '全班学生端同步接收,讲解画面实时跟看' },
{ icon: Zap, text: '课件、白板、实操演示一屏直达,线上线下同堂' },
]
const { target, isVisible } = useScrollReveal()
const workflowSteps = [
{ step: '01', title: '共享屏幕讲解', desc: '课堂管控选班后点「共享屏幕」,教师端独立窗口向全班推流', highlight: true },
{ step: '02', title: '开启课堂监控', desc: '一键开启监控会话,学生端 WebSocket 联动进入投屏状态' },
{ step: '03', title: '实时截图墙', desc: '按设定间隔采集屏幕快照,网格展示全班学习画面' },
{ step: '04', title: '回溯与复盘', desc: '历史会话存档,可按学生查看全部截图记录' },
]
const features = [
{
icon: MonitorPlay,
title: '一键开启监控',
desc: '按班级控制监控会话,实时查看监控状态、开始时间与采集间隔',
color: 'cyan',
},
{
icon: Image,
title: '学生截图墙',
desc: '全班学生屏幕快照网格展示,支持自动刷新、延迟提示与单生详情',
color: 'sky',
},
{
icon: Radio,
title: '屏幕监控',
desc: '桌面客户端打开学员 JPEG 截屏监控窗口,课堂专注度一目了然',
color: 'cyan',
},
{
icon: History,
title: '历史监控',
desc: '按会话查看教师、时长、学生数与截图数,支持进入会话详情复盘',
color: 'sky',
},
{
icon: Layers,
title: '截图归档',
desc: '点击学生卡片可查看该生在单次会话中的全部截图与时间轴',
color: 'teal',
},
{
icon: Clock,
title: '心跳保活',
desc: '监控期间自动心跳与定时刷新,保障长课时课堂连接稳定',
color: 'cyan',
},
{
icon: Monitor,
title: '课堂管控中心',
desc: '班级列表集中管理共享屏幕与屏幕监控入口,管控操作一站完成',
color: 'sky',
},
]
const colorMap: Record<string, { iconBg: string; text: string; border: string }> = {
primary: { iconBg: 'bg-primary/12', text: 'text-primary', border: 'border-primary/20' },
cyan: { iconBg: 'bg-cyan-500/12', text: 'text-cyan-600', border: 'border-cyan-500/10' },
sky: { iconBg: 'bg-sky-500/12', text: 'text-sky-600', border: 'border-sky-500/10' },
teal: { iconBg: 'bg-teal-500/12', text: 'text-teal-600', border: 'border-teal-500/10' },
}
</script>
<template>
<section id="classroom-monitor" class="relative py-24 lg:py-32 bg-white overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-cyan-500/25 to-transparent" />
<div class="absolute top-24 -left-32 w-72 h-72 rounded-full bg-cyan-500/5 blur-3xl" />
<div class="absolute bottom-16 -right-24 w-64 h-64 rounded-full bg-teal-500/5 blur-3xl" />
<div ref="target" class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div
class="text-center max-w-3xl mx-auto mb-12 lg:mb-16 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
>
<p class="text-sm font-semibold text-cyan-600 tracking-wider uppercase mb-3">课堂监控</p>
<h2 class="text-3xl sm:text-4xl lg:text-[2.75rem] font-extrabold text-text-heading leading-tight">
老师一讲全班跟看<span class="bg-gradient-to-r from-primary to-cyan-600 bg-clip-text text-transparent">课堂尽在掌握</span>
</h2>
<p class="text-lg text-text-muted mt-5 leading-relaxed">
<strong class="font-semibold text-text-heading">教师共享屏幕讲解</strong>让课件与演示同步到每位学生
配合课堂监控截图与历史复盘覆盖复盘完整教学闭环
</p>
</div>
<!-- 共享屏幕讲解 · 核心亮点 -->
<div
class="mb-10 lg:mb-12 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
:style="{ transitionDelay: isVisible ? '120ms' : '0ms' }"
>
<div class="relative overflow-visible rounded-3xl border-2 border-primary/20 bg-gradient-to-br from-primary/[0.06] via-white to-cyan-50/80 shadow-xl shadow-primary/10">
<div class="absolute top-0 right-0 w-64 h-64 rounded-full bg-primary/10 blur-3xl -translate-y-1/2 translate-x-1/3 pointer-events-none" />
<div class="absolute bottom-0 left-0 w-48 h-48 rounded-full bg-cyan-400/10 blur-3xl translate-y-1/3 -translate-x-1/4 pointer-events-none" />
<div class="relative grid lg:grid-cols-2 gap-8 lg:gap-12 p-6 sm:p-8 lg:p-10 items-center">
<div>
<span class="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-bold bg-primary text-white shadow-md shadow-primary/25 mb-4">
<Share2 class="w-3.5 h-3.5" />
核心亮点
</span>
<h3 class="text-2xl sm:text-3xl font-extrabold text-text-heading leading-snug mb-3">
教师共享屏幕讲解
</h3>
<p class="text-base text-text-muted leading-relaxed mb-6">
在管理端课堂管控选择班级点击共享屏幕即可唤起教师桌面端独立推流窗口
教师课件白板与实操画面实时同步至全班学生端线上线下同堂跟讲告别看不清跟不上
</p>
<ul class="space-y-3">
<li
v-for="point in screenSharePoints"
:key="point.text"
class="flex items-start gap-3"
>
<div class="w-9 h-9 shrink-0 rounded-xl bg-primary/10 flex items-center justify-center">
<component :is="point.icon" class="w-4 h-4 text-primary" />
</div>
<span class="text-sm text-text-body leading-relaxed pt-1.5">{{ point.text }}</span>
</li>
</ul>
</div>
<div class="relative max-w-md mx-auto lg:max-w-none w-full px-1 sm:px-2">
<TeacherScreenShareMockup />
<div class="absolute -top-2 -right-1 sm:right-4 glass-card-strong rounded-xl px-3 py-2 shadow-lg animate-float-slow">
<div class="flex items-center gap-2">
<span class="relative flex h-2 w-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75" />
<span class="relative inline-flex rounded-full h-2 w-2 bg-red-500" />
</span>
<p class="text-xs font-semibold text-text-heading">讲解推流中</p>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="text-center text-sm font-medium text-cyan-700/90 mb-6">学生屏幕监控</p>
<div
class="mb-14 lg:mb-16 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
:style="{ transitionDelay: isVisible ? '200ms' : '0ms' }"
>
<div class="max-w-4xl mx-auto relative">
<ClassroomMonitorMockup />
<div class="absolute -top-3 -right-2 lg:right-6 glass-card-strong rounded-xl px-3.5 py-2.5 shadow-lg animate-float-slow hidden sm:block">
<div class="flex items-center gap-2">
<div class="w-7 h-7 rounded-lg bg-primary/15 flex items-center justify-center">
<Share2 class="w-4 h-4 text-primary" />
</div>
<div>
<p class="text-xs font-semibold text-text-heading">共享屏幕讲解</p>
<p class="text-xs text-primary font-medium">全班同步跟看</p>
</div>
</div>
</div>
<div class="absolute bottom-6 -left-2 lg:left-2 glass-card-strong rounded-xl px-3.5 py-2.5 shadow-lg animate-float-medium hidden sm:block">
<div class="flex items-center gap-2">
<div class="w-7 h-7 rounded-lg bg-teal-500/15 flex items-center justify-center">
<Image class="w-4 h-4 text-teal-600" />
</div>
<div>
<p class="text-xs font-semibold text-text-heading">截图自动刷新</p>
<p class="text-xs text-teal-600 font-medium">间隔 5 </p>
</div>
</div>
</div>
</div>
</div>
<div
class="mb-14 lg:mb-16 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
:style="{ transitionDelay: isVisible ? '280ms' : '0ms' }"
>
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div
v-for="(item, i) in workflowSteps"
:key="item.step"
class="relative p-5 rounded-2xl border transition-colors duration-200"
:class="item.highlight
? 'bg-gradient-to-br from-primary/[0.08] to-cyan-50/90 border-primary/25 shadow-md shadow-primary/5'
: 'bg-bg-soft/80 border-cyan-500/10'"
>
<span
class="text-xs font-bold tracking-wider"
:class="item.highlight ? 'text-primary' : 'text-cyan-600/80'"
>{{ item.step }}</span>
<h4 class="text-base font-bold text-text-heading mt-2 mb-1.5">{{ item.title }}</h4>
<p class="text-sm text-text-muted leading-relaxed">{{ item.desc }}</p>
<span
v-if="item.highlight"
class="inline-block mt-2 text-[10px] font-semibold px-2 py-0.5 rounded-full bg-primary/10 text-primary"
>推荐首选</span>
<div
v-if="i < workflowSteps.length - 1"
class="hidden lg:block absolute top-1/2 -right-2 w-4 h-px bg-cyan-300/60"
aria-hidden="true"
/>
</div>
</div>
</div>
<!-- 共享屏幕能力大卡 -->
<div
class="mb-4 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-6'"
:style="{ transitionDelay: isVisible ? '360ms' : '0ms' }"
>
<div class="group relative p-6 lg:p-8 rounded-2xl border-2 border-primary/25 bg-gradient-to-r from-primary/[0.06] via-white to-primary/[0.04] hover:border-primary/40 hover:shadow-xl hover:shadow-primary/10 transition-all duration-300 cursor-pointer">
<div class="flex flex-col sm:flex-row sm:items-center gap-5">
<div class="w-14 h-14 shrink-0 rounded-2xl bg-primary flex items-center justify-center shadow-lg shadow-primary/30 group-hover:scale-105 transition-transform duration-300">
<Share2 class="w-7 h-7 text-white" />
</div>
<div class="flex-1 min-w-0">
<div class="flex flex-wrap items-center gap-2 mb-1">
<h4 class="text-lg font-bold text-text-heading">教师共享屏幕讲解</h4>
<span class="text-xs font-semibold px-2.5 py-0.5 rounded-full bg-primary text-white">核心亮点</span>
</div>
<p class="text-sm text-text-muted leading-relaxed">
管理端课堂管控一键打开教师桌面端独立推流窗口课件白板实操演示同步到全班学生端线上线下混合课的首选讲解方式
</p>
</div>
</div>
</div>
</div>
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div
v-for="(feat, i) in features"
:key="feat.title"
class="group relative p-5 rounded-2xl bg-white border hover:border-cyan-500/25 hover:shadow-lg hover:shadow-cyan-500/5 hover:-translate-y-0.5 transition-all duration-300 cursor-pointer"
:class="[
colorMap[feat.color].border,
isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-6',
]"
:style="{ transitionDelay: isVisible ? `${440 + i * 70}ms` : '0ms', transitionDuration: '600ms' }"
>
<div class="absolute -bottom-4 -right-4 w-16 h-16 rounded-full bg-cyan-500/[0.03] group-hover:bg-cyan-500/[0.08] transition-colors duration-500" />
<div class="relative">
<div
class="w-10 h-10 rounded-xl flex items-center justify-center mb-3 group-hover:scale-110 transition-transform duration-300"
:class="colorMap[feat.color].iconBg"
>
<component :is="feat.icon" class="w-5 h-5" :class="colorMap[feat.color].text" />
</div>
<h4 class="text-base font-bold text-text-heading mb-1">{{ feat.title }}</h4>
<p class="text-sm text-text-muted leading-relaxed">{{ feat.desc }}</p>
</div>
</div>
</div>
<div
class="mt-12 lg:mt-14 p-6 lg:p-8 rounded-2xl bg-gradient-to-br from-primary/[0.06] via-cyan-50/80 to-teal-50/80 border border-primary/15 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-6'"
:style="{ transitionDelay: isVisible ? '750ms' : '0ms' }"
>
<div class="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4">
<div>
<p class="text-sm font-semibold text-primary mb-1">多端协同 · 讲解优先</p>
<p class="text-text-muted text-sm leading-relaxed max-w-2xl">
<strong class="text-text-heading font-medium">教师桌面端共享屏幕</strong>负责向全班推流讲解
管理端负责监控开关与截图查看学生端接收推流并上报屏幕
三者配合先讲清楚再看得住最后能复盘
</p>
</div>
<div class="flex flex-wrap gap-2 shrink-0">
<span class="px-3 py-1.5 text-xs font-semibold rounded-full bg-primary text-white shadow-sm">教师桌面端 · 共享屏幕</span>
<span class="px-3 py-1.5 text-xs font-medium rounded-full bg-white text-cyan-700 border border-cyan-200/80">管理端 · 课堂管控</span>
<span class="px-3 py-1.5 text-xs font-medium rounded-full bg-white text-sky-700 border border-sky-200/80">学生体验端</span>
</div>
</div>
</div>
</div>
</section>
</template>
<style scoped>
@keyframes float-slow {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
@keyframes float-medium {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-7px); }
}
.animate-float-slow { animation: float-slow 5s ease-in-out infinite; }
.animate-float-medium { animation: float-medium 4s ease-in-out infinite 0.5s; }
</style>

View File

@ -9,6 +9,7 @@ const footerLinks = [
links: [
{ label: '体验端', href: '#app' },
{ label: '管理端', href: '#admin' },
{ label: '课堂监控', href: '#classroom-monitor' },
{ label: '核心技术', href: '#tech' },
{ label: '功能介绍', href: '#features' },
],

View File

@ -1,6 +1,11 @@
<script setup lang="ts">
import { Sparkles, ArrowRight, Play } from 'lucide-vue-next'
import { Sparkles, ArrowRight, Play, Monitor } from 'lucide-vue-next'
import HeroIllustrationNew from '@/components/new/illustrations/HeroIllustrationNew.vue'
function scrollToSection(href: string) {
const el = document.querySelector(href)
el?.scrollIntoView({ behavior: 'smooth' })
}
</script>
<template>
@ -31,25 +36,33 @@ import HeroIllustrationNew from '@/components/new/illustrations/HeroIllustration
<span class="text-text-body font-medium">一个平台连接服务的每一个环节</span>
</p>
<div class="flex flex-wrap gap-5">
<div class="flex flex-wrap gap-3 sm:gap-4">
<a
href="https://ai.xuexiaole.com/"
href="https://ai.lingxixue.com/"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center gap-2.5 px-8 py-4 text-base font-semibold text-white bg-gradient-to-r from-primary to-primary-light rounded-2xl hover:shadow-xl hover:shadow-primary/25 hover:-translate-y-0.5 transition-all duration-300 cursor-pointer group"
class="inline-flex items-center gap-2 px-6 sm:px-7 py-3.5 sm:py-4 text-sm sm:text-base font-semibold text-white bg-gradient-to-r from-primary to-primary-light rounded-2xl hover:shadow-xl hover:shadow-primary/25 hover:-translate-y-0.5 transition-all duration-300 cursor-pointer group"
>
<span>体验入口</span>
<ArrowRight class="w-4.5 h-4.5 group-hover:translate-x-0.5 transition-transform duration-200" />
<ArrowRight class="w-4 h-4 sm:w-4.5 sm:h-4.5 group-hover:translate-x-0.5 transition-transform duration-200" />
</a>
<a
href="https://admin.xuexiaole.com/"
href="https://tiku.lingxixue.com/"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center gap-2.5 px-8 py-4 text-base font-semibold text-primary bg-white border-2 border-primary/20 rounded-2xl hover:border-primary/40 hover:bg-primary/5 hover:-translate-y-0.5 transition-all duration-300 cursor-pointer group"
class="inline-flex items-center gap-2 px-6 sm:px-7 py-3.5 sm:py-4 text-sm sm:text-base font-semibold text-primary bg-white border-2 border-primary/20 rounded-2xl hover:border-primary/40 hover:bg-primary/5 hover:-translate-y-0.5 transition-all duration-300 cursor-pointer group"
>
<Play class="w-4.5 h-4.5" />
<Play class="w-4 h-4 sm:w-4.5 sm:h-4.5" />
<span>管理入口</span>
</a>
<a
href="#classroom-monitor"
class="inline-flex items-center gap-2 px-6 sm:px-7 py-3.5 sm:py-4 text-sm sm:text-base font-semibold text-cyan-800 bg-gradient-to-r from-cyan-50 to-teal-50 border-2 border-cyan-500/25 rounded-2xl hover:border-cyan-500/45 hover:shadow-lg hover:shadow-cyan-500/10 hover:-translate-y-0.5 transition-all duration-300 cursor-pointer group"
@click.prevent="scrollToSection('#classroom-monitor')"
>
<Monitor class="w-4 h-4 sm:w-4.5 sm:h-4.5 text-cyan-600" />
<span>教师端</span>
</a>
</div>
<div class="flex items-center gap-6 pt-2">

View File

@ -10,6 +10,7 @@ const navLinks = [
{ label: '产品功能', href: '#features' },
{ label: '体验端', href: '#app' },
{ label: '管理端', href: '#admin' },
{ label: '课堂监控', href: '#classroom-monitor' },
{ label: '关于我们', href: '#about' },
]

View File

@ -0,0 +1,80 @@
<template>
<svg viewBox="0 0 640 420" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto drop-shadow-2xl">
<defs>
<linearGradient id="cm-frame" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0E7490" />
<stop offset="100%" stop-color="#155E75" />
</linearGradient>
<linearGradient id="cm-active" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#06B6D4" />
<stop offset="100%" stop-color="#22D3EE" />
</linearGradient>
<clipPath id="cm-screen-clip">
<rect x="68" y="24" width="504" height="300" rx="4" />
</clipPath>
</defs>
<rect x="44" y="10" width="552" height="322" rx="16" fill="url(#cm-frame)" />
<rect x="54" y="18" width="532" height="306" rx="8" fill="#0C4A6E" />
<rect x="68" y="24" width="504" height="296" rx="4" fill="#F8FAFC" />
<circle cx="320" cy="16" r="3" fill="#155E75" />
<path d="M24 332 L616 332 L636 358 Q636 372 622 372 L18 372 Q4 372 4 358 Z" fill="url(#cm-frame)" />
<rect x="270" y="336" width="100" height="6" rx="3" fill="#155E75" />
<ellipse cx="320" cy="382" rx="84" ry="6" fill="#0C4A6E" opacity="0.25" />
<g clip-path="url(#cm-screen-clip)">
<rect x="68" y="24" width="504" height="296" fill="#F1F5F9" />
<rect x="68" y="24" width="504" height="44" fill="white" />
<line x1="68" y1="68" x2="572" y2="68" stroke="#E2E8F0" stroke-width="1" />
<text x="84" y="52" font-size="11" font-weight="bold" fill="#0F172A">三年级2</text>
<text x="84" y="62" font-size="7" fill="#64748B">课堂管控 · 监控中</text>
<rect x="468" y="36" width="52" height="20" rx="6" fill="#FEE2E2" />
<text x="494" y="50" text-anchor="middle" font-size="7" font-weight="600" fill="#DC2626">停止监控</text>
<rect x="526" y="36" width="38" height="20" rx="6" fill="#E0F2FE" />
<text x="545" y="50" text-anchor="middle" font-size="7" font-weight="600" fill="#0369A1">刷新</text>
<rect x="80" y="80" width="480" height="36" rx="8" fill="white" stroke="#E2E8F0" stroke-width="1" />
<rect x="92" y="90" width="44" height="16" rx="8" fill="#DCFCE7" />
<text x="114" y="102" text-anchor="middle" font-size="7" font-weight="600" fill="#16A34A">监控中</text>
<text x="148" y="94" font-size="7" fill="#64748B">开始</text>
<text x="148" y="106" font-size="8" font-weight="600" fill="#0F172A">14:32:08</text>
<text x="220" y="94" font-size="7" fill="#64748B">采集间隔</text>
<text x="220" y="106" font-size="8" font-weight="600" fill="#0F172A">5000ms</text>
<text x="300" y="94" font-size="7" fill="#64748B">在线学生</text>
<text x="300" y="106" font-size="8" font-weight="600" fill="#0891B2">32</text>
<text x="80" y="136" font-size="9" font-weight="bold" fill="#0F172A">学生监控信息</text>
<text x="520" y="136" text-anchor="end" font-size="7" fill="#0891B2">5 秒自动刷新</text>
<g v-for="(card, i) in snapshotCards" :key="i">
<rect
:x="card.x"
:y="148"
width="112"
height="128"
rx="10"
fill="white"
stroke="#E2E8F0"
stroke-width="1"
/>
<rect :x="card.x + 8" :y="156" width="96" height="68" rx="6" :fill="card.fill" />
<rect v-if="card.live" :x="card.x + 88" :y="160" width="10" height="10" rx="5" fill="#22C55E" />
<circle v-if="card.live" :cx="card.x + 93" :cy="165" r="3" fill="white" opacity="0.9" />
<circle :cx="card.x + 20" :cy="242" r="10" :fill="card.avatar" />
<text :x="card.x + 20" :y="246" text-anchor="middle" font-size="8" font-weight="bold" fill="white">{{ card.initial }}</text>
<text :x="card.x + 36" :y="238" font-size="8" font-weight="600" fill="#0F172A">{{ card.name }}</text>
<text :x="card.x + 36" :y="250" font-size="6" fill="#64748B">延迟 {{ card.delay }}</text>
</g>
</g>
</svg>
</template>
<script setup lang="ts">
const snapshotCards = [
{ x: 80, name: '张同学', initial: '张', delay: 2, live: true, fill: '#E0F2FE', avatar: '#0891B2' },
{ x: 204, name: '李同学', initial: '李', delay: 1, live: true, fill: '#DBEAFE', avatar: '#4F46E5' },
{ x: 328, name: '王同学', initial: '王', delay: 4, live: false, fill: '#F1F5F9', avatar: '#64748B' },
{ x: 452, name: '赵同学', initial: '赵', delay: 2, live: true, fill: '#CCFBF1', avatar: '#0D9488' },
]
</script>

View File

@ -0,0 +1,60 @@
<template>
<svg viewBox="0 0 560 300" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" preserveAspectRatio="xMidYMid meet">
<defs>
<linearGradient id="ts-teacher" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#4F46E5" />
<stop offset="100%" stop-color="#6366F1" />
</linearGradient>
<linearGradient id="ts-beam" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#06B6D4" stop-opacity="0.5" />
<stop offset="100%" stop-color="#22D3EE" stop-opacity="0.15" />
</linearGradient>
<linearGradient id="ts-screen" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#312E81" />
<stop offset="100%" stop-color="#1E1B4B" />
</linearGradient>
</defs>
<!-- Teacher laptop -->
<rect x="24" y="48" width="200" height="128" rx="12" fill="url(#ts-teacher)" />
<rect x="34" y="58" width="180" height="100" rx="6" fill="#0F0D2E" />
<rect x="42" y="66" width="164" height="84" rx="4" fill="white" />
<text x="52" y="82" font-size="7" font-weight="bold" fill="#4F46E5">教师讲解画面</text>
<rect x="52" y="90" width="140" height="8" rx="2" fill="#E0E7FF" />
<rect x="52" y="104" width="120" height="6" rx="2" fill="#EEF2FF" />
<rect x="52" y="116" width="100" height="6" rx="2" fill="#EEF2FF" />
<rect x="52" y="128" width="80" height="14" rx="4" fill="url(#ts-teacher)" opacity="0.25" />
<path d="M14 176 L234 176 L250 198 Q252 208 242 208 L6 208 Q-4 208 -2 198 Z" fill="url(#ts-teacher)" />
<text x="124" y="40" text-anchor="middle" font-size="8" font-weight="600" fill="#4F46E5">教师桌面端</text>
<!-- Broadcast beam -->
<path d="M234 110 Q320 100 360 120 L360 140 Q320 120 234 130 Z" fill="url(#ts-beam)" />
<path d="M234 120 Q340 115 380 145 L380 165 Q330 135 234 140 Z" fill="url(#ts-beam)" opacity="0.7" />
<circle cx="300" cy="128" r="22" fill="#06B6D4" opacity="0.12" />
<circle cx="300" cy="128" r="14" fill="#06B6D4" opacity="0.2" />
<path d="M292 128 L304 128 M300 124 L300 132" stroke="#0891B2" stroke-width="2" stroke-linecap="round" />
<text x="300" y="158" text-anchor="middle" font-size="7" font-weight="600" fill="#0891B2">实时推流</text>
<!-- Student devices -->
<g v-for="(device, i) in devices" :key="i">
<rect :x="device.x" :y="device.y" width="88" height="118" rx="10" fill="white" stroke="#E2E8F0" stroke-width="1.5" />
<rect :x="device.x + 8" :y="device.y + 12" width="72" height="88" rx="6" fill="url(#ts-screen)" />
<rect :x="device.x + 14" :y="device.y + 20" width="60" height="40" rx="3" fill="#312E81" opacity="0.6" />
<rect :x="device.x + 14" :y="device.y + 66" width="44" height="4" rx="1" fill="#818CF8" opacity="0.5" />
<rect :x="device.x + 14" :y="device.y + 74" width="36" height="3" rx="1" fill="#818CF8" opacity="0.35" />
<circle :cx="device.x + 44" :cy="device.y + 108" r="4" fill="#22C55E" />
<text :x="device.x + 44" :y="device.y + 8" text-anchor="middle" font-size="6" fill="#64748B">{{ device.label }}</text>
</g>
<rect x="188" y="228" width="184" height="28" rx="14" fill="#ECFEFF" stroke="#A5F3FC" stroke-width="1" />
<text x="280" y="246" text-anchor="middle" font-size="8" font-weight="600" fill="#0E7490">全班同步观看教师屏幕</text>
</svg>
</template>
<script setup lang="ts">
const devices = [
{ x: 348, y: 56, label: '学生端' },
{ x: 348, y: 168, label: '学生端' },
{ x: 448, y: 112, label: '学生端' },
]
</script>

View File

@ -4,6 +4,7 @@ import HeroSectionNew from '@/components/new/HeroSectionNew.vue'
import FeaturesSectionNew from '@/components/new/FeaturesSectionNew.vue'
import AppSectionNew from '@/components/new/AppSectionNew.vue'
import AdminSectionNew from '@/components/new/AdminSectionNew.vue'
import ClassroomMonitorSectionNew from '@/components/new/ClassroomMonitorSectionNew.vue'
import TechSectionNew from '@/components/new/TechSectionNew.vue'
import StatsSectionNew from '@/components/new/StatsSectionNew.vue'
import TestimonialSectionNew from '@/components/new/TestimonialSectionNew.vue'
@ -19,6 +20,7 @@ import FooterSectionNew from '@/components/new/FooterSectionNew.vue'
<FeaturesSectionNew />
<AppSectionNew />
<AdminSectionNew />
<ClassroomMonitorSectionNew />
<TechSectionNew />
<StatsSectionNew />
<!-- <TestimonialSectionNew /> -->