Electronで、VJをしよう!③Cross Originの制限のある画像をテクスチャにする

  • 10
    Like
  • 0
    Comment
More than 1 year has passed since last update.

ひきつづき、Electronでニッチな使い方を・・・。
今回は、three.jsを使って3D表現をしようと思います。
Electronならではのブラウザ表現を活かそうとすると、やはりウェブサイトの表示はしたいですね。ところが、一般的なブラウザだと、画像の取得でCross-Originの問題が発生します。

three.js編

three.jsでは、ImageLoader#crossOriginを設定することで、ドメインの異なるサイトの画像をテクスチャにすることができます。

main.js
var sphere = new THREE.Mesh(new THREE.SphereGeometry(100, 32, 32), new THREE.MeshPhongMaterial({color: 0xffffff}));
scene.add(sphere);

var loader = new THREE.TextureLoader();
loader.crossOrigin = '*'; // ココが重要
loader.load('http://example.com/hoge.png', (texture) => {
    sphere.material.map = texture;
    sphere.material.needsUpdate = true;
});

1d254443-b001-080e-7111-916e86a8e059.png

ただし、これができるのは、レスポンスヘッダーで、access-control-allow-originを設定した画像のみとなります。

origin.png

設定されていない場合は、以下のようなエラーがコンソールに吐かれます。

スクリーンショット 2016-03-09 16.25.23.png

Electron + three.js編

BrowserWindow内のjsで以下

main.js
var sphere = new THREE.Mesh(new THREE.SphereGeometry(100, 32, 32), new THREE.MeshPhongMaterial({color: 0xffffff}));
scene.add(sphere);

var loader = new THREE.TextureLoader();
loader.load('http://example.com/hoge.png', (texture) => {
    sphere.material.map = texture;
    sphere.material.needsUpdate = true;
});

なんと、crossOriginを設定しなくても、表示されます!
弊社ロゴもこのとおり真ん丸に・・・。
01f214f5-53f7-56cf-680e-33ba63411539.png

ちゃんちゃん。

発展系

というだけでは脳がないので、ウェブサイトを表示した上に、各画像を球状にして表示させて、グリグリさせてみます。

画像の取得

mainWindow.js
var loader = new THREE.TextureLoader();
var wv = document.getElementById('wv');
wv.addEventListener('did-get-response-details', (e) => {
    // 画像かどうかの判定
    var isImage = false;
    e.headers["content-type"].forEach((type) => {
        if (type.search("image") === 0) {
            isImage = true;
        }
    });
    if (isImage) {
        // 球の作成
        let geometry = new THREE.SphereGeometry(20, 32, 32);
        let material = new THREE.MeshPhongMaterial({
            color: 0xffffff
        });
        let sphere = new THREE.Mesh(geometry, material);
        loader.load(e.newURL, (texture) => {
                sphere.material.map = texture;
                sphere.material.needsUpdate = true;
        });
        scene.add(sphere);
    }
});

Webview表示の場合、did-get-reseponse-detailsイベントで読み込まれたリソースの詳細が取得できます。
そこで、レスポンスヘッダー内を見て、画像かどうかを判断し、画像の場合は、球体のテクスチャに貼り付けて、表示するということをやっています。
URLを元にテクスチャを貼っているので、2回取りに行っていますが、webview側でbase64変換して、ipcRenderer#sendToHostで送信し、ipc-messageイベントで取得する方法もあります。

ソース

もうすこしアレンジしたソースを以下に置いておきましたので、参考にどうぞ。

https://github.com/aquaring/BrowsingApp

弊社のサイトは、以下のとおり。
映像が流れていると、いいかんじですね。
スクリーンショット 2016-03-10 11.09.29.png

追記

既存のサイトをもとにアレンジできますし、
大きな画面に投影したりすると、もっとおもしろい表現ができそうですね。