去年,我有機會與肖恩·王(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)的屬性的對象。 sizeLimit
, defaultAlpha
和densityRatio
是傳遞給具有默認值的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進行補充。我們還將添加scaleLimit
和proximityRatio
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.ticker
( requestAnimationFrame
的一個很好的替代方法),將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代碼復活節彩蛋。如果輸入代碼,我們將收聽鍵盤事件並觸發動畫。
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中文網其他相關文章!