新聞中心
大家好,我卡頌。

創(chuàng)新互聯(lián)專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、雜多網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、購物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為雜多等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
最近被一段酷炫的量子糾纏效果刷屏了:
原作者是@_nonfigurativ_,一位藝術(shù)家、程序員。
今天簡單講講他的核心原理。
基礎(chǔ)概念
首先我們需要知道兩個概念:
- 屏幕坐標(biāo)系,屏幕左上角就是「屏幕坐標(biāo)系」的圓點。
- 窗口坐標(biāo)系,頁面窗口左上角就是「窗口坐標(biāo)系」的圓點。
如果只用一臺電腦,不外接屏幕的話,我們會有:
- 一個屏幕坐標(biāo)系
- 打開幾個頁面,每個頁面有各自的窗口坐標(biāo)系
如果外接了屏幕(或外接pad),那么就存在多個屏幕坐標(biāo)系,這種情況的計算需要用到「管理屏幕設(shè)備的API」 —— window.getScreenDetails[1],在本文的討論中不涉及這種情況。
當(dāng)我們打開一個新頁面窗口,窗口的左上角就是窗口坐標(biāo)系的圓點,如果要在頁面正中間畫個圓,那圓心的窗口坐標(biāo)系坐標(biāo)應(yīng)該是(window.innerWidth / 2, window.innerHeight / 2)。
對于一個打開的窗口:
- 他的左上角相對于屏幕頂部的距離為window.screenTop。
- 他的左上角相對于屏幕左邊的距離為window.screenLeft。
所以,我們可以輕松得出圓的圓心在「屏幕坐標(biāo)系」中的坐標(biāo):
位置檢測
在效果中,當(dāng)打開兩個頁面,他們能感知到對方的位置并作出反應(yīng),這是如何實現(xiàn)的呢?
當(dāng)前,我們已經(jīng)知道圓心在「屏幕坐標(biāo)系」中的坐標(biāo)。如果打開多個頁面,就會獲得多個「圓心的屏幕坐標(biāo)系坐標(biāo)」。
現(xiàn)在需要做的,就是讓這些頁面互相知道對方的坐標(biāo),這樣就能向?qū)?yīng)的方向做出連接的特效。
同源網(wǎng)站跨頁面通信的方式有很多,比如:
- Window.postMessage
- LocalStorage、SessionStorage
- SharedWorker
- BroadcastChannel
甚至Cookie也能用于跨頁面通信(可以在同源的所有頁面之間共享)。
在這里作者使用的是LocalStorage:
只需要為每個頁面生成一個唯一ID:
const pageId = Math.random().toString(36).substring(2); // 生成一個隨機的頁面ID每當(dāng)將圓心最新坐標(biāo)存儲進(jìn)LocalStorage時:
localStorage.setItem(
pageId,
JSON.stringify({
x: window.screenX,
y: window.screenY,
width: window.innerWidth,
height: window.innerHeight,
})
);在另一個頁面通過監(jiān)聽storage事件就能獲取「對方圓心的屏幕坐標(biāo)系坐標(biāo)」:
window.addEventListener("storage", (event) => {
if (event.key !== pageId) {
// 來自另一個頁面
const { x, y } = JSON.parse(event.newValue);
// ...
}
});再將對方「圓心的屏幕坐標(biāo)系坐標(biāo)」轉(zhuǎn)換為自身的「窗口坐標(biāo)系坐標(biāo)」,并在該坐標(biāo)繪制一個圓,就能達(dá)到類似「窗口疊加后,下面窗口的畫面出現(xiàn)在上面窗口內(nèi)」的效果。
通俗的講,所有頁面都會繪制其他頁面的圓,只是有些圓在頁面窗口外,看不見罷了。
考慮到頁面性能,「檢測圓心的屏幕坐標(biāo)系坐標(biāo)」、「渲染圓」相關(guān)操作可以放到requestAnimationFrame回調(diào)中執(zhí)行。
后記
上述只是該效果的核心原理。要完全復(fù)刻效果,還得考慮:
- 渲染大量粒子(我們示例中用「圓」代替),且多窗口通信時的性能問題。
- 窗口移動時的阻尼效果。
- 當(dāng)前的實現(xiàn)是在同一個屏幕坐標(biāo)系中,如果要跨屏幕實現(xiàn),需要使用window.getScreenDetails。
不得不感嘆跨界(作者是藝術(shù)家 + 程序員)迸發(fā)的想象力真的不一般。
參考資料
[1]window.getScreenDetails:https://developer.chrome.com/zh/articles/multi-screen-window-placement/。
網(wǎng)站標(biāo)題:談?wù)勍饩W(wǎng)刷屏的量子糾纏效果
瀏覽路徑:http://www.dlmjj.cn/article/ccojcog.html


咨詢
建站咨詢
