首页 >web前端 >css教程 >内容的互动星空背景

内容的互动星空背景

William Shakespeare
William Shakespeare原创
2025-03-13 11:22:10851浏览

内容的互动星空背景

去年,我有机会与肖恩·王(Shawn Wang)(Swyx)合作就暂时的项目。目标是通过一些创意元素来增强他们的网站。这是一个令人着迷的挑战,因为我更像是一个开发人员,而不是设计师,但我却抓住了扩大设计技能的机会。

我的贡献之一是互动的星空背景。您可以在这里看到它:

使用Perspective和CSS自定义属性的BlockQuote概念。享受@temporalio的创意自由。添加一点点奇思妙想! ⚒️@reaectjs && @tailwindcss(站点是nextjs)?通过@codepen pic.twitter.com/s9xp2trrox链接到codepen

- jhey ??✨(@jh3yy)2021年7月2日

该设计的强度在于它作为可重复使用的React组件的实现,提供了高配置性。需要不同的形状而不是星星?想要精确控制粒子放置吗?您可以完全控制。

让我们构建此组件!我们将使用React,Greensock和HTML<canvas></canvas>元素。 React是可选的,但使用它为将来的项目创建了可重复使用的组件。

构建基本应用

从'https://cdn.skypack.dev/reeact'导入反应';
从'https://cdn.skypack.dev/reaeact-dom'导入reactdom';
从'https://cdn.skypack.dev/gsap'导入GSAP';

const root_node = document.queryselector('#app');

const starscape =()=><h1>很酷的东西!</h1> ;

const app =()=><starscape></starscape> ;

Reactdom.render(<app></app> ,root_node);

首先,我们渲染一个<canvas></canvas>元素并获取引用以在React的useEffect挂钩中使用。如果不使用React,请将参考直接存储在变量中。

 const starscape =()=> {
  const canvasref = react.useref(null);
  返回<canvas ref="{canvasRef}"></canvas>;
};

我们会样式<canvas></canvas>填充视口并坐在内容的背后:

帆布 {
  位置:固定;
  插图:0;
  背景:#262626;
  z index:-1;
  身高:100VH;
  宽度:100VW;
}

添加星星

我们将通过使用具有不同不透明度和尺寸的圆圈来简化星星的渲染。在一个圆上画一个圆<canvas></canvas>涉及获取上下文并使用arc功能。让我们使用useEffect钩在中心渲染一个圆圈(我们的星星):

 const starscape =()=> {
  const canvasref = react.useref(null);
  const contextref = react.useref(null);
  react.useeffect(()=> {
    canvasref.current.width = window.innerwidth;
    canvasref.current.height = window.innerheight;
    contextref.current = canvasref.current.getContext('2d');
    contextref.current.fillstyle ='Yellow';
    contextref.current.beginath();
    contextref.current.arc(
      window.innerwidth / 2,// x
      window.innerheight / 2,// y
      100,//半径
      0,//开始角度(弧度)
      Math.pi * 2 //末端角度(弧度)
    );
    contextref.current.fill();
  },[]);
  返回<canvas ref="{canvasRef}"></canvas>;
};

这会产生一个黄色的圆圈。其余代码将在此useEffect之内。这就是为什么反应部分是可选的。您可以将此代码适应其他框架。

我们需要生成并渲染多个星星。让我们创建一个LOAD功能来处理恒星生成和画布设置,包括帆布尺寸:

 const load =()=> {
  const vmin = math.min(window.innerheight,window.innerwidth);
  const star_count = math.floor(vmin * densepratio);
  canvasref.current.width = window.innerwidth;
  canvasref.current.height = window.innerheight;
  starsref.current = new Array(star_count).fill()。map(()=>({{)
    x:gsap.utils.random(0,window.innerwidth,1),
    y:gsap.utils.random(0,window.innerheight,1),
    尺寸:gsap.utils.random(1,Sizelimit,1),
    比例:1,
    alpha:gsap.utils.random(0.1,defaultalpha,0.1),
  }));
};

每个恒星都是具有定义其特征(x,y位置,大小,比例,alpha)的属性的对象。 sizeLimitdefaultAlphadensityRatio是传递给具有默认值的Starscape组件。

样本星对象:

 {
  “ x”:1252,
  “ Y”:29,
  “大小”:4,
  “比例”:1,
  “ alpha”:0.5
}

为了渲染这些恒星,我们创建了一个RENDER函数,该函数可在stars阵列上迭代,并使用arc函数呈现每个恒星:

 const Render =()=> {
  contextref.current.ClearRect(
    0,
    0,
    canvasref.current.width,
    canvasref.current.height
  );
  StarsRef.Current.Foreach((Star)=> {
    contextref.current.fillstyle =`hsla(0,100%,100%,$ {star.alpha})`;
    contextref.current.beginath();
    contextref.current.arc(star.x,star.y,star.size / 2,0,math.pi * 2);
    contextref.current.fill();
  });
};

clearRect功能在渲染之前清除了画布,这对于动画至关重要。

完整的Starscape组件(尚无交互性)如下:

完整的Starscape组件(没有互动性)

 const starscape =({denseratio = 0.5,sizelimit = 5,defaultalpha = 0.5})=> {
  const canvasref = react.useref(null);
  const contextref = react.useref(null);
  const starsRef = react.useref(null);
  react.useeffect(()=> {
    contextref.current = canvasref.current.getContext('2d');
    const load =()=> {
      const vmin = math.min(window.innerheight,window.innerwidth);
      const star_count = math.floor(vmin * densepratio);
      canvasref.current.width = window.innerwidth;
      canvasref.current.height = window.innerheight;
      starsref.current = new Array(star_count).fill()。map(()=>({{)
        x:gsap.utils.random(0,window.innerwidth,1),
        y:gsap.utils.random(0,window.innerheight,1),
        尺寸:gsap.utils.random(1,Sizelimit,1),
        比例:1,
        alpha:gsap.utils.random(0.1,defaultalpha,0.1),
      }));
    };
    const Render =()=> {
      contextref.current.ClearRect(0,0,canvasref.current.width,canvasref.current.height);
      StarsRef.Current.Foreach((Star)=> {
        contextref.current.fillstyle =`hsla(0,100%,100%,$ {star.alpha})`;
        contextref.current.beginath();
        contextref.current.arc(star.x,star.y,star.size / 2,0,math.pi * 2);
        contextref.current.fill();
      });
    };
    const run =()=> {
      加载();
      使成为();
    };
    跑步();
    window.addeventListener('resize',run);
    返回()=> {
      window.removeEventListener('resize',run);
    };
  },[]);
  返回<canvas ref="{canvasRef}"></canvas>;
};

在演示中尝试道具以查看其效果。要处理视口度调整大小,我们调用LOAD并在调整大小上RENDER (以优化的措施进行了辩论,此处省略了)。

添加互动

现在,让我们进行背景互动。当指针移动时,光标附近的恒星会变亮并扩大规模。

我们将添加一个UPDATE功能来计算指针与每个星星之间的距离,然后使用Greensock的mapRange实用程序对恒星的比例和Alpha进行补充。我们还将添加scaleLimitproximityRatio props来控制缩放行为。

 const update =({x,y})=> {
  StarsRef.Current.Foreach((Star)=> {
    const距离= MATH.SQRT(MATH.POW(Star.X -X,2)Math.pow(Star.Y -Y,2));
    gsap.to(星,{
      比例:scalemapperref.current(Math.min(距离,vminref.current * proximityratio)),),),),)
      alpha:alphamapperref.current(Math.min(距离,vminref.current * proximityratio)),),),),)
    });
  });
};

为了渲染更新,我们使用gsap.tickerrequestAnimationFrame的一个很好的替代方法),将RENDER添加到股票中并在清理中删除。我们将每秒(FPS)的帧设置为24。 RENDER函数现在使用star.scale值绘制弧线时。

加载();
gsap.ticker.add(渲染);
gsap.ticker.fps(24);
window.addeventListener('ressize',load);
document.AddeventListener('PointerMove',Update);
返回()=> {
  window.removeEventListener('resize',load);
  document.removeEventListener('PointerMove',Update);
  gsap.ticker.remove(渲染);
};

现在,当您移动鼠标时,星星会做出反应!

为了处理鼠标离开画布的情况,我们添加了一个pointerleave事件侦听器,该侦听器将星星重新回到其原始状态:

 const exit =()=> {
  GSAP.TO(StarsRef.Current,{scale:1,alpha:defaultalpha});
};

// ...活动听众...
document.AddeventListener(“ Pointerleave”,退出);
返回()=> {
  // ... 清理 ...
  Document.RemoveEventListener(“ Pointerleave”,退出);
  gsap.ticker.remove(渲染);
};

奖金:Konami代码复活节彩蛋

让我们添加一个Konami代码复活节彩蛋。如果输入代码,我们将收听键盘事件并触发动画。

 const konami_code ='arrowup,arrowup,arrowdown,arrowdown,arrowleft,arrowLight,arrowleft,arrowleft,arrowright,keya,keya';
const coderef = react.useref([]);
react.useeffect(()=> {
  const handlecode =(e)=> {
    coderef.current = [... coderef.current,e.code] .slice(coderef.current.length> 9?coderef.current.length-length -9:0);
    if(coderef.current.join(',').tolowercase()=== konami_code.tolowercase()){
      //触发复活节彩蛋动画
    }
  };
  window.addeventListener('keyup',handlecode);
  返回()=> {
    window.removeEventListener('keyup',handlecode);
  };
},[]);

带有Konami Code复活节彩蛋的完整的,交互式的Starscape组件非常冗长,因此在这里省略了。但是,上面概述的原则演示了如何使用React,Greensock和HTML创建功能齐全且可定制的交互式星空背景<canvas></canvas>。复活节彩蛋动画将涉及创建一个gsap.timeline

此示例演示了创建自己的自定义背景所需的技术。请记住要考虑背景如何与您网站的内容相互作用。尝试不同的形状,颜色和动画,以创建独特而引人入胜的视觉效果。

以上是内容的互动星空背景的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn