首頁 >web前端 >css教學 >內容的互動星空背景

內容的互動星空背景

William Shakespeare
William Shakespeare原創
2025-03-13 11:22:10869瀏覽

內容的互動星空背景

去年,我有機會與肖恩·王(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