「スクリーン上でブラウザのウィンドウを動かしたら描画に影響」「2つのブラウザのウィンドウの一方を動かすと他方に影響」という方向の実装作品の技術メモ【JavaScript】

> ※ 後付けで [JavaScript Advent Calendar 2023](https://qiita.com/advent-calendar/2023/javascript) の 7日目の記事として登録してみました

自分が観測していた中では、以下のポストが発端になっていると思われる話です。
この作品にインスパイアされた作品を作られた方も見かけていて、その作品や技術面のメモを残したく、記事を書きました。

https://twitter.com/_nonfigurativ_/status/1727322594570027343

## 技術的な部分について
「素敵な作品だなー！」と思って、も「し実装するとしたら必要そうなものは何か」と考えたら、「スクリーン内のブラウザのウィンドウの位置を取得する仕組み」と、「異なるページ間で情報をやりとりする仕組みがあれば良さそう」と思いました。

### ページ間の通信の仕組み
上記の 2つの技術のうち、「異なるページ間で情報をやりとりする仕組み」については、別端末間で IoT の仕組み（技術的には MQTT）を使って、こんな試作などをやったことがありました。

https://twitter.com/youtoy/status/1428759249291677696

また、同じ端末内で同じブラウザのタブ間などであれば、自分が以下の記事で書いていた仕組みを使っても良さそうと思いました。

●ブラウザのタブ間でのリアルタイム通信を行う 4つの方法【概要編】 - Qiita
 https://qiita.com/youtoy/items/b202209d0eb36bad830f

### スクリーン内のブラウザのウィンドウの位置を取得する仕組み
冒頭の作品や、それにインスパイアされた作品を見てた中、「スクリーン内のブラウザのウィンドウの位置を取得する仕組み」を知りたいなと思ってたところ、以下のポストで「screenLeft というプロパティがある」というのを知りました。

https://twitter.com/steveruizok/status/1727438418580525487

MDN のページを見ると「window.screenTop」というものもあるようでした。

●Window: screenLeft property - Web APIs | MDN
　https://developer.mozilla.org/en-US/docs/Web/API/Window/screenLeft

#### Steve Ruiz さんのポストにたどり着いた流れ
上記の「screenLeft property」を知った流れは以下で、冒頭に掲載した作品のインスパイア作品が複数見られたのもあり良かったです。

↓このポストを見かけて、冒頭の作品と同じ技術を使ってそうだな、と思い

https://twitter.com/ampersand_xyz/status/1728097804961345663

↓上記のポストの引用から、以下にたどり着き

https://twitter.com/steveruizok/status/1727436505440981099

Steve Ruiz さんのコメントを見かけたという流れでした。

#### Chigozie Nri さんが作品を作ったきっかけ
上の Chigozie Nri さんの作品は、冒頭で掲載した作品にインスパイアされて作ったとのことでした。

https://twitter.com/chigozienri/status/1727733082826891650

 #### 上記の仕組みを p5.js で軽く試してみる
上記の情報を得られたので、自分がよく使う p5.js を使って、簡単な動作確認用の試作をやってみました（※ 実装の詳細などは、別途、記事化できれば！）。

↓こちらは単一のウィンドウで、ウィンドウの動きがボールの動きに影響を与える、という感じにしてみたものです。

https://twitter.com/youtoy/status/1728214364111691904

余談ですが、何らか全体の動きに合わせて、キャンバス内の描画が影響を受けて動くというのは、例えば以下など過去に作ったもので、仕組みはいろいろ試していました（そのため、今回は「スクリーン内のブラウザのウィンドウの位置を取得する仕組み」が分かった時点で、サクッと上記を試作できました）。

https://twitter.com/youtoy/status/1701077601274691766

また ↓こちらは、片方のウィンドウの左上の位置座標を別ウィンドウで受け取る形で、片方のウィンドウのスクリーン上の位置がもう一方に影響を与える仕組みを試したものです。
以下を実装した時は、自分が過去に使った MQTT でページ間をつないでますが、[上で自分が過去に書いた記事](https://qiita.com/youtoy/items/b202209d0eb36bad830f)として掲載したもので、いくつか出てきていた仕組みの 1つを使ったほうが準備がシンプルになりそうでした。

https://twitter.com/youtoy/status/1728109865485365518

## その後、元の実装・インスパイアされた作品の実装の情報をゲット
その後、冒頭の方の作品のソースや、それにインスパイアされた方の作品のソースが、GitHub や他で公開されてるという情報をもらいました。それらもメモしておきます。

### 冒頭の方の作品の実装
リポジトリは以下です。

●bgstaal/multipleWindow3dScene: A quick example of how one can "synchronize" a 3d scene across multiple windows using three.js and localStorage
　https://github.com/bgstaal/multipleWindow3dScene

- 実装方法など
   - 描画： three.js
   - タブ間通信： localStorage経由
   - ウィンドウ位置の取得： Window.screenX（ screenLeft のエイリアスのようです ）・Window.screenY

![Window.screenX](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a1c91d28-0ea0-8162-03a2-30adf4ad69be.png)

#### Chigozie Nri さんの作品の実装
Chigozie Nri さんも、GitHub でソースを公開されていました。

https://twitter.com/chigozienri/status/1727838196925407379

●chigozienri/browser-bounce: Experiment with multiple browser windows interacting
　https://github.com/chigozienri/browser-bounce/

 - 実装方法など
   - 描画： Canvas API
   - タブ間通信： Socket.IO
   - ウィンドウ位置の取得： window.screenLeft・window.screenTop

### その他
こんなポストも見かけました。

https://twitter.com/addyosmani/status/1727412022747554073

MDN で見てみると、こんな記載がされているものでした。

●Window: getScreenDetails() method - Web APIs | MDN
　https://developer.mozilla.org/en-US/docs/Web/API/Window/getScreenDetails

 ![getScreenDetails()](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e8ef3e86-a1aa-f820-b715-d26262b6f9d3.png)

「利用可能なディスプレイそれぞれについて...」という記載があり、これも面白そうなので、詳細を別途確認してみたいと思います。
![利用可能なディスプレイそれぞれについて...](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/fa2bac3e-0406-8915-bdcd-0e3864be54e9.png)

[「Chrome for Developers の Managing several displays with the Window Management API」というページ](　https://developer.chrome.com/articles/window-management/#the-getscreendetails-method)も見てみるのが良さそうです。

https://twitter.com/addyosmani/status/1727555984691003687

### 上で出てきたもののブラウザ対応状況
上で出てきたもののうち「screenLeft」と「getScreenDetails()」のブラウザ対応の状況（※ MDN の情報）をメモしておきます。

![screenLeft](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/19a4e182-92d4-625f-330f-304789cd4358.png)

![getScreenDetails()](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a807516f-b958-827c-e17d-1005c98fbde3.png)