写点什么

如何实现一个充满科技感的官网(二)

作者:极限实验室
  • 2025-01-02
    北京
  • 本文字数:3744 字

    阅读完需:约 12 分钟

如何实现一个充满科技感的官网(二)

背景

在上一篇文章 《如何实现一个充满科技感的官网(一)》 中,我们初步了解了该官网的整体设计,并与大家探讨了它的视觉呈现和用户体验。


我们前期的内部设计偏向简洁,所以开始思考如何提升网站的整体设计感。这些尝试便由此展开。


网站地址:https://infinilabs.com/


如果你对动态背景的实现感兴趣,这篇文章将带你深入探索,揭秘如何从零打造一个兼具美感与功能性的企业官网!

技术选型

  • 前端框架:Next.js

  • UI 框架:基于 Tailwind CSS

  • CSS 样式:Tailwind CSS(快速开发、内置响应式、丰富工具类)

为什么选择 Next.js?

  1. 兼容团队技术栈:基于 React,便于团队协作。

  2. SEO 和性能优化:支持服务端渲染(SSR)和静态站点生成(SSG)。

  3. 路由强大:支持动态路由和文件路由,灵活易用。

  4. 内置优化:图片优化、国际化、多种性能提升。

  5. 动态内容支持:博客、新闻等动态场景轻松应对。

  6. 加载体验佳:用户体验和页面加载速度表现优秀。

动态的背景方案

动态背景可以显著提升视觉吸引力,以下是常用实现方案:


  1. CSS 动画背景:使用纯 CSS 实现动态背景,通过 @keyframes 配合渐变色、位置移动等属性。

  2. 动态 Canvas 背景:使用 <canvas> 元素,结合 JavaScript 绘制动态效果,比如粒子系统、波浪效果等。

  3. 动态视频背景:使用 <video> 元素播放循环视频作为背景。

  4. WebGL 动态背景:使用 WebGL 库(如 Three.js)渲染 3D 动态背景。

  5. 动态粒子背景:使用现有的粒子背景库快速实现动态粒子效果。(particles.js 或 tsparticles)

  6. ......

如何选择?

  1. 简单需求: 纯 CSS 动画、动态视频背景。

  2. 复杂交互:Canvas 动画、WebGL 动画(Three.js)。

  3. 快速实现:使用粒子背景库(particles.js / tsparticles)。

动态背景代码实现

以下示例通过 WebGL 创建了一个动态背景组件,支持 React 和 Tailwind CSS。


  1. 创建 GlobalBackground.tsx 文件:


"use client";
import dynamic from "next/dynamic";import { Suspense, useEffect, useState } from "react";import { Layout } from "./Layout";
const ShaderGradient = dynamic( () => import("shadergradient").then((mod) => mod.ShaderGradient), { ssr: false });const View = dynamic(() => import("./View").then((mod) => mod.View), { ssr: false, loading: () => ( <div className="w-full h-full bg-cover bg-center" style={{ backgroundImage: "url(/images/loading-bg.png)" }} ></div> ),});
export default function GlobalBackground() { const defaultProps: any = { control: "props", animate: "on", brightness: 1.2, cDistance: 3.6, cameraZoom: 1, color1: "#0600B8", color2: "#9000E3", color3: "#0B004F", // embedMode: "off", envPreset: "city", // gizmoHelper: "hide", grain: "off", lightType: "3d", reflection: 0.1, shader: "defaults", type: "waterPlane", uSpeed: 0.2, uTime: 0, wireframe: false, zoomOut: false, toggleAxis: false, };
const [suspenseWebgl, setSuspenseWebgl] = useState(false); useEffect(() => { const canvas = document.createElement("canvas"); const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); if (gl) { // 浏览器支持 WebGL console.log("The browser does support WebGL"); setSuspenseWebgl(true); } else { console.log("The browser does not support WebGL"); // 浏览器不支持 WebGL } }, []); return ( <> {suspenseWebgl ? ( <Layout> <View className="w-full h-full"> <Suspense fallback={null}> <ShaderGradient {...defaultProps} /> </Suspense> </View> </Layout> ) : null} </> );}
复制代码


  1. 创建 Layout.tsx 文件:


"use client";
import { useRef } from "react";import dynamic from "next/dynamic";const Scene = dynamic(() => import("./Scene"), { ssr: false });
const Layout = ({ children }: any) => { const ref = useRef<any>();
return ( <div ref={ref} className="fade-in" style={{ position: "fixed", top: 0, left: 0, width: "100%", height: "100%", zIndex: -1, overflow: "auto", touchAction: "auto", }} > {children} <Scene style={{ position: "fixed", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none", }} eventSource={ref} eventPrefix="client" pixelDensity={1} pointerEvents="none" /> </div> );};
export { Layout };
复制代码


  1. 创建 Scene.tsx 文件:


"use client";
import { ShaderGradientCanvas } from "shadergradient";import { Canvas } from "@react-three/fiber";import { Preload } from "@react-three/drei";import tunnel from "tunnel-rat";
const r3f = tunnel();
export default function Scene({ ...props }) { // Everything defined in here will persist between route changes, only children are swapped
return ( <ShaderGradientCanvas {...props}> {/* @ts-ignore */} <r3f.Out /> <Preload all /> </ShaderGradientCanvas> );}
复制代码


  1. 创建 View.tsx 文件:


"use client";
import { forwardRef, Suspense, useImperativeHandle, useRef } from "react";import { OrbitControls, PerspectiveCamera, View as ViewImpl,} from "@react-three/drei";import tunnel from "tunnel-rat";
const r3f = tunnel();
const Three = ({ children }: any) => { return <r3f.In>{children}</r3f.In>;};
export const Common = ({ color }: any) => ( <Suspense fallback={null}> {color && <color attach="background" args={[color]} />} <ambientLight intensity={0.5} /> <pointLight position={[20, 30, 10]} intensity={1} /> <pointLight position={[-10, -10, -10]} color="blue" /> <PerspectiveCamera makeDefault fov={40} position={[0, 0, 6]} /> </Suspense>);
const View = forwardRef(({ children, orbit, ...props }: any, ref) => { const localRef = useRef<any>(null); useImperativeHandle(ref, () => localRef.current);
return ( <> <div ref={localRef} {...props} /> <Three> <ViewImpl track={localRef}> {children} {orbit && <OrbitControls />} </ViewImpl> </Three> </> );});View.displayName = "View";
export { View };
复制代码


  1. 直接在 app/page.tsx 使用背景组件:


import GlobalBackground from "@/components/GlobalBackground";
export default function Home() { return ( <> <GlobalBackground></GlobalBackground> <div className="min-h-screen bg-cover bg-center" style={{ backgroundImage: "url(/svg/bg_n.svg)" }} > .... </div> </> );}
复制代码


  1. 当然,代码弄好了,要想让代码运行起来,还需要安装一下依赖:


pnpm add @react-three/drei @react-three/fiber shadergradient tunnel-rat
复制代码


通过这些步骤,你将能够为网站实现高性能、响应式的动态背景效果。根据具体需求调整背景类型和交互复杂度,让你的官网更具吸引力!

效果

具体效果,可以直接在网站上浏览,效果更真实。网站地址:https://infinilabs.com/

分享

如果你也想配置自己的动态效果图,可以前往 shadergradient.co 网站进行自定义设置。完成后,将生成的配置参数复制到 GlobalBackground.tsx 文件的 defaultProps 中,即可实现属于你自己的动态背景效果。

参考

福利

INFINI Labs 一直致力于为开发者和企业提供优质的开源工具,提升整个技术生态的活力。除了维护国内最流行的分词器 analysis-ikanalysis-pinyin,也在不断推动更多高质量开源产品的诞生。


最近新开源的产品和工具:



以上开源软件都可以在 Github 上面找到: https://github.com/infinilabs


希望大家都能给个免费的 Star🌟 支持一下!!!


作者:Rain9,极限科技(INFINI Labs) 高级前端开发工程师。

发布于: 9 小时前阅读数: 2
用户头像

简单、易用、极致、创新 2021-11-22 加入

极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。

评论

发布
暂无评论
如何实现一个充满科技感的官网(二)_React_极限实验室_InfoQ写作社区