diff --git a/cli/templates/.vuepress/config.ts.handlebars b/cli/templates/.vuepress/config.ts.handlebars index 9f8f658f..41c2aafe 100644 --- a/cli/templates/.vuepress/config.ts.handlebars +++ b/cli/templates/.vuepress/config.ts.handlebars @@ -82,7 +82,7 @@ export default defineUserConfig({ // provider: 'algolia', // appId: '', // apiKey: '', - // indexName: '', + // indices: [''], // }, /** diff --git a/cli/templates/docs/en/README.md.handlebars b/cli/templates/docs/en/README.md.handlebars index da437fdf..dee4bd0a 100644 --- a/cli/templates/docs/en/README.md.handlebars +++ b/cli/templates/docs/en/README.md.handlebars @@ -5,7 +5,7 @@ config: - type: hero full: true - background: tint-plate + effect: lightning hero: name: Theme Plume tagline: VuePress Next Theme diff --git a/cli/templates/docs/zh/README.md.handlebars b/cli/templates/docs/zh/README.md.handlebars index ba8e79f1..6d00b51e 100644 --- a/cli/templates/docs/zh/README.md.handlebars +++ b/cli/templates/docs/zh/README.md.handlebars @@ -5,7 +5,7 @@ config: - type: hero full: true - background: tint-plate + effect: lightning hero: name: Theme Plume tagline: VuePress Next Theme diff --git a/docs/.vuepress/collections/en/theme-guide.ts b/docs/.vuepress/collections/en/theme-guide.ts index 1b5ebf42..4a323709 100644 --- a/docs/.vuepress/collections/en/theme-guide.ts +++ b/docs/.vuepress/collections/en/theme-guide.ts @@ -172,7 +172,7 @@ export const themeGuide: ThemeCollectionItem = defineCollection({ collapsed: false, prefix: 'custom', items: [ - 'home', + { text: 'Custom Homepage', link: 'home', items: ['home-hero-effect'] }, 'style', 'slots', 'component-overrides', diff --git a/docs/.vuepress/collections/zh/theme-guide.ts b/docs/.vuepress/collections/zh/theme-guide.ts index 18f56c28..67cbdcb5 100644 --- a/docs/.vuepress/collections/zh/theme-guide.ts +++ b/docs/.vuepress/collections/zh/theme-guide.ts @@ -172,7 +172,7 @@ export const themeGuide: ThemeCollectionItem = defineCollection({ collapsed: false, prefix: 'custom', items: [ - 'home', + { text: '自定义首页', link: 'home', items: ['home-hero-effect'] }, 'style', 'slots', 'component-overrides', diff --git a/docs/.vuepress/public/images/hero-effects/beams.png b/docs/.vuepress/public/images/hero-effects/beams.png new file mode 100644 index 00000000..d0369358 Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/beams.png differ diff --git a/docs/.vuepress/public/images/hero-effects/dot-grid.png b/docs/.vuepress/public/images/hero-effects/dot-grid.png new file mode 100644 index 00000000..ab2e1fe4 Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/dot-grid.png differ diff --git a/docs/.vuepress/public/images/hero-effects/hyper-speed.png b/docs/.vuepress/public/images/hero-effects/hyper-speed.png new file mode 100644 index 00000000..c40b8489 Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/hyper-speed.png differ diff --git a/docs/.vuepress/public/images/hero-effects/iridescence.png b/docs/.vuepress/public/images/hero-effects/iridescence.png new file mode 100644 index 00000000..d0f22075 Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/iridescence.png differ diff --git a/docs/.vuepress/public/images/hero-effects/lightning.png b/docs/.vuepress/public/images/hero-effects/lightning.png new file mode 100644 index 00000000..8ad4d8b9 Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/lightning.png differ diff --git a/docs/.vuepress/public/images/hero-effects/liquid-ether.png b/docs/.vuepress/public/images/hero-effects/liquid-ether.png new file mode 100644 index 00000000..65b39a9c Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/liquid-ether.png differ diff --git a/docs/.vuepress/public/images/hero-effects/orb.png b/docs/.vuepress/public/images/hero-effects/orb.png new file mode 100644 index 00000000..6c043c05 Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/orb.png differ diff --git a/docs/.vuepress/public/images/hero-effects/pixel-blast.png b/docs/.vuepress/public/images/hero-effects/pixel-blast.png new file mode 100644 index 00000000..e198a042 Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/pixel-blast.png differ diff --git a/docs/.vuepress/public/images/hero-effects/prism.png b/docs/.vuepress/public/images/hero-effects/prism.png new file mode 100644 index 00000000..90ad42ab Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/prism.png differ diff --git a/docs/.vuepress/public/images/hero-effects/tint-plate.png b/docs/.vuepress/public/images/hero-effects/tint-plate.png new file mode 100644 index 00000000..e92ebda7 Binary files /dev/null and b/docs/.vuepress/public/images/hero-effects/tint-plate.png differ diff --git a/docs/README.md b/docs/README.md index 648cf6b6..2e8c0e2f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,7 +5,8 @@ config: - type: hero full: true - background: tint-plate + effect: lightning + forceDark: true hero: name: Theme Plume tagline: VuePress Next Theme diff --git a/docs/en/README.md b/docs/en/README.md index 196f9748..2f69fd4c 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -4,7 +4,8 @@ config: - type: hero full: true - background: tint-plate + effect: lightning + forceDark: true hero: name: Theme Plume tagline: VuePress Next Theme diff --git a/docs/en/guide/custom/home-hero-effect.md b/docs/en/guide/custom/home-hero-effect.md new file mode 100644 index 00000000..fab07ccb --- /dev/null +++ b/docs/en/guide/custom/home-hero-effect.md @@ -0,0 +1,1306 @@ +--- +title: Hero Background Effects +icon: icon-park-outline:effects +createTime: 2025/10/24 15:35:14 +permalink: /en/guide/custom-home/hero-effect/ +badge: New +--- + +## Overview + +For most websites, a **visually stunning** homepage hero section can more easily attract users to stay. +However, achieving **visual appeal** often requires complex technical effort and a touch of creative inspiration. + +The theme comes with a series of **visually impressive** background effects built into the **Hero** section of the **homepage**, +which can be easily applied to your site through simple configuration: + +```md {6,8-10} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate + effectConfig: + key: value +--- +``` + +::: important Only when `type: hero` is set will the theme apply the effect specified in `effect`. +::: + +The `effect` property supports the following values: + +- [tint-plate](#tint-plate) +- [prism](#prism) +- [pixel-blast](#pixel-blast) +- [hyper-speed](#hyper-speed) +- [liquid-ether](#liquid-ether) +- [dot-grid](#dot-grid) +- [iridescence](#iridescence) +- [orb](#orb) +- [beams](#beams) +- [lightning](#lightning) + +The `effectConfig` should be configured according to the selected `effect`. +In most cases, you don’t need to configure it—the theme will automatically apply preset configurations. + +:::important Note +The built-in effects are based on the excellent open-source project [vue-bits](https://vue-bits.dev/), +whose code has been adapted and integrated into the theme under the MIT license. +::: + +## Force Dark Mode + +Most background effects perform better in **dark mode**, +so it is recommended to enable [dark mode](../../config/theme.md#appearance) for the best experience. + +However, for documentation pages, you may prefer **light mode**. Therefore, the theme provides a `forceDark` option in the `hero` section, +which forces the homepage into **dark mode** without affecting the color mode of other pages. + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + forceDark: true + effect: lightning +--- +``` + +## Dynamic Background Effects + +::: important +Some effects may depend on `three`, `gsap`, or `ogl`. You need to manually install the corresponding dependencies based on the effect you choose. + +The theme loads these effects **on-demand**, so there is no need to worry about increasing the final bundle size. +::: + +### tint-plate + +#### Effect Preview + +![tint-plate](/images/hero-effects/tint-plate.png) + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate +--- +``` + +#### Configuration + +`effectConfig` is used to configure RGB values: + +- When configured as a single value, it sets the same value for red, green, and blue channels (range: 0–255). Example: `210`. +- When configured as three values, it sets different values for red, green, and blue channels (range: 0–255). Example: `210,210,210`. +- When configured as `TintPlate`, it allows more flexible control over each color value and its corresponding offset. +- It can also be configured as `{ light: TintPlate, dark: TintPlate }` to use different color values in light mode and dark mode. + +```ts +interface TintPlate { + r: { value: number, offset: number } + g: { value: number, offset: number } + b: { value: number, offset: number } +} +``` + +**Example**: + +::: code-tabs + +@tab Single value + +```md {8,9} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate + effectConfig: 210 +--- +``` + +@tab Three values + +```md {8,9} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate + effectConfig: 210,210,210 +--- +``` + +@tab TintPlate + +```md {8-18} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate + effectConfig: + r: + value: 210 + offset: 0 + g: + value: 210 + offset: 0 + b: + value: 210 + offset: 0 +--- +``` + +::: + +::: info +To help users easily configure visually appealing and personalized backgrounds, +the theme also provides a [Homepage Hero Tint Plate Configuration Tool](../../../tools/home-hero-tint-plate.md). +You can use this tool for visual configuration and generate configuration content that can be directly copied into your own project. +::: + +### prism + +#### Effect Preview + +![prism](/images/hero-effects/prism.png) + +#### Install dependencies + +:::npm-to + +```sh +npm i ogl +``` + +::: + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: prism +--- +``` + +#### Configuration + +:::: field-group + +:::field name="height" type="number" optional default="3.5" +Apex height of the prism (world units) +::: +:::field name="baseWidth" type="number" optional default="5.5" +Total base width across X/Z (world units). +::: +:::field name="animationType" type="'rotate' | 'hover' | '3drotate'" optional default="'rotate'" +Animation mode: shader wobble, pointer hover tilt, or full 3D rotation. +::: +:::field name="glow" type="number" optional default="1" +Glow/bleed intensity multiplier. +::: +:::field name="offset" type="{ x?: number, y?: number }" optional default="{ x: 0, y: 0 }" +Pixel offset within the canvas (x→right, y→down). +::: +:::field name="noise" type="number" optional default="0" +Film-grain noise amount added to final color (0 disables). +::: +:::field name="transparent" type="boolean" optional default="true" +Whether the canvas has an alpha channel (transparent background). +::: +:::field name="scale" type="number" optional default="3.6" +Overall screen-space scale of the prism (bigger = larger). +::: +:::field name="hueShift" type="number" optional default="0" +Hue rotation (radians) applied to final color. +::: +:::field name="colorFrequency" type="number" optional default="1" +Frequency of internal sine bands controlling color variation. +::: +:::field name="hoverStrength" type="number" optional default="2" +Sensitivity of hover tilt (pitch/yaw amplitude). +::: +:::field name="inertia" type="number" optional default="0.05" +Easing factor for hover (0..1, higher = snappier). +::: +:::field name="bloom" type="number" optional default="1" +Extra bloom factor layered on top of glow. +::: +:::field name="suspendWhenOffscreen" type="boolean" optional default="true" +Pause rendering when the element is not in the viewport. +::: +:::field name="timeScale" type="number" optional default="0.5" +Global time multiplier for animations (0=frozen, 1=normal). +::: +:::: + +**Example**: + +```md {8-26} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: prism + effectConfig: + height: 3.5, + baseWidth: 5.5 + animationType: rotate + glow: 1 + offset: + x: 0 + y: 0 + noise: 0 + transparent: true + scale: 3.6 + hueShift: 0 + colorFrequency: 1 + hoverStrength: 2 + inertia: 0.05 + bloom: 1 + suspendWhenOffscreen: true + timeScale: 0.5 +--- +``` + +### pixel-blast + +#### Effect Preview + +![pixel-blast](/images/hero-effects/pixel-blast.png) + +#### Install dependencies + +:::npm-to + +```sh +npm i three postprocessing +``` + +::: + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: pixel-blast +--- +``` + +#### Configuration + +::::field-group +:::field name="variant" type="'square' | 'circle' | 'triangle' | 'diamond'" optional default="'square'" +Pixel shape variant +::: +:::field name="pixelSize" type="number" optional default="4" +Base pixel size (auto scaled for DPI). +::: +:::field name="color" type="string" optional default="'#5086a1'" +Pixel color. +::: +:::field name="antialias" type="boolean" optional default="true" +Enable antialiasing. +::: +:::field name="patternScale" type="number" optional default="2" +Noise/pattern scale. +::: +:::field name="patternDensity" type="number" optional default="1" +Pattern density adjustment. +::: +:::field name="liquid" type="boolean" optional default="false" +Enable liquid distortion effect. +::: +:::field name="liquidStrength" type="number" optional default="0.1" +Liquid distortion strength. +::: +:::field name="liquidRadius" type="number" optional default="1" +Liquid touch brush radius scale. +::: +:::field name="liquidWobbleSpeed" type="number" optional default="4.5" +Liquid wobble frequency. +::: +:::field name="pixelSizeJitter" type="number" optional default="0" +Random jitter applied to coverage. +::: +:::field name="enableRipples" type="boolean" optional default="true" +Enable click ripple waves. +::: +:::field name="rippleIntensityScale" type="number" optional default="1" +Ripple intensity multiplier. +::: +:::field name="rippleThickness" type="number" optional default="0.1" +Ripple ring thickness. +::: +:::field name="rippleSpeed" type="number" optional default="0.3" +Ripple propagation speed. +::: +:::field name="autoPauseOffscreen" type="boolean" optional default="true" +Enable auto-pausing when offscreen. +::: +:::field name="speed" type="number" optional default="0.5" +Animation time scale. +::: +:::field name="transparent" type="boolean" optional default="true" +Transparent background. +::: +:::field name="edgeFade" type="number" optional default="0.5" +Edge fade distance (`0-1`). +::: +:::field name="noiseAmount" type="number" optional default="0" +Post noise amount. +::: +:::field name="className" type="string" optional +Container class name +::: +:::field name="style" type="CSSProperties" optional +Container style +::: +:::field name="backgroundImage" type="string" optional +Background image URL +::: +:::: + +**Example**: + +```md {8-29} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: pixel-blast + effectConfig: + variant: square + pixelSize: 4 + color: #5086a1 + antialias: true + patternScale: 2 + patternDensity: 1 + liquid: false + liquidStrength: 0.1 + liquidRadius: 1 + pixelSizeJitter: 0 + enableRipples: true + rippleIntensityScale: 1 + rippleThickness: 0.1 + rippleSpeed: 0.3 + liquidWobbleSpeed: 4.5 + autoPauseOffscreen: true + speed: 0.5 + transparent: true + edgeFade: 0.5 + noiseAmount: 0 +--- +``` + +### hyper-speed + +#### Effect Preview + +![hyper-speed](/images/hero-effects/hyper-speed.png) + +#### Install dependencies + +:::npm-to + +```sh +npm i three postprocessing +``` + +::: + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed +--- +``` + +#### Configuration + +```ts +interface ThemeHomeHeroHyperSpeedDistortion { + uniforms: Record + getDistortion: string +} + +interface ThemeHomeHeroHyperSpeedColors { + roadColor: number + islandColor: number + background: number + shoulderLines: number + brokenLines: number + leftCars: number[] + rightCars: number[] + sticks: number +} + +interface ThemeHomeHeroHyperSpeed { + distortion?: string | ThemeHomeHeroHyperSpeedDistortion + length: number + roadWidth: number + islandWidth: number + lanesPerRoad: number + fov: number + fovSpeedUp: number + speedUp: number + carLightsFade: number + totalSideLightSticks: number + lightPairsPerRoadWay: number + shoulderLinesWidthPercentage: number + brokenLinesWidthPercentage: number + brokenLinesLengthPercentage: number + lightStickWidth: [number, number] + lightStickHeight: [number, number] + movingAwaySpeed: [number, number] + movingCloserSpeed: [number, number] + carLightsLength: [number, number] + carLightsRadius: [number, number] + carWidthPercentage: [number, number] + carShiftX: [number, number] + carFloorSeparation: [number, number] + colors: ThemeHomeHeroHyperSpeedColors + isHyper?: boolean +} +``` + +:::warning [vue-bits](https://vue-bits.dev/backgrounds/hyperspeed) does not provide detailed configuration instructions; please use with caution. +::: + +You can use the following preset configuration, directly copy it into your markdown file: + +:::code-tabs +@tab Cyberpunk + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: turbulentDistortion + length: 400 + roadWidth: 10 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 20 + lightPairsPerRoadWay: 40 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [12, 80] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.8, 0.8] + carFloorSeparation: [0, 5] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xd856bf, 0x6750a2, 0xc247ac] + rightCars: [0x03b3c3, 0x0e5ea5, 0x324555] + sticks: 0x03b3c3 +--- +``` + +@tab Akira + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: mountainDistortion + length: 400 + roadWidth: 9 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 50 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [20, 60] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.2, 0.2] + carFloorSeparation: [0.05, 1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xff102a, 0xeb383e, 0xff102a] + rightCars: [0xdadafa, 0xbebae3, 0x8f97e4] + sticks: 0xdadafa +--- +``` + +@tab Golden + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: xyDistortion + length: 400 + roadWidth: 9 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 3 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 30 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.02, 0.05] + lightStickHeight: [0.3, 0.7] + movingAwaySpeed: [20, 50] + movingCloserSpeed: [-150, -230] + carLightsLength: [20, 80] + carLightsRadius: [0.03, 0.08] + carWidthPercentage: [0.1, 0.5] + carShiftX: [-0.5, 0.5] + carFloorSeparation: [0, 0.1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318, + leftCars: [0x7d0d1b, 0xa90519, 0xff102a] + rightCars: [0xf1eece, 0xe6e2b1, 0xdfd98a] + sticks: 0xf1eece +--- +``` + +@tab Split + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: LongRaceDistortion + length: 400 + roadWidth: 10 + islandWidth: 5 + lanesPerRoad: 2 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 70 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [20, 60] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.2, 0.2] + carFloorSeparation: [0.05, 1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xff5f73, 0xe74d60, 0xff102a] + rightCars: [0xa4e3e6, 0x80d1d4, 0x53c2c6] + sticks: 0xa4e3e6 +--- +``` + +@tab Highway + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: turbulentDistortion + length: 400 + roadWidth: 9 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 50 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [20, 60] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.2, 0.2] + carFloorSeparation: [0.05, 1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xdc5b20, 0xdca320, 0xdc2020] + rightCars: [0x334bf7, 0xe5e6ed, 0xbfc6f3] + sticks: 0xc5e8eb +--- +``` + +@tab Deep + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: deepDistortion + length: 400 + roadWidth: 18 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 50 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [20, 60] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.2, 0.2] + carFloorSeparation: [0.05, 1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xff322f, 0xa33010, 0xa81508] + rightCars: [0xfdfdf0, 0xf3dea0, 0xe2bb88] + sticks: 0xfdfdf0 +--- +``` + +::: + +### liquid-ether + +#### Effect Preview + +![liquid-ether](/images/hero-effects/liquid-ether.png) + +#### Install dependencies + +:::npm-to + +```sh +npm i three +``` + +::: + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: liquid-ether +--- +``` + +#### Configuration + +::::field-group +:::field name="mouseForce" type="number" optional default="20" +Strength multiplier applied to mouse / touch movement when injecting velocity. +::: +:::field name="cursorSize" type="number" optional default="100" +Radius (in pixels at base resolution) of the force brush. +::: +:::field name="isViscous" type="boolean" optional default="false" +Toggle iterative viscosity solve (smoother, thicker motion when enabled). +::: +:::field name="viscous" type="number" optional default="30" +Viscosity coefficient used when `isViscous` is `true`. +::: +:::field name="iterationsViscous" type="number" optional default="32" +Number of Gauss-Seidel iterations for viscosity (higher = smoother, slower). +::: +:::field name="iterationsPoisson" type="number" optional default="32" +Number of pressure Poisson iterations to enforce incompressibility. +::: +:::field name="dt" type="number" optional default="0.014" +Fixed simulation timestep used inside the advection / diffusion passes. +::: +:::field name="BFECC" type="boolean" optional default="true" +Enable BFECC advection (error-compensated) for crisper flow; disable for slight performance gain. +::: +:::field name="resolution" type="number" optional default="0.5" +Simulation texture scale relative to canvas size (lower = better performance, more blur). +::: +:::field name="isBounce" type="boolean" optional default="false" +If true, shows bounce boundaries (velocity clamped at edges). +::: +:::field name="colors" type="string[]" optional default="['#5227FF', '#FF9FFC', '#B19EEF']" +Array of hex color stops used to build the velocity-to-color palette. +::: +:::field name="autoDemo" type="boolean" optional default="true" +Enable idle auto-driving of the pointer when no user interaction. +::: +:::field name="autoSpeed" type="number" optional default="0.5" +Speed (normalized units/sec) for auto pointer motion. +::: +:::field name="autoIntensity" type="number" optional default="2.2" +Multiplier applied to velocity delta while in auto mode. +::: +:::field name="takeoverDuration" type="number" optional default="2.5" +Seconds to interpolate from auto pointer to real cursor when user moves mouse. +::: +:::field name="autoResumeDelay" type="number" optional default="1000" +Milliseconds of inactivity before auto mode resumes. +::: +:::field name="autoRampDuration" type="number" optional default="0.6" +Seconds to ramp auto movement speed from 0 to full after activation. +::: +:::field name="className" type="string" optional +Custom class name to apply to the container element +::: +:::field name="style" type="CSSProperties" optional +Custom inline styles to apply to the container element +::: +:::: + +**Example**: + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: liquid-ether + effectConfig: + mouseForce: 20 + cursorSize: 100 + isViscous: false + viscous: 30 + iterationsViscous: 32 + iterationsPoisson: 32 + dt: 0.014 + BFECC: true + resolution: 0.5 + isBounce: false + colors: [#5227FF, #FF9FFC, #B19EEF] + autoDemo: true + autoSpeed: 0.5 + autoIntensity: 2.2 + takeoverDuration: 0.25 + autoResumeDelay: 1000 + autoRampDuration: 0.6 +--- +``` + +### dot-grid + +#### Effect Preview + +![dot-grid](/images/hero-effects/dot-grid.png) + +#### Install dependencies + +:::npm-to + +```sh +npm i three gsap +``` + +::: + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: dot-grid +--- +``` + +#### Configuration + +::::field-group +:::field name="dotSize" type="number" optional default="5" +Size of each dot in pixels. +::: +:::field name="gap" type="number" optional default="15" +Gap between each dot in pixels. +::: +:::field name="baseColor" type="string" optional default="'#ebebf5'" +Base color of the dots. +::: +:::field name="activeColor" type="string" optional default="'#8cccd5'" +Color of dots when hovered or activated. +::: +:::field name="proximity" type="number" optional default="120" +Radius around the mouse pointer within which dots react. +::: +:::field name="speedTrigger" type="number" optional default="100" +Mouse speed threshold to trigger inertia effect. +::: +:::field name="shockRadius" type="number" optional default="250" +Radius of the shockwave effect on click. +::: +:::field name="shockStrength" type="number" optional default="5" +Strength of the shockwave effect on click. +::: +:::field name="maxSpeed" type="number" optional default="5000" +Maximum speed for inertia calculation. +::: +:::field name="resistance" type="number" optional default="750" +Resistance for the inertia effect. +::: +:::field name="returnDuration" type="number" optional default="1.5" +Duration for dots to return to their original position after inertia. +::: +:::field name="className" type="string" optional +CSS class names applied to the container. +::: +:::field name="style" type="CSSProperties" optional +Inline styles applied to the container. +::: +:::: + +**Example**: + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: dot-grid + effectConfig: + dotSize: 5 + gap: 15 + baseColor: #ebebf5 + activeColor: #8cccd5 + proximity: 120 + speedTrigger: 100 + shockRadius: 250 + shockStrength: 5 + maxSpeed: 5000 + resistance: 750 + returnDuration: 1.5 +--- +``` + +### iridescence + +#### Effect Preview + +![iridescence](/images/hero-effects/iridescence.png) + +#### Install dependencies + +:::npm-to + +```sh +npm i ogl +``` + +::: + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: iridescence +--- +``` + +#### Configuration + +::::field-group +:::field name="color" type="readonly [number, number, number]" optional default="[1, 1, 1]" +Base color as an array of RGB values (each between 0 and 1). +::: +:::field name="speed" type="number" optional default="1" +Speed multiplier for the animation. +::: +:::field name="amplitude" type="number" optional default="0.1" +Amplitude for the mouse-driven effect. +::: +:::field name="mouseReact" type="boolean" optional default="true" +Enable or disable mouse interaction with the shader. +::: +:::: + +**Example**: + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: iridescence + effectConfig: + color: [1, 1, 1] + speed: 1.0 + amplitude: 0.1 + mouseReact: true +--- +``` + +### orb + +#### Effect Preview + +![orb](/images/hero-effects/orb.png) + +#### Install dependencies + +:::npm-to + +```sh +npm i ogl +``` + +::: + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: orb +--- +``` + +#### Configuration + +::::field-group +:::field name="hue" type="number" optional default="0" +The base hue for the orb (in degrees). +::: +:::field name="hoverIntensity" type="number" optional default="0.2" +Controls the intensity of the hover distortion effect. +::: +:::field name="rotateOnHover" type="boolean" optional default="true" +Toggle to enable or disable continuous rotation on hover. +::: +:::field name="forceHoverState" type="boolean" optional default="false" +Force hover animations even when the orb is not actually hovered. +::: +:::field name="className" type="string" optional +Additional CSS classes for the component. +::: +:::: + +**Example**: + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: orb + effectConfig: + hue: 0 + hoverIntensity: 0.2 + rotateOnHover: true + forceHoverState: false +--- +``` + +### beams + +#### Effect Preview + +![beams](/images/hero-effects/beams.png) + +#### Install dependencies + +:::npm-to + +```sh +npm i three +``` + +::: + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: beams +--- +``` + +#### Configuration + +::::field-group +:::field name="beamWidth" type="number" optional default="2" +Width of each beam. +::: +:::field name="beamHeight" type="number" optional default="15" +Height of each beam. +::: +:::field name="beamNumber" type="number" optional default="12" +Number of beams to display. +::: +:::field name="lightColor" type="string" optional default="#fff" +Color of the directional light. +::: +:::field name="speed" type="number" optional default="2" +Speed of the animation. +::: +:::field name="noiseIntensity" type="number" optional default="1.75" +Intensity of the noise effect overlay. +::: +:::field name="scale" type="number" optional default="0.2" +Scale of the noise pattern. +::: +:::field name="rotation" type="number" optional default="0" +Rotation of the entire beams system in degrees. +::: +:::: + +**Example**: + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: beams + effectConfig: + beamWidth: 2 + beamHeight: 15 + beamNumber: 12 + lightColor: #fff + speed: 2 + noiseIntensity: 1.75 + scale: 0.2 + rotation: 0 +--- +``` + +### lightning + +#### Effect Preview + +![lightning](/images/hero-effects/lightning.png) + +#### Usage + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: lightning +--- +``` + +#### Configuration + +::::field-group +:::field name="hue" type="number" optional default="255" +Hue of the lightning in degrees (0 to 360). +::: +:::field name="xOffset" type="number" optional default="0" +Horizontal offset of the lightning in normalized units. +::: +:::field name="speed" type="number" optional default="1" +Animation speed multiplier for the lightning. +::: +:::field name="intensity" type="number" optional default="1" +Brightness multiplier for the lightning. +::: +:::field name="size" type="number" optional default="1" +Scale factor for the bolt size. +::: +:::: + +**Example**: + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: lightning + effectConfig: + hue: 255 + xOffset: 0 + speed: 1 + intensity: 1 + size: 1 +--- +``` diff --git a/docs/en/guide/custom/home.md b/docs/en/guide/custom/home.md index bf46d4bf..2f3b805a 100644 --- a/docs/en/guide/custom/home.md +++ b/docs/en/guide/custom/home.md @@ -140,8 +140,6 @@ config: Suitable for documentation-type sites, placed at the top. -**Tool Support: [Homepage Hero Tint Plate Configuration Tool](../../tools/home-hero-tint-plate.md)** - ```ts interface PlumeThemeHomeHero extends PlumeHomeConfigBase { type: 'hero' @@ -160,97 +158,22 @@ interface PlumeThemeHomeHero extends PlumeHomeConfigBase { } } /** - * Background image. "tint-plate" is a preset effect, or a custom image URL can be provided. + * The built-in background effects of the theme, if they are not preset background effects, allow for a background image link address to be passed in. */ - background?: 'tint-plate' | string - + effect?: 'tint-plate' | 'prism' | 'pixel-blast' | 'hyper-speed' | 'liquid-ether' + | 'dot-grid' | 'iridescence' | 'orb' | 'beams' | 'lightning' | string /** - * When background is the preset, configure RGB values to adjust the background color. - * This configuration only takes effect when `background` is set to `tint-plate`. + * Background effect configuration options vary depending on the value of `effect`. */ - tintPlate?: TintPlate + effectConfig?: any /** * If using a non-preset background, set the filter effect for the background image. */ filter?: string } -interface TintPlateObj { - // value represents the base color value, range 0 ~ 255 - // offset represents the offset from the base value, range 0 ~ (255 - value) - r: { value: number, offset: number } - g: { value: number, offset: number } - b: { value: number, offset: number } -} -type TintPlate - = | number // e.g., 210 - | string // e.g., '210,210,210' => red,green,blue - // e.g., { r: { value: 220, offset: 36 }, g: { value: 220, offset: 36 }, b: { value: 220, offset: 36 } } - | TintPlateObj - // e.g., { light: 210, dark: 20 } - // e.g., { light: '210,210,210', dark: '20,20,20' } - | { light: number | string, dark: number | string } - | { light: TintPlateObj, dark: TintPlateObj } ``` -**Example:** - -```md ---- -home: true -config: - - - type: hero - full: true - background: tint-plate - hero: - name: Theme Plume - tagline: Vuepress Next Theme - text: A minimalistic, feature-rich vuepress documentation & blog theme - actions: - - - theme: brand - text: Get Started → - link: / - - - theme: alt - text: Github - link: https://github.com/pengzhanbo/vuepress-theme-plume ---- -``` - -**Result:** - -:::demo-wrapper img no-padding -Theme Plume -::: - -When `background` is configured as `tint-plate`, you can additionally configure `tintPlate` to adjust -the background hue, with a range of `0 ~ 255`: - -```md ---- -home: true -config: - - - type: hero - full: true - background: tint-plate - tintPlate: 210 ---- -``` - -`tintPlate` is used to configure RGB values: - -- When configured as a single number, it sets the red, green, and blue color channels to the same value (range: 0 - 255). Example: `210`. -- When configured as three comma-separated values, it sets the red, green, and blue channels to different values (range: 0 - 255). Example: `210,210,210`. -- When configured as a `TintPlateObj`, it allows more granular control over each color channel and its corresponding offset. -- It can also be configured as `{ light, dark }` to use different color values in dark and light modes. - -::: info -To facilitate the configuration of aesthetically pleasing and personalized backgrounds, -the theme also provides a [Homepage Hero Tint Plate Configuration Tool](../../tools/custom-theme.md) -for visual configuration. You can generate configuration content and copy it directly for use in your own project. -::: +[See **Background Effects Configuration & Demo** to learn more.](./home-hero-effect.md){.read-more} The theme also supports customizing the colors of `name`, `tagline`, and `text`. diff --git a/docs/guide/custom/home-hero-effect.md b/docs/guide/custom/home-hero-effect.md new file mode 100644 index 00000000..8e57d911 --- /dev/null +++ b/docs/guide/custom/home-hero-effect.md @@ -0,0 +1,1303 @@ +--- +title: Hero 背景效果 +icon: icon-park-outline:effects +createTime: 2025/10/24 15:35:14 +permalink: /guide/custom-home/hero-effect/ +badge: 新 +--- + +## 概述 + +对于大多数的站点而言,一个 **炫酷好看** 首页首屏,能够更容易的吸引用户停留下来。 +但实现 **炫酷好看** 往往需要比较复杂的技术成本,以及一些不错的灵感。 + +主题对 **首页** 的 **Hero** 部分,内置了一系列 **炫酷好看** 的背景效果, +通过简单的配置即可应用到你的站点首页中: + +```md {6,8-10} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate + effectConfig: + key: value +--- +``` + +::: important 当且仅当 `type: hero` 时,主题会应用 `effect` 配置的效果。 +::: + +`effect` 支持以下可选值: + +- [tint-plate](#tint-plate) +- [prism](#prism) +- [pixel-blast](#pixel-blast) +- [hyper-speed](#hyper-speed) +- [liquid-ether](#liquid-ether) +- [dot-grid](#dot-grid) +- [iridescence](#iridescence) +- [orb](#orb) +- [beams](#beams) +- [lightning](#lightning) + +`effectConfig` 需要根据不同的 `effect` 值,进行不同的配置。通常你不需要配置,主题会自动应用预设配置。 + +:::important 重要说明 +主题内置的效果,得益于优秀开源项目 [vue-bits](https://vue-bits.dev/)。 +遵循 MIT 协议,复制并修改其中的代码到主题中。 +::: + +## 强制深色模式 + +大部分背景效果在 **深色模式** 下表现更加出色,因此建议开启 [深色模式](../../config/theme.md#appearance) 以获得最佳体验。 + +但对于文档部分,也许 **浅色模式** 才是你想要的,因此主题在 `hero` 中提供了 `forceDark` 选项, +仅强制将首页强制变更为 **深色模式**,而不影响其他页面的颜色模式。 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + forceDark: true + effect: lightning +--- +``` + +## 背景动态效果 + +::: important +不同的效果可能会依赖 `three` 或 `gsap` 或 `ogl`,你需要根据所使用的效果,手动安装相应的依赖包。 + +主题通过 **按需加载** 的方式动态加载这些效果, 因此不用担心最终打包后的文档体积过大。 +::: + +### tint-plate + +#### 效果预览 + +![tint-plate](/images/hero-effects/tint-plate.png) + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate +--- +``` + +#### 配置项 + +`effectConfig` 用于配置 RGB 值: + +- 配置为单个值时,表示配置 red,green,blue 三个颜色值为相同值,范围: 0 - 255。示例: `210`。 +- 配置为三个值时,表示配置 red,green,blue 三个颜色值为不同值,范围: 0 - 255。示例: `210,210,210`。 +- 配置为 `TintPlate`,则可以更加灵活的控制每个颜色值和对应的偏移量。 +- 还可以配置为 `{ light: TintPlate, dark: TintPlate }`,在深色模式和浅色模式下使用不同的颜色值。 + +```ts +interface TintPlate { + r: { value: number, offset: number } // value 表示色值,offset 表示偏移量 + g: { value: number, offset: number } + b: { value: number, offset: number } +} +``` + +**示例**: + +::: code-tabs + +@tab 单个值 + +```md {8,9} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate + effectConfig: 210 +--- +``` + +@tab 三个值 + +```md {8,9} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate + effectConfig: 210,210,210 +--- +``` + +@tab TintPlate + +```md {8-18} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: tint-plate + effectConfig: + r: + value: 210 + offset: 0 + g: + value: 210 + offset: 0 + b: + value: 210 + offset: 0 +--- +``` + +::: + +::: info +为了便于用户配置 美观的个性化的背景,主题还提供了 [首页背景色板配置工具](../../tools/home-hero-tint-plate.md) +进行可视化操作,生成配置内容,你可以直接复制它们用于自己的项目中。 +::: + +### prism + +#### 效果预览 + +![prism](/images/hero-effects/prism.png) + +#### 安装依赖 + +:::npm-to + +```sh +npm i ogl +``` + +::: + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: prism +--- +``` + +#### 配置项 + +:::: field-group + +:::field name="height" type="number" optional default="3.5" +棱柱的顶点高度(world units) +::: +:::field name="baseWidth" type="number" optional default="5.5" +X/Z轴总基准宽度(world units) +::: +:::field name="animationType" type="'rotate' | 'hover' | '3drotate'" optional default="'rotate'" +动画模式:着色器摆动、指针悬停倾斜或完全三维旋转。 +::: +:::field name="glow" type="number" optional default="1" +发光/溢出强度乘数。 +::: +:::field name="offset" type="{ x?: number, y?: number }" optional default="{ x: 0, y: 0 }" +画布内的像素偏移(x → 向右,y → 向下)。 +::: +:::field name="noise" type="number" optional default="0" +最终颜色中添加的颗粒噪声量(0表示禁用)。 +::: +:::field name="transparent" type="boolean" optional default="true" +画布是否具有Alpha通道(透明背景)。 +::: +:::field name="scale" type="number" optional default="3.6" +棱镜的整体屏幕空间比例(数值越大,显示尺寸越大)。 +::: +:::field name="hueShift" type="number" optional default="0" +色调旋转(弧度)应用于最终颜色。 +::: +:::field name="colorFrequency" type="number" optional default="1" +控制颜色变化的内部正弦带频率。 +::: +:::field name="hoverStrength" type="number" optional default="2" +悬停倾斜(俯仰/偏航幅度)灵敏度。 +::: +:::field name="inertia" type="number" optional default="0.05" +悬停缓动因子(`0 ~ 1`,数值越大响应越灵敏)。 +::: +:::field name="bloom" type="number" optional default="1" +在光泽之上叠加额外的绽放效果层次。 +::: +:::field name="suspendWhenOffscreen" type="boolean" optional default="true" +当元素不在视口内时暂停渲染。 +::: +:::field name="timeScale" type="number" optional default="0.5" +动画全局时间倍率(0=冻结,1=正常)。 +::: +:::: + +**示例**: + +```md {8-26} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: prism + effectConfig: + height: 3.5, + baseWidth: 5.5 + animationType: rotate + glow: 1 + offset: + x: 0 + y: 0 + noise: 0 + transparent: true + scale: 3.6 + hueShift: 0 + colorFrequency: 1 + hoverStrength: 2 + inertia: 0.05 + bloom: 1 + suspendWhenOffscreen: true + timeScale: 0.5 +--- +``` + +### pixel-blast + +#### 效果预览 + +![pixel-blast](/images/hero-effects/pixel-blast.png) + +#### 安装依赖 + +:::npm-to + +```sh +npm i three postprocessing +``` + +::: + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: pixel-blast +--- +``` + +#### 配置项 + +::::field-group +:::field name="variant" type="'square' | 'circle' | 'triangle' | 'diamond'" optional default="'square'" +像素形状变体 +::: +:::field name="pixelSize" type="number" optional default="4" +基础像素尺寸(根据DPI自动缩放)。 +::: +:::field name="color" type="string" optional default="'#5086a1'" +像素颜色 +::: +:::field name="antialias" type="boolean" optional default="true" +是否启用抗锯齿 +::: +:::field name="patternScale" type="number" optional default="2" +噪声/图案比例 +::: +:::field name="patternDensity" type="number" optional default="1" +调整图案密度 +::: +:::field name="liquid" type="boolean" optional default="false" +是否启用液体扭曲效果。 +::: +:::field name="liquidStrength" type="number" optional default="0.1" +液体扭曲强度 +::: +:::field name="liquidRadius" type="number" optional default="1" +液体触摸笔刷半径比例。 +::: +:::field name="liquidWobbleSpeed" type="number" optional default="4.5" +液体晃动频率 +::: +:::field name="pixelSizeJitter" type="number" optional default="0" +应用于覆盖范围的随机抖动 +::: +:::field name="enableRipples" type="boolean" optional default="true" +启用点击涟漪效果 +::: +:::field name="rippleIntensityScale" type="number" optional default="1" +纹波强度乘数 +::: +:::field name="rippleThickness" type="number" optional default="0.1" +纹波环厚度 +::: +:::field name="rippleSpeed" type="number" optional default="0.3" +纹波传播速度 +::: +:::field name="autoPauseOffscreen" type="boolean" optional default="true" +当元素不在视口内时自动暂停渲染 +::: +:::field name="speed" type="number" optional default="0.5" +动画时间缩放比例 +::: +:::field name="transparent" type="boolean" optional default="true" +透明背景 +::: +:::field name="edgeFade" type="number" optional default="0.5" +边缘淡入距离(`0-1`)。 +::: +:::field name="noiseAmount" type="number" optional default="0" +噪声强度 +::: +:::field name="className" type="string" optional +容器自定义类名 +::: +:::field name="style" type="CSSProperties" optional +容器自定义样式 +::: +:::field name="backgroundImage" type="string" optional +背景图像 URL +::: +:::: + +**示例**: + +```md {8-29} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: pixel-blast + effectConfig: + variant: square + pixelSize: 4 + color: #5086a1 + antialias: true + patternScale: 2 + patternDensity: 1 + liquid: false + liquidStrength: 0.1 + liquidRadius: 1 + pixelSizeJitter: 0 + enableRipples: true + rippleIntensityScale: 1 + rippleThickness: 0.1 + rippleSpeed: 0.3 + liquidWobbleSpeed: 4.5 + autoPauseOffscreen: true + speed: 0.5 + transparent: true + edgeFade: 0.5 + noiseAmount: 0 +--- +``` + +### hyper-speed + +#### 效果预览 + +![hyper-speed](/images/hero-effects/hyper-speed.png) + +#### 安装依赖 + +:::npm-to + +```sh +npm i three postprocessing +``` + +::: + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed +--- +``` + +#### 配置项 + +```ts +interface ThemeHomeHeroHyperSpeedDistortion { + uniforms: Record + getDistortion: string +} + +interface ThemeHomeHeroHyperSpeedColors { + roadColor: number + islandColor: number + background: number + shoulderLines: number + brokenLines: number + leftCars: number[] + rightCars: number[] + sticks: number +} + +interface ThemeHomeHeroHyperSpeed { + distortion?: string | ThemeHomeHeroHyperSpeedDistortion + length: number + roadWidth: number + islandWidth: number + lanesPerRoad: number + fov: number + fovSpeedUp: number + speedUp: number + carLightsFade: number + totalSideLightSticks: number + lightPairsPerRoadWay: number + shoulderLinesWidthPercentage: number + brokenLinesWidthPercentage: number + brokenLinesLengthPercentage: number + lightStickWidth: [number, number] + lightStickHeight: [number, number] + movingAwaySpeed: [number, number] + movingCloserSpeed: [number, number] + carLightsLength: [number, number] + carLightsRadius: [number, number] + carWidthPercentage: [number, number] + carShiftX: [number, number] + carFloorSeparation: [number, number] + colors: ThemeHomeHeroHyperSpeedColors + isHyper?: boolean +} +``` + +:::warning [vue-bits](https://vue-bits.dev/backgrounds/hyperspeed) 未提供详细配置项说明,请谨慎使用。 +::: + +可以使用以下预设配置,直接复制到你的 markdown 文件中: + +:::code-tabs +@tab Cyberpunk + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: turbulentDistortion + length: 400 + roadWidth: 10 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 20 + lightPairsPerRoadWay: 40 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [12, 80] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.8, 0.8] + carFloorSeparation: [0, 5] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xd856bf, 0x6750a2, 0xc247ac] + rightCars: [0x03b3c3, 0x0e5ea5, 0x324555] + sticks: 0x03b3c3 +--- +``` + +@tab Akira + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: mountainDistortion + length: 400 + roadWidth: 9 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 50 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [20, 60] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.2, 0.2] + carFloorSeparation: [0.05, 1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xff102a, 0xeb383e, 0xff102a] + rightCars: [0xdadafa, 0xbebae3, 0x8f97e4] + sticks: 0xdadafa +--- +``` + +@tab Golden + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: xyDistortion + length: 400 + roadWidth: 9 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 3 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 30 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.02, 0.05] + lightStickHeight: [0.3, 0.7] + movingAwaySpeed: [20, 50] + movingCloserSpeed: [-150, -230] + carLightsLength: [20, 80] + carLightsRadius: [0.03, 0.08] + carWidthPercentage: [0.1, 0.5] + carShiftX: [-0.5, 0.5] + carFloorSeparation: [0, 0.1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318, + leftCars: [0x7d0d1b, 0xa90519, 0xff102a] + rightCars: [0xf1eece, 0xe6e2b1, 0xdfd98a] + sticks: 0xf1eece +--- +``` + +@tab Split + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: LongRaceDistortion + length: 400 + roadWidth: 10 + islandWidth: 5 + lanesPerRoad: 2 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 70 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [20, 60] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.2, 0.2] + carFloorSeparation: [0.05, 1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xff5f73, 0xe74d60, 0xff102a] + rightCars: [0xa4e3e6, 0x80d1d4, 0x53c2c6] + sticks: 0xa4e3e6 +--- +``` + +@tab Highway + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: turbulentDistortion + length: 400 + roadWidth: 9 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 50 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [20, 60] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.2, 0.2] + carFloorSeparation: [0.05, 1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xdc5b20, 0xdca320, 0xdc2020] + rightCars: [0x334bf7, 0xe5e6ed, 0xbfc6f3] + sticks: 0xc5e8eb +--- +``` + +@tab Deep + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: hyper-speed + effectConfig: + distortion: deepDistortion + length: 400 + roadWidth: 18 + islandWidth: 2 + lanesPerRoad: 3 + fov: 90 + fovSpeedUp: 150 + speedUp: 2 + carLightsFade: 0.4 + totalSideLightSticks: 50 + lightPairsPerRoadWay: 50 + shoulderLinesWidthPercentage: 0.05 + brokenLinesWidthPercentage: 0.1 + brokenLinesLengthPercentage: 0.5 + lightStickWidth: [0.12, 0.5] + lightStickHeight: [1.3, 1.7] + movingAwaySpeed: [60, 80] + movingCloserSpeed: [-120, -160] + carLightsLength: [20, 60] + carLightsRadius: [0.05, 0.14] + carWidthPercentage: [0.3, 0.5] + carShiftX: [-0.2, 0.2] + carFloorSeparation: [0.05, 1] + colors: + roadColor: 0x080808 + islandColor: 0x0a0a0a + background: 0x000000 + shoulderLines: 0x131318 + brokenLines: 0x131318 + leftCars: [0xff322f, 0xa33010, 0xa81508] + rightCars: [0xfdfdf0, 0xf3dea0, 0xe2bb88] + sticks: 0xfdfdf0 +--- +``` + +::: + +### liquid-ether + +#### 效果预览 + +![liquid-ether](/images/hero-effects/liquid-ether.png) + +#### 安装依赖 + +:::npm-to + +```sh +npm i three +``` + +::: + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: liquid-ether +--- +``` + +#### 配置项 + +::::field-group +:::field name="mouseForce" type="number" optional default="20" +鼠标/触摸移动注入速度时的强度系数。 +::: +:::field name="cursorSize" type="number" optional default="100" +光标半径(以基本分辨率的像素为单位)。 +::: +:::field name="isViscous" type="boolean" optional default="false" +启用迭代性质量解决方案(更平滑,更粗糙的运动)。 +::: +:::field name="viscous" type="number" optional default="30" +当 `isViscous` 为 `true` 时使用的粘性系数。 +::: +:::field name="iterationsViscous" type="number" optional default="32" +粘性的高斯-塞德尔迭代次数(值越大 = 更平滑,更慢)。 +::: +:::field name="iterationsPoisson" type="number" optional default="32" +用于确保不可压缩性的压力泊松迭代次数。 +::: +:::field name="dt" type="number" optional default="0.014" +内部的对流/扩散迭代中使用固定的模拟时间步长。 +::: +:::field name="BFECC" type="boolean" optional default="true" +启用 BFECC 传输(错误补偿)以获得更清晰的流动,禁用以获得稍微的性能提升。 +::: +:::field name="resolution" type="number" optional default="0.5" +相对于画布大小的仿真纹理缩放(值越小,更好的性能、更模糊)。 +::: +:::field name="isBounce" type="boolean" optional default="false" +如果为 true,显示弹跳边界(速度在边缘上限)。 +::: +:::field name="colors" type="string[]" optional default="['#5227FF', '#FF9FFC', '#B19EEF']" +用于构建速度-颜色映射调色板的十六进制颜色停止点数组。 +::: +:::field name="autoDemo" type="boolean" optional default="true" +启用无用户交互时的自动驾驶指针。 +::: +:::field name="autoSpeed" type="number" optional default="0.5" +自动指针运动的速度(标准化单位/秒)。 +::: +:::field name="autoIntensity" type="number" optional default="2.2" +在自动模式下应用于速度增量的乘数。 +::: +:::field name="takeoverDuration" type="number" optional default="2.5" +在用户移动鼠标时从自动指针插值到实际光标的秒数。 +::: +:::field name="autoResumeDelay" type="number" optional default="1000" +在自动模式恢复之前的不活动时间(毫秒)。 +::: +:::field name="autoRampDuration" type="number" optional default="0.6" +在激活后从 0 开始加速自动移动速度的秒数。 +::: +:::field name="className" type="string" optional +应用于容器上的 CSS 类名。 +::: +:::field name="style" type="CSSProperties" optional +应用于容器上的 CSS 样式。 +::: +:::: + +**示例**: + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: liquid-ether + effectConfig: + mouseForce: 20 + cursorSize: 100 + isViscous: false + viscous: 30 + iterationsViscous: 32 + iterationsPoisson: 32 + dt: 0.014 + BFECC: true + resolution: 0.5 + isBounce: false + colors: [#5227FF, #FF9FFC, #B19EEF] + autoDemo: true + autoSpeed: 0.5 + autoIntensity: 2.2 + takeoverDuration: 0.25 + autoResumeDelay: 1000 + autoRampDuration: 0.6 +--- +``` + +### dot-grid + +#### 效果预览 + +![dot-grid](/images/hero-effects/dot-grid.png) + +#### 安装依赖 + +:::npm-to + +```sh +npm i three gsap +``` + +::: + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: dot-grid +--- +``` + +#### 配置项 + +::::field-group +:::field name="dotSize" type="number" optional default="5" +每个点的尺寸(像素)。 +::: +:::field name="gap" type="number" optional default="15" +每个点之间的间隙(像素)。 +::: +:::field name="baseColor" type="string" optional default="'#ebebf5'" +点的基本颜色。 +::: +:::field name="activeColor" type="string" optional default="'#8cccd5'" +鼠标悬停或激活时点的颜色。 +::: +:::field name="proximity" type="number" optional default="120" +鼠标指针周围的半径,在此范围内点会响应 +::: +:::field name="speedTrigger" type="number" optional default="100" +触发惯性效果的鼠标速度阈值。 +::: +:::field name="shockRadius" type="number" optional default="250" +点击时的震动波半径。 +::: +:::field name="shockStrength" type="number" optional default="5" +点击时震动波的强度。 +::: +:::field name="maxSpeed" type="number" optional default="5000" +惯性计算的最大速度。 +::: +:::field name="resistance" type="number" optional default="750" +惯性效果的阻力 +::: +:::field name="returnDuration" type="number" optional default="1.5" +惯性后点返回原始位置的持续时间。 +::: +:::field name="className" type="string" optional +应用于容器上的 CSS 类名。 +::: +:::field name="style" type="CSSProperties" optional +应用于容器上的 CSS 样式。 +::: +:::: + +**示例**: + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: dot-grid + effectConfig: + dotSize: 5 + gap: 15 + baseColor: #ebebf5 + activeColor: #8cccd5 + proximity: 120 + speedTrigger: 100 + shockRadius: 250 + shockStrength: 5 + maxSpeed: 5000 + resistance: 750 + returnDuration: 1.5 +--- +``` + +### iridescence + +#### 效果预览 + +![iridescence](/images/hero-effects/iridescence.png) + +#### 安装依赖 + +:::npm-to + +```sh +npm i ogl +``` + +::: + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: iridescence +--- +``` + +#### 配置项 + +::::field-group +:::field name="color" type="readonly [number, number, number]" optional default="[1, 1, 1]" +基准色以 RGB 值数组形式表示(每个数值范围在 `0` 到 `1` 之间)。 +::: +:::field name="speed" type="number" optional default="1" +动画的速度乘数 +::: +:::field name="amplitude" type="number" optional default="0.1" +鼠标驱动效果的振幅。 +::: +:::field name="mouseReact" type="boolean" optional default="true" +启用或禁用鼠标与着色器的交互 +::: +:::: + +**示例**: + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: iridescence + effectConfig: + color: [1, 1, 1] + speed: 1.0 + amplitude: 0.1 + mouseReact: true +--- +``` + +### orb + +#### 效果预览 + +![orb](/images/hero-effects/orb.png) + +#### 安装依赖 + +:::npm-to + +```sh +npm i ogl +``` + +::: + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: orb +--- +``` + +#### 配置项 + +::::field-group +:::field name="hue" type="number" optional default="0" +球的基本色调(度)。 +::: +:::field name="hoverIntensity" type="number" optional default="0.2" +控制悬停扭曲效果的强度。 +::: +:::field name="rotateOnHover" type="boolean" optional default="true" +启用或禁用悬停时的持续旋转。 +::: +:::field name="forceHoverState" type="boolean" optional default="false" +即使没有悬停,也强制启用悬停动画。 +::: +:::field name="className" type="string" optional +应用于容器上的 CSS 类名。 +::: +:::: + +**示例**: + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: orb + effectConfig: + hue: 0 + hoverIntensity: 0.2 + rotateOnHover: true + forceHoverState: false +--- +``` + +### beams + +#### 效果预览 + +![beams](/images/hero-effects/beams.png) + +#### 安装依赖 + +:::npm-to + +```sh +npm i three +``` + +::: + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: beams +--- +``` + +#### 配置项 + +::::field-group +:::field name="beamWidth" type="number" optional default="2" +每个激光束的宽度。 +::: +:::field name="beamHeight" type="number" optional default="15" +每个激光束的高度。 +::: +:::field name="beamNumber" type="number" optional default="12" +要显示的激光束数量。 +::: +:::field name="lightColor" type="string" optional default="#fff" +方向光的颜色。 +::: +:::field name="speed" type="number" optional default="2" +动画的速度。 +::: +:::field name="noiseIntensity" type="number" optional default="1.75" +噪音效果的强度。 +::: +:::field name="scale" type="number" optional default="0.2" +噪音模式的缩放比例。 +::: +:::field name="rotation" type="number" optional default="0" +整个激光束系统的旋转角度(度)。 +::: +:::: + +**示例**: + +```md +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: beams + effectConfig: + beamWidth: 2 + beamHeight: 15 + beamNumber: 12 + lightColor: #fff + speed: 2 + noiseIntensity: 1.75 + scale: 0.2 + rotation: 0 +--- +``` + +### lightning + +#### 效果预览 + +![lightning](/images/hero-effects/lightning.png) + +#### 使用方法 + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: lightning +--- +``` + +#### 配置项 + +::::field-group +:::field name="hue" type="number" optional default="255" +光束的色调(度)(0到360)。 +::: +:::field name="xOffset" type="number" optional default="0" +光束的水平偏移量(标准化单位)。 +::: +:::field name="speed" type="number" optional default="1" +光束的动画速度乘数。 +::: +:::field name="intensity" type="number" optional default="1" +光束的亮度乘数。 +::: +:::field name="size" type="number" optional default="1" +光束的缩放因子。 +::: +:::: + +**示例**: + +```md {8} +--- +pageLayout: home +home: true +config: + - + type: hero + full: true + effect: lightning + effectConfig: + hue: 255 + xOffset: 0 + speed: 1 + intensity: 1 + size: 1 +--- +``` diff --git a/docs/guide/custom/home.md b/docs/guide/custom/home.md index fc8dec04..4bd05547 100644 --- a/docs/guide/custom/home.md +++ b/docs/guide/custom/home.md @@ -139,8 +139,6 @@ config: 适用于 文档 类型站点,放置于 首位。 -**工具支持: [首页背景色板配置工具](../../tools/home-hero-tint-plate.md)** - ```ts interface PlumeThemeHomeHero extends PlumeHomeConfigBase { type: 'hero' @@ -159,95 +157,22 @@ interface PlumeThemeHomeHero extends PlumeHomeConfigBase { } } /** - * 背景图片,"tint-plate" 为预设效果, 也可以配置为图片地址 + * 主题内置的背景效果,如果为非预设背景效果,则可以传入背景图片链接地址 */ - background?: 'tint-plate' | string - + effect?: 'tint-plate' | 'prism' | 'pixel-blast' | 'hyper-speed' | 'liquid-ether' + | 'dot-grid' | 'iridescence' | 'orb' | 'beams' | 'lightning' | string /** - * 当 background 为预设背景时,可以配置 RGB 值,用于调整背景 - * 该配置仅在 `background` 为 `tint-plate` 时生效 + * 背景效果配置项,根据 `effect` 值不同,配置项不同 */ - tintPlate?: TintPlate + effectConfig?: any /** * 如果是非预设背景,可以设置背景图片的滤镜效果 */ filter?: string } -interface TintPlateObj { - // value 表示 基准色值,范围为 0 ~ 255 - // offset 表示 基准色值的偏移量,范围为 0 ~ (255 - value) - r: { value: number, offset: number } - g: { value: number, offset: number } - b: { value: number, offset: number } -} -type TintPlate - = | number // 210 - | string // '210,210,210' => red,green,blue - // { r: { value: 220, offset: 36 }, g: { value: 220, offset: 36 }, b: { value: 220, offset: 36 } } - | TintPlate - // { light: 210, dark: 20 } - // { light: '210,210,210', dark: '20,20,20' } - | { light: number | string, dark: number | string } - | { light: TintPlate, dark: TintPlate } ``` -**示例:** - -```md ---- -home: true -config: - - - type: hero - full: true - background: tint-plate - hero: - name: Theme Plume - tagline: Vuepress Next Theme - text: 一个简约的,功能丰富的 vuepress 文档&博客 主题 - actions: - - - theme: brand - text: 快速开始 → - link: / - - - theme: alt - text: Github - link: https://github.com/pengzhanbo/vuepress-theme-plume ---- -``` - -**效果:** - -:::demo-wrapper img no-padding -Theme Plume -::: - -当 `background` 配置为 `tint-plate` 时,还可以额外配置 `tintPlate` 调整 背景色调,范围为 `0 ~ 255`: - -```md ---- -home: true -config: - - - type: hero - full: true - background: tint-plate - tintPlate: 210 ---- -``` - -`tintPlate` 用于配置 RGB 值: - -- 配置为单个值时,表示配置 red,green,blue 三个颜色值为相同值,范围: 0 - 255。示例: `210`。 -- 配置为三个值时,表示配置 red,green,blue 三个颜色值为不同值,范围: 0 - 255。示例: `210,210,210`。 -- 配置为 `TintPlate`,则可以更加灵活的控制每个颜色值和对应的偏移量。 -- 还可以配置为 `{ light, dark }`,在深色模式和浅色模式下使用不同的颜色值。 - -::: info -为了便于用户配置 美观的个性化的背景,主题还提供了 [首页背景色板配置工具](../../tools/custom-theme.md) -进行可视化操作,生成配置内容,你可以直接复制它们用于自己的项目中。 -::: +[查看 **背景效果 配置 & 演示** 了解更多](./home-hero-effect.md){.read-more} 主题还支持自定义 `name`, `tagline`, `text` 的颜色。 diff --git a/package.json b/package.json index 8b27241c..26902149 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@types/node": "catalog:dev", "@types/picomatch": "catalog:dev", "@types/stylus": "catalog:dev", + "@types/three": "catalog:dev", "@types/webpack-env": "catalog:dev", "@vitest/coverage-istanbul": "catalog:dev", "bumpp": "catalog:dev", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 37d9964a..a918a61d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,6 +51,9 @@ catalogs: '@types/stylus': specifier: ^0.48.43 version: 0.48.43 + '@types/three': + specifier: ^0.180.0 + version: 0.180.0 '@types/webpack-env': specifier: ^1.18.8 version: 1.18.8 @@ -142,6 +145,9 @@ catalogs: dashjs: specifier: ^5.0.3 version: 5.0.3 + gsap: + specifier: ^3.13.0 + version: 3.13.0 hls.js: specifier: ^1.6.13 version: 1.6.13 @@ -151,6 +157,12 @@ catalogs: mpegts.js: specifier: 1.7.3 version: 1.7.3 + ogl: + specifier: ^1.0.11 + version: 1.0.11 + postprocessing: + specifier: ^6.37.8 + version: 6.37.8 pyodide: specifier: ^0.29.0 version: 0.29.0 @@ -160,6 +172,9 @@ catalogs: swiper: specifier: ^12.0.2 version: 12.0.2 + three: + specifier: ^0.180.0 + version: 0.180.0 prod: '@clack/prompts': specifier: ^0.11.0 @@ -418,6 +433,9 @@ importers: '@types/stylus': specifier: catalog:dev version: 0.48.43 + '@types/three': + specifier: catalog:dev + version: 0.180.0 '@types/webpack-env': specifier: catalog:dev version: 1.18.8 @@ -898,9 +916,21 @@ importers: '@iconify/json': specifier: catalog:peer version: 2.2.398 + gsap: + specifier: catalog:peer + version: 3.13.0 + ogl: + specifier: catalog:peer + version: 1.0.11 + postprocessing: + specifier: catalog:peer + version: 6.37.8(three@0.180.0) swiper: specifier: catalog:peer version: 12.0.2 + three: + specifier: catalog:peer + version: 0.180.0 vue-router: specifier: catalog:dev version: 4.6.3(vue@3.5.22(typescript@5.9.3)) @@ -1254,6 +1284,9 @@ packages: peerDependencies: postcss-selector-parser: ^7.0.0 + '@dimforge/rapier3d-compat@0.12.0': + resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==} + '@docsearch/css@4.2.0': resolution: {integrity: sha512-65KU9Fw5fGsPPPlgIghonMcndyx1bszzrDQYLfierN+Ha29yotMHzVS94bPkZS6On9LS8dE4qmW4P/fGjtCf/g==} @@ -2480,6 +2513,9 @@ packages: '@svta/common-media-library@0.12.4': resolution: {integrity: sha512-9EuOoaNmz7JrfGwjsrD9SxF9otU5TNMnbLu1yU4BeLK0W5cDxVXXR58Z89q9u2AnHjIctscjMTYdlqQ1gojTuw==} + '@tweenjs/tween.js@23.1.3': + resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==} + '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -2699,9 +2735,15 @@ packages: '@types/serve-static@1.15.8': resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} + '@types/stats.js@0.17.4': + resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} + '@types/stylus@0.48.43': resolution: {integrity: sha512-72dv/zdhuyXWVHUXG2VTPEQdOG+oen95/DNFx2aMFFaY6LoITI6PwEqf5x31JF49kp2w9hvUzkNfTGBIeg61LQ==} + '@types/three@0.180.0': + resolution: {integrity: sha512-ykFtgCqNnY0IPvDro7h+9ZeLY+qjgUWv+qEvUt84grhenO60Hqd4hScHE7VTB9nOQ/3QM8lkbNE+4vKjEpUxKg==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -2714,6 +2756,9 @@ packages: '@types/webpack-env@1.18.8': resolution: {integrity: sha512-G9eAoJRMLjcvN4I08wB5I7YofOb/kaJNd5uoCMX+LbKXTPCF+ZIHuqTnFaK9Jz1rgs035f9JUPUhNFtqgucy/A==} + '@types/webxr@0.5.24': + resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==} + '@typescript-eslint/eslint-plugin@8.45.0': resolution: {integrity: sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3178,6 +3223,9 @@ packages: peerDependencies: vue: ^3.5.0 + '@webgpu/types@0.1.66': + resolution: {integrity: sha512-YA2hLrwLpDsRueNDXIMqN9NTzD6bCDkuXbOSe0heS+f8YE8usA6Gbv1prj81pzVHrbaAma7zObnIC+I6/sXJgA==} + '@xmldom/xmldom@0.9.8': resolution: {integrity: sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==} engines: {node: '>=14.6'} @@ -4840,6 +4888,9 @@ packages: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} + gsap@3.13.0: + resolution: {integrity: sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw==} + hachure-fill@0.5.2: resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} @@ -5632,6 +5683,7 @@ packages: mathjax-full@3.2.2: resolution: {integrity: sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==} + deprecated: Version 4 replaces this package with the scoped package @mathjax/src mathml-tag-names@2.1.3: resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} @@ -5705,6 +5757,9 @@ packages: mermaid@11.12.0: resolution: {integrity: sha512-ZudVx73BwrMJfCFmSSJT84y6u5brEoV8DOItdHomNLz32uBjNrelm7mg95X7g+C6UoQH/W6mBLGDEDv73JdxBg==} + meshoptimizer@0.22.0: + resolution: {integrity: sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==} + mhchemparser@4.2.1: resolution: {integrity: sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==} @@ -5960,6 +6015,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + ogl@1.0.11: + resolution: {integrity: sha512-kUpC154AFfxi16pmZUK4jk3J+8zxwTWGPo03EoYA8QPbzikHoaC82n6pNTbd+oEaJonaE8aPWBlX7ad9zrqLsA==} + ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} @@ -6246,6 +6304,11 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + postprocessing@6.37.8: + resolution: {integrity: sha512-qTFUKS51z/fuw2U+irz4/TiKJ/0oI70cNtvQG1WxlPKvBdJUfS1CcFswJd5ATY3slotWfvkDDZAsj1X0fU8BOQ==} + peerDependencies: + three: '>= 0.157.0 < 0.181.0' + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -7013,6 +7076,9 @@ packages: peerDependencies: tslib: ^2 + three@0.180.0: + resolution: {integrity: sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==} + throttleit@2.1.0: resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} engines: {node: '>=18'} @@ -8118,6 +8184,8 @@ snapshots: dependencies: postcss-selector-parser: 7.1.0 + '@dimforge/rapier3d-compat@0.12.0': {} + '@docsearch/css@4.2.0': {} '@docsearch/js@4.2.0': {} @@ -9154,6 +9222,8 @@ snapshots: '@svta/common-media-library@0.12.4': {} + '@tweenjs/tween.js@23.1.3': {} + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -9407,10 +9477,22 @@ snapshots: '@types/node': 24.8.1 '@types/send': 0.17.5 + '@types/stats.js@0.17.4': {} + '@types/stylus@0.48.43': dependencies: '@types/node': 24.9.1 + '@types/three@0.180.0': + dependencies: + '@dimforge/rapier3d-compat': 0.12.0 + '@tweenjs/tween.js': 23.1.3 + '@types/stats.js': 0.17.4 + '@types/webxr': 0.5.24 + '@webgpu/types': 0.1.66 + fflate: 0.8.2 + meshoptimizer: 0.22.0 + '@types/trusted-types@2.0.7': {} '@types/unist@3.0.3': {} @@ -9419,6 +9501,8 @@ snapshots: '@types/webpack-env@1.18.8': {} + '@types/webxr@0.5.24': {} + '@typescript-eslint/eslint-plugin@8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.38.0(jiti@2.5.1))(typescript@5.9.3))(eslint@9.38.0(jiti@2.5.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -10148,6 +10232,8 @@ snapshots: dependencies: vue: 3.5.22(typescript@5.9.3) + '@webgpu/types@0.1.66': {} + '@xmldom/xmldom@0.9.8': {} JSONStream@1.3.5: @@ -12078,6 +12164,8 @@ snapshots: section-matter: 1.0.0 strip-bom-string: 1.0.0 + gsap@3.13.0: {} + hachure-fill@0.5.2: {} handlebars@4.7.8: @@ -13089,6 +13177,8 @@ snapshots: transitivePeerDependencies: - supports-color + meshoptimizer@0.22.0: {} + mhchemparser@4.2.1: {} micromark-core-commonmark@2.0.3: @@ -13436,6 +13526,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + ogl@1.0.11: {} + ohash@2.0.11: {} once@1.4.0: @@ -13709,6 +13801,10 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postprocessing@6.37.8(three@0.180.0): + dependencies: + three: 0.180.0 + prelude-ls@1.2.1: {} prismjs@1.30.0: {} @@ -14608,6 +14704,8 @@ snapshots: dependencies: tslib: 2.8.1 + three@0.180.0: {} + throttleit@2.1.0: {} through@2.3.8: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 63d28572..52b9a79e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -13,7 +13,6 @@ overrides: patchedDependencies: floating-vue: patches/floating-vue.patch - catalogs: dev: '@commitlint/cli': ^20.1.0 @@ -31,6 +30,7 @@ catalogs: '@types/node': ^24.9.1 '@types/picomatch': ^4.0.2 '@types/stylus': ^0.48.43 + '@types/three': ^0.180.0 '@types/webpack-env': ^1.18.8 '@vitest/coverage-istanbul': ^3.2.4 bumpp: ^10.3.1 @@ -62,13 +62,17 @@ catalogs: '@iconify/json': ^2.2.398 artplayer: ^5.3.0 dashjs: ^5.0.3 + gsap: ^3.13.0 hls.js: ^1.6.13 mathjax-full: ^3.2.2 mpegts.js: 1.7.3 + ogl: ^1.0.11 + postprocessing: ^6.37.8 pyodide: ^0.29.0 sass: ^1.93.2 sass-embedded: ^1.93.2 swiper: ^12.0.2 + three: ^0.180.0 prod: '@clack/prompts': ^0.11.0 '@iconify/utils': ^3.0.2 diff --git a/theme/package.json b/theme/package.json index c6e65db6..2f41660e 100644 --- a/theme/package.json +++ b/theme/package.json @@ -67,8 +67,12 @@ "peerDependencies": { "@iconify/json": "catalog:peer", "@vuepress/shiki-twoslash": "catalog:vuepress", + "gsap": "catalog:peer", "mathjax-full": "catalog:peer", + "ogl": "catalog:peer", + "postprocessing": "catalog:peer", "swiper": "catalog:peer", + "three": "catalog:peer", "vuepress": "catalog:vuepress" }, "peerDependenciesMeta": { @@ -78,11 +82,23 @@ "@vuepress/shiki-twoslash": { "optional": true }, + "gsap": { + "optional": true + }, "mathjax-full": { "optional": true }, + "ogl": { + "optional": true + }, + "postprocessing": { + "optional": true + }, "swiper": { "optional": true + }, + "three": { + "optional": true } }, "dependencies": { @@ -128,7 +144,11 @@ }, "devDependencies": { "@iconify/json": "catalog:peer", + "gsap": "catalog:peer", + "ogl": "catalog:peer", + "postprocessing": "catalog:peer", "swiper": "catalog:peer", + "three": "catalog:peer", "vue-router": "catalog:dev" } } diff --git a/theme/src/client/components/Home/VPHome.vue b/theme/src/client/components/Home/VPHome.vue index 69dd992d..d02a4a6f 100644 --- a/theme/src/client/components/Home/VPHome.vue +++ b/theme/src/client/components/Home/VPHome.vue @@ -104,6 +104,7 @@ onUnmounted(() => { diff --git a/theme/src/client/components/Home/VPHomeBox.vue b/theme/src/client/components/Home/VPHomeBox.vue index ce7e994b..4647cb12 100644 --- a/theme/src/client/components/Home/VPHomeBox.vue +++ b/theme/src/client/components/Home/VPHomeBox.vue @@ -17,6 +17,9 @@ const styles = computed(() => { const image = typeof props.backgroundImage === 'string' ? props.backgroundImage : (props.backgroundImage[isDark.value ? 'dark' : 'light'] ?? props.backgroundImage.light) + if (!image) + return null + const link = isLinkHttp(image) ? props.backgroundImage : withBase(image) return { 'background-image': `url(${link})`, diff --git a/theme/src/client/components/Home/VPHomeDocHero.vue b/theme/src/client/components/Home/VPHomeDocHero.vue index 38d6f8e9..20bb92f0 100644 --- a/theme/src/client/components/Home/VPHomeDocHero.vue +++ b/theme/src/client/components/Home/VPHomeDocHero.vue @@ -12,8 +12,8 @@ const actions = computed(() => hero.value.actions ?? [])