diff --git a/sites/README.md b/sites/README.md index 8ba2664..252a325 100644 --- a/sites/README.md +++ b/sites/README.md @@ -4,6 +4,15 @@ 正式站点地址: +首页将 GoodBuddy 定位为“桌面助手|AI 编程工具台”,优先展示三大桌面 +系统与双架构下载入口、统一 Agent Runtime,以及知识库、魔法笔记、 +智能心跳、桌面上下文和远程消息通道等桌面助手能力。下载区位于主要 +功能说明之前,并明确列出统信 UOS、银河麒麟、海光、兆芯、鲲鹏和飞腾 +对应的 Linux x64 / arm64 包。页面不重复设置底部下载推广区。 +首屏产品界面默认正面展示,在精确指针设备上使用克制的 3D 倾斜、 +柔和跟随光效和同步浮动标签;触屏设备保持静态布局,系统启用“减少动态 +效果”时不运行该交互。 + ## 部署 `.github/workflows/pages.yml` 会在 `main` 分支中的官网文件发生变化后, @@ -34,7 +43,7 @@ node --check sites/app.js ## 下载入口 -官网正文不展示具体版本号,所有下载入口直接指向 GitHub 最新正式 +官网正文不展示具体版本号,三个系统下载按钮直接指向 GitHub 最新正式 Release: ```text diff --git a/sites/app.js b/sites/app.js index 672b239..9a08416 100644 --- a/sites/app.js +++ b/sites/app.js @@ -7,7 +7,11 @@ const navigation = document.querySelector("[data-navigation]"); const themeToggle = document.querySelector("[data-theme-toggle]"); const themeColor = document.querySelector('meta[name="theme-color"]'); + const tiltStage = document.querySelector("[data-tilt-stage]"); + const tiltCard = tiltStage?.querySelector("[data-tilt-card]"); const systemTheme = window.matchMedia("(prefers-color-scheme: dark)"); + const finePointer = window.matchMedia("(hover: hover) and (pointer: fine)"); + const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"); const getSavedTheme = () => { try { @@ -90,6 +94,50 @@ window.addEventListener("scroll", setHeaderState, { passive: true }); + if (tiltStage instanceof HTMLElement && tiltCard instanceof HTMLElement) { + let tiltFrame = 0; + + const resetTilt = () => { + window.cancelAnimationFrame(tiltFrame); + tiltStage.classList.remove("is-tilting"); + tiltStage.style.setProperty("--spotlight-x", "50%"); + tiltStage.style.setProperty("--spotlight-y", "50%"); + tiltCard.style.setProperty("--spotlight-x", "50%"); + tiltCard.style.setProperty("--spotlight-y", "50%"); + tiltStage.style.setProperty("--scene-tilt-x", "0deg"); + tiltStage.style.setProperty("--scene-tilt-y", "0deg"); + }; + + const updateTilt = (event) => { + if (!finePointer.matches || reducedMotion.matches) { + resetTilt(); + return; + } + + const bounds = tiltStage.getBoundingClientRect(); + const x = Math.min(Math.max((event.clientX - bounds.left) / bounds.width, 0), 1); + const y = Math.min(Math.max((event.clientY - bounds.top) / bounds.height, 0), 1); + + window.cancelAnimationFrame(tiltFrame); + tiltFrame = window.requestAnimationFrame(() => { + const spotlightX = `${(x * 100).toFixed(1)}%`; + const spotlightY = `${(y * 100).toFixed(1)}%`; + tiltStage.classList.add("is-tilting"); + tiltStage.style.setProperty("--spotlight-x", spotlightX); + tiltStage.style.setProperty("--spotlight-y", spotlightY); + tiltCard.style.setProperty("--spotlight-x", spotlightX); + tiltCard.style.setProperty("--spotlight-y", spotlightY); + tiltStage.style.setProperty("--scene-tilt-x", `${((0.5 - y) * 8).toFixed(2)}deg`); + tiltStage.style.setProperty("--scene-tilt-y", `${((x - 0.5) * 11).toFixed(2)}deg`); + }); + }; + + tiltStage.addEventListener("pointermove", updateTilt, { passive: true }); + tiltStage.addEventListener("pointerleave", resetTilt); + finePointer.addEventListener("change", resetTilt); + reducedMotion.addEventListener("change", resetTilt); + } + const sections = [...document.querySelectorAll("main section[id]")]; const navLinks = [...document.querySelectorAll('.site-navigation a[href^="#"]')]; diff --git a/sites/index.html b/sites/index.html index 413cd15..a742c41 100644 --- a/sites/index.html +++ b/sites/index.html @@ -5,11 +5,11 @@ - GoodBuddy|桌面 AI 助手 + GoodBuddy|桌面助手与 AI 编程工具台