這里給大家分享我在網(wǎng)上總結(jié)出來的一些知識,希望對大家有所幫助
一、前言
最近 推特上 一位懂設(shè)計和寫代碼的大神一個兩個瀏覽器之間 星球粒子交互的動畫火了, 讓人看了大呼腦洞大開, 瀏覽器竟然還能這么玩!?。?/p>
準(zhǔn)備自己也搞搞玩一下
二、實現(xiàn)
原作者的粒子動畫非常炫酷, 但是不是我們本文重點, 我們通過一個元素在不同窗口的拖拽實現(xiàn)一個可以變幻的例子來學(xué)習(xí)一下原理, 后續(xù)在實現(xiàn)一個稍微復(fù)雜的多窗口的小游戲。關(guān)于粒子動畫的內(nèi)容,有興趣的小伙伴可以自己實現(xiàn)
其實實現(xiàn)類似的功能需要的難點并不多,不在乎以下幾個步驟
- 1、 屏幕坐標(biāo)和窗口坐標(biāo)轉(zhuǎn)換
- 2、 跨標(biāo)簽通訊
1、 先來看第一個點, 獲取屏幕坐標(biāo)與窗口坐標(biāo)
// 屏幕坐標(biāo)轉(zhuǎn)換為窗口坐標(biāo) const screenToClient = (screenX, screenY) => { const clienX = screenX - window.screenX; const clienY = screenY - window.screenY - barHeight(); return [clienX, clienY]; }; // 窗口坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo) const clientToScreen = (clienX, clienY) => { const screenX = clienX + window.screenX; const screenY = clienY + window.screenY + barHeight(); return [screenX, screenY]; };
我們先簡單實現(xiàn)一個卡片, 通過url上面?zhèn)鬟f顏色值, 設(shè)置定位
在卡片本上設(shè)置上點擊拖動等事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>跨標(biāo)簽通訊</title> </head> <style> .card { width: 300px; height: 300px; background-color: #f00; position: fixed; top: 100px; left: 100px; } </style> <body> 跨標(biāo)簽通訊 <div class="card">card</div> </body> <script> const barHeight = () => window.outerHeight - window.innerHeight; const cardDom = document.querySelector(".card"); cardDom.style.top = 100 + "px"; cardDom.style.left = 100 + "px"; cardDom.style.background = new URLSearchParams(window.location.search).get("color") || "red"; window.onload = function () { cardDom.onmousedown = function (e) { cardDom.style.cursor = "pointer"; let x = e.pageX - cardDom.offsetLeft; let y = e.pageY - cardDom.offsetTop; window.onmousemove = function (e) { cardDom.style.left = e.clientX - x + "px"; cardDom.style.top = e.clientY - y + "px"; // 發(fā)送消息 const clientCoordinateX = e.clientX - x; const clientCoordinateY = e.clientY - y; const ScreenCoordinate = clientToScreen( clientCoordinateX, clientCoordinateY ); sendMessage(ScreenCoordinate); }; window.onmouseup = function () { window.onmousemove = null; window.onmouseup = null; cardDom.style.cursor = "unset"; }; }; }; </script> </html>
2、 跨標(biāo)簽傳輸
單個元素的拖動就實現(xiàn)了, 很簡單, 如何讓其他標(biāo)簽的元素也能同步進(jìn)行, 需要實現(xiàn)跨標(biāo)簽方案了, 可以參考該文章- 跨標(biāo)簽頁通信的8種方式
我們就選擇第一種,使用 BroadCast Channel, 使用也很簡單
// 創(chuàng)建 Broadcast Channel const channel = new BroadcastChannel("myChannel"); // 監(jiān)聽消息 channel.onmessage = (event) => { // 處理接收到的消息 console.log('接收',event) }; // 發(fā)送消息 const sendMessage = (message) => { channel.postMessage(message); };
// 鼠標(biāo)移動發(fā)送消息的時候,窗口坐標(biāo)轉(zhuǎn)化成屏幕坐標(biāo) window.onmousemove = function (e) { cardDom.style.left = e.clientX - x + "px"; cardDom.style.top = e.clientY - y + "px"; const clientCoordinateX = e.clientX - x; const clientCoordinateY = e.clientY - y; const ScreenCoordinate = clientToScreen( clientCoordinateX, clientCoordinateY ); sendMessage(ScreenCoordinate); // 接收消息的時候,屏幕坐標(biāo)轉(zhuǎn)化成窗口坐標(biāo) channel.onmessage = (event) => { // 處理接收到的消息 const [clienX, clienY] = screenToClient(...event.data); // 不同窗口的卡片要在同一個位置, 要放到同一個坐標(biāo)系下面,保持屏幕坐標(biāo)一致 cardDom.style.left = clienX + "px"; cardDom.style.top = clienY + "px"; };
完整代碼,在最下面
三、總結(jié)
本文通過移動一個簡單的圖形, 在不同瀏覽器之間穿梭變換, 初步體驗了多個瀏覽器之間如何進(jìn)行交互, 通過拖拽元素,通過跨標(biāo)簽的通訊, 將當(dāng)前窗口元素的位置進(jìn)行發(fā)送, 另一個窗口進(jìn)行實時接收, 然后通過屏幕坐標(biāo)和窗口坐標(biāo)進(jìn)行轉(zhuǎn)換, 就能實現(xiàn),從一個瀏覽器拖動到另一個瀏覽器時, 變化元素顏色的功能了, 當(dāng)然變化背景色只是舉例子, 你也可以變化撲克牌, 變化照片, 這樣看起來像變魔術(shù)一樣,非常神奇,看似瀏覽器不同標(biāo)簽之間沒有聯(lián)系,當(dāng)以這種方式產(chǎn)生聯(lián)系后, 就會產(chǎn)生很多不可思議的神奇事情。 就像國外大神的多標(biāo)簽頁的兩個星球粒子, 產(chǎn)生吸引 融合的效果。原理其實是一樣的。
后續(xù)前瞻
在通過小demo的學(xué)習(xí),知道多瀏覽器的玩法后, 接下來的我們會實現(xiàn)一個更有意思的小游戲,通過瀏覽器化身一個小木棒, 接小球游戲, 先看一下 gif, 接下來的文章會寫具體實現(xiàn)
?
傳送門 ???多標(biāo)簽通訊--實現(xiàn)用瀏覽器接小球游戲
完整代碼實現(xiàn)如下文章來源:http://www.zghlxwxcb.cn/news/detail-747286.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>跨標(biāo)簽通訊</title> </head> <style> .card { width: 300px; height: 300px; background-color: #f00; position: fixed; top: 100px; left: 100px; } </style> <body> 跨標(biāo)簽通訊 <div class="card">card</div> </body> <script> const barHeight = () => window.outerHeight - window.innerHeight; const cardDom = document.querySelector(".card"); cardDom.style.top = 100 + "px"; cardDom.style.left = 100 + "px"; cardDom.style.background = new URLSearchParams(window.location.search).get("color") || "red"; // 屏幕坐標(biāo)轉(zhuǎn)換為窗口坐標(biāo) const screenToClient = (screenX, screenY) => { const clienX = screenX - window.screenX; const clienY = screenY - window.screenY - barHeight(); return [clienX, clienY]; }; // 窗口坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo) const clientToScreen = (clienX, clienY) => { const screenX = clienX + window.screenX; const screenY = clienY + window.screenY + barHeight(); return [screenX, screenY]; }; // 創(chuàng)建 Broadcast Channel const channel = new BroadcastChannel("myChannel"); // 監(jiān)聽消息 channel.onmessage = (event) => { // 處理接收到的消息 const [clienX, clienY] = screenToClient(...event.data); // 不同窗口的卡片要在同一個位置, 要放到同一個坐標(biāo)系下面,保持屏幕坐標(biāo)一致 cardDom.style.left = clienX + "px"; cardDom.style.top = clienY + "px"; }; // 發(fā)送消息 const sendMessage = (message) => { channel.postMessage(message); }; window.onload = function () { cardDom.onmousedown = function (e) { cardDom.style.cursor = "pointer"; let x = e.pageX - cardDom.offsetLeft; let y = e.pageY - cardDom.offsetTop; window.onmousemove = function (e) { cardDom.style.left = e.clientX - x + "px"; cardDom.style.top = e.clientY - y + "px"; // 發(fā)送消息 const clientCoordinateX = e.clientX - x; const clientCoordinateY = e.clientY - y; const ScreenCoordinate = clientToScreen( clientCoordinateX, clientCoordinateY ); sendMessage(ScreenCoordinate); }; window.onmouseup = function () { window.onmousemove = null; window.onmouseup = null; cardDom.style.cursor = "unset"; }; }; }; </script> </html>
本文轉(zhuǎn)載于:
https://juejin.cn/post/7304598711992598566
如果對您有所幫助,歡迎您點個關(guān)注,我會定時更新技術(shù)文檔,大家一起討論學(xué)習(xí),一起進(jìn)步。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-747286.html
到了這里,關(guān)于記錄--瀏覽器跨標(biāo)簽星球火了,簡單探究一下實現(xiàn)原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!