unityController - ユーザーインタラクション¶
onResize メソッドは、 index.html
の Web ページのユーザー操作に使用されるすべてのメソッドが含まれています。すべてのキー入力機能とクリック機能は、このセクションにあります。
In This Section
onKeyDown¶
onKeyDown(event: KeyboardEvent)
onKeyDown メソッドが、ウィンドウが選択されたときにどのキーが押されたかに応じて、指定の機能をトリガします。
- changeOffset
- 値を変更して、ビデオ遅延オフセットを変更する。
- toggleGenvidOverlay
- Genvid オーバーレイの表示、非表示を切り替える。
- client.videoPlayer.isPaused
- ビデオが一時停止しているかどうかを示すブール値を返す。
- client.videoPlayer.play
- ビデオを再生する。
- client.videoPlayer.pause
- ビデオを一時停止する。
- client.videoPlayer.getMuted
- ビデオサウンドがミュートされているかどうかを示すブール値を返す。
- client.videoPlayer.setMuted
- 引数に応じて、音声のミュートの有効、無効を切り替える。
- client.videoPlayer.setVolume
- 送信された引数にビデオボリュームを設定する。
- client.videoPlayer.getVolume
- 現在のビデオボリュームを取得する。
- onHelpActivation
- ヘルプオーバーレイの表示、非表示を切り替える。
onKeyDown(event: KeyboardEvent) {
// Seems to be the most cross-platform way to determine keys:
// Ref: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
let code = event.code || this.getKeyCode(event);
if (code === "Equal" || code === "NumpadAdd") {
this.changeOffset(+1, event);
} else if (code === "Minus" || code === "NumpadSubtract") {
this.changeOffset(-1, event);
} else if (code === "NumpadMultiply") {
this.changeOffset(0, event);
} else if (code === "KeyG") {
this.toggleGenvidOverlay();
}
else if (code === "Space") {
if (this.client.videoPlayer.isPaused()) {
this.client.videoPlayer.play();
} else {
this.client.videoPlayer.pause();
}
event.preventDefault();
}
else if (code === "KeyM") {
this.onMute();
}
else if (code === "KeyZ") {
this.promptOverlay = <HTMLDivElement>document.querySelector("#prompt_overlay");
this.client.videoPlayer.setVolume(this.client.videoPlayer.getVolume() - 20);
this.promptOverlay.style.visibility = "visible";
this.timeVisiblePrompt = 0;
this.volumeChange = 2;
}
else if (code === "KeyX") {
this.promptOverlay = <HTMLDivElement>document.querySelector("#prompt_overlay");
this.client.videoPlayer.setVolume(this.client.videoPlayer.getVolume() + 20);
this.promptOverlay.style.visibility = "visible";
this.timeVisiblePrompt = 0;
this.volumeChange = 1;
}
else if (code === "KeyH") {
this.onHelpActivation();
}
}
getKeyCode¶
getKeyCode(event: KeyboardEvent)
getKeyCode メソッドは、さまざまなブラウザで適切な keyCode を取得します。
// Compatibility code for browsers (Safari) not having KeyboardEvent.code.
getKeyCode(event: KeyboardEvent) {
if (event.keyCode) {
console.log(event.keyCode, event.code);
if (65 <= event.keyCode && event.keyCode <= 90) {
return "Key" + String.fromCharCode(event.keyCode);
} else {
switch (event.keyCode) {
case 13: return "Enter";
case 106: return "NumpadMultiply";
case 107: return "NumpadAdd";
case 109: return "NumpadSubtract";
case 110: return "NumpadDecimal";
case 111: return "NumpadDivide";
case 187: return "Equal";
case 188: return "Comma";
case 189: return "Minus";
case 190: return "Period";
case 222: return "Backquote";
}
}
}
}
onResize¶
onResize()
onResize メソッドは、 index.html
の Web ページで使用されているさまざまなオーバーレイのサイズを変更します。この関数の影響を受けるオーバーレイは、次のとおりです。
- videoOverlay,
- canvas3d,
- promptOverlay (サウンド調整に使用)、および
- 各オブジェクト名のアニメーション div。
index.html
ページに表示するビデオストリームのサイズ値を取得し、このサイズを元に他のオーバーレイを調整します。このサンプルでは、オブジェクトが適切に選択できるようにするために、適切なオーバーレイサイズが必要となるため、サイズ変更が不可欠です。また、ビデオ内のオブジェクトの目印にするために、適切な場所に WebGL の輪を表示する必要があります。
// Allow to adjust the various overlay when resizing the windows - needed to see the PromptOverlay and Name moving div
onResize() {
let refElement = this.client.videoElem; // The element to match.
let refElementSize = refElement ? genvidMath.vec2(refElement.clientWidth, refElement.clientHeight) : genvidMath.vec2(1280, 720);
let refElementRatio = refElementSize.x / refElementSize.y;
let videoRatio = this.client.videoAspectRatio;
let pos: genvidMath.IVec2;
let size: genvidMath.IVec2;
if (videoRatio >= refElementRatio) {
// Top+Bottom bars, fill width fully, shrink height.
let ey = refElementSize.x / videoRatio;
let dy = refElementSize.y - ey;
// Center vertically.
let y = dy * 0.5;
pos = genvidMath.vec2(0, Math.round(y));
size = genvidMath.vec2(refElementSize.x, Math.round(ey));
} else {
// Left+Right bars, fill height fully, shrink width.
let ex = refElementSize.y * videoRatio;
let dx = refElementSize.x - ex;
// Center horizontally.
let x = dx * 0.5;
pos = genvidMath.vec2(Math.round(x), 0);
size = genvidMath.vec2(Math.round(ex), refElementSize.y);
}
let style = this.videoOverlay.style;
let cur_pos = genvidMath.vec2(parseInt(style.left), parseInt(style.top));
let cur_size = genvidMath.vec2(parseInt(style.width), parseInt(style.height));
if (!genvidMath.equal2D(cur_size, size, 0.9) || !genvidMath.equal2D(cur_pos, pos, 0.9)) {
this.videoOverlay.style.left = pos.x + "px";
this.videoOverlay.style.width = size.x + "px";
this.videoOverlay.style.top = pos.y + "px";
this.videoOverlay.style.height = size.y + "px";
this.canvas3d.width = size.x;
this.canvas3d.height = size.y;
this.genvidWebGL.setViewport(0, 0, size.x, size.y); // Render in the whole area.
}
if (this.lastSelection != null) {
this.onSelect(this.lastSelection, true);
}
else {
for (let nameSelect of this.cubeDiv) {
nameSelect.style.backgroundColor = "#181818";
}
}
}
toggleFullScreen¶
toggleFullScreen()
toggleFullScreen メソッドは、ビデオのフルスクリーンを有効または無効にします。checkFullScreen 関数でフルスクリーンの状態を確認し、適切な状態に調整します。
すでにフルスクリーンである場合は、Web ブラウザ機能に従ってフルスクリーンをキャンセルし、フルスクリーンボタンアイコンも調整します。
フルスクリーンでない場合は、 video_area
要素を取得します。その後、Web ブラウザ機能でフルスクリーンを有効にし、フルスクリーンボタンアイコンを更新します。
toggleFullScreen() {
let doc = <any>document;
if (this.checkFullScreen()) {
if (doc.exitFullscreen) {
doc.exitFullscreen();
} else if (doc.mozCancelFullScreen) {
doc.mozCancelFullScreen();
} else if (doc.webkitExitFullscreen) {
doc.webkitExitFullscreen();
} else if (doc.msExitFullscreen) {
doc.msExitFullscreen();
}
this.fullScreenElement.classList.remove("fa-compress");
this.fullScreenElement.classList.add("fa-expand");
} else {
let element = <any>document.querySelector("#video_area");
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
}
this.fullScreenElement.classList.remove("fa-expand");
this.fullScreenElement.classList.add("fa-compress");
}
}
onMute¶
onMute()
onMute メソッドは、ビデオプレイヤーがミュート/ミュート解除されるたびに呼び出されます。
この関数を呼び出すと、 getMuted()
を呼び出してミュート状態を取得し、オーディオ、ボリュームアップなどのアイコンの見やすさ、オーバーレイメッセージを調整することができます。
// Depending on the status, mute or unmute the video player audio
onMute() {
const muteIcon = document.querySelector("#mute-button i");
this.promptOverlay = <HTMLDivElement>document.querySelector("#prompt_overlay");
if (this.client.videoPlayer.getMuted()) {
muteIcon.classList.remove("fa-volume-off");
muteIcon.classList.add("fa-volume-up");
this.client.videoPlayer.setMuted(false);
this.promptOverlay.style.visibility = "visible";
this.promptOverlay.textContent = "Volume is unmuted";
this.timeVisiblePrompt = 0;
} else {
muteIcon.classList.remove("fa-volume-up");
muteIcon.classList.add("fa-volume-off");
this.client.videoPlayer.setMuted(true);
this.promptOverlay.style.visibility = "visible";
this.promptOverlay.textContent = "Volume is muted";
this.timeVisiblePrompt = 0;
}
}
showOverlay¶
showOverlay()
showOverlay メソッドは、Genvid オーバーレイを表示します。
// Change the style to display the Genvid overlay
showOverlay() {
this.genvidOverlay.style.display = "block";
}
hideOverlay¶
hideOverlay()
showOverlay メソッドは、Genvid オーバーレイを非表示にします。
// Change the style to hide the Genvid overlay
hideOverlay() {
this.genvidOverlay.style.display = "none";
}
clickCube¶
clickCube(event: MouseEvent)
clickCube は、WebGL オーバーレイをクリックしてキューブが選択されたと pickCube メソッドが判断した場合に、 true を戻します。そうでない場合は、この関数でイベントの伝達を処理します。
// Method used when clicking on the WebGL overlay
clickCube(event: MouseEvent) {
let best = this.pickCube(event);
if (best) {
return true;
} else {
// Continue propagation.
return false;
}
}
pickCube¶
pickCube(event: MouseEvent)
pickCube メソッドは、WebGL オーバーレイをクリックした時にキューブが選択されているかどうかを確認します。
ゲームデータが有効かどうかを確認し、無効の場合は、他の検証を行いません。
ウィンドウ内でクリックした位置を取得します。
その後、この座標を投影空間に変換します。
if (this.lastGameData == null) { return false; } // [0, 1] coordinates in the window. let rect = this.canvas3d.getBoundingClientRect(); let x = event.pageX - rect.left; // More robust to recompute from pageX/pageY. let y = event.pageY - rect.top; let p01 = genvidMath.vec2(x / rect.width, y / rect.height); // [-1, 1] coordinates in projection space. let p = genvidMath.mad2D(p01, genvidMath.vec2(2, -2), genvidMath.vec2(-1, 1)); let mat = this.convertMatrix(this.lastGameData.MatProjView); let best = null; let bestDist = Infinity;
各オブジェクトの座標を確認するループ処理を開始します。
このループ処理で、オブジェクトの座標を取得し、検索するゾーンの半径を適用します。
最後に、座標がオブジェクトゾーン内にあるかどうかを検索し、距離に応じて最良の結果として保持します (2 つのオブジェクトが近い場合、ゾーンまでの距離が小さいものが選択されます)。
for (let cube of this.lastGameData.cubes) { let pos3D = genvidMath.vec3(cube.mat.e03, cube.mat.e13, cube.mat.e23); let radius = 1.0; let pos2D_rad2D = this.projectWithRadius(mat, pos3D, radius); let pos2D = pos2D_rad2D[0]; let rad2D = pos2D_rad2D[1]; let pos2D_to_p = genvidMath.sub2D(p, pos2D); let d = genvidMath.length2D(pos2D_to_p); if (d < rad2D && d < bestDist) { best = cube.name; bestDist = d; } } if (event.ctrlKey || event.metaKey) { this.toggleSelection(best); this.onSelect(best, false); } else if (best != null) { this.setSelection(best); this.onSelect(best, false); } return best;
toggleSelection¶
toggleSelection(name)
toggleSelection メソッドは送信されたオブジェクト名を選択状態として追加します。
// Select a cube via the circle
toggleSelection(name) {
if (!this.removeFromArray(this.selection, name)) {
this.addToSelection(name);
}
}
setSelection¶
setSelection(name)
setSelection メソッドは、選択したオブジェクトが選択された状態になるように選択リストをリセットします。
// Set the selection to a specific cube
setSelection(name) {
this.selection = [];
if (name) {
this.selection.push(name);
this.client.sendEventObject({ select: name });
}
}
isSelected¶
isSelected(name)
isSelected メソッドは、オブジェクトが選択されているかどうかを判別します。
// Verify if the cube is selected
isSelected(name) {
return this.selection.indexOf(name) !== -1;
}
addToSelection¶
addToSelection(name)
addToSelection メソッドは、オブジェクトが前回選択されなかった場合に、オブジェクトを選択に追加します。
// Add the cube selected to the selection list
addToSelection(name) {
if (name && !this.isSelected(name)) {
this.selection.push(name);
}
}
changeOffset¶
changeOffset(direction, event)
changeOffset メソッドはビデオの遅延オフセットを追加、縮小、またはリセットします。引数の方向が 0 の場合、ビデオの遅延オフセットはリセットされ、それ以外の場合は送信された値に応じて変更されます。
// Function that changed the delay offset depending of the key pressed
private changeOffset(direction, event) {
if (direction !== 0) {
let delayDelta = 100 * direction;
if (event.altKey) delayDelta *= 10;
if (event.shiftKey) delayDelta /= 2;
let newDelayOffset = this.client.delayOffset + delayDelta;
this.client.delayOffset = newDelayOffset;
} else {
this.client.delayOffset = 0;
}
}
toggleGenvidOverlay¶
toggleGenvidOverlay()
toggleGenvidOverlay メソッドは、Genvid オーバーレイの表示、非表示を切り替えます。Genvid オーバーレイは、ストリームに関するさまざまなデータを表示します。
- Raw Video
- raw ビデオを受信した時間。
- Est. Video
- ビデオを受信した時点の推定時間。
- Last Compose
- 直前の合成時間。
- Est. Compose
- 推定合成時間。
- Stream
- ストリーミングが開始されてからの時間。
- Latency
- ストリームを見ている時に発生する遅延。
- DelayOffset
- ビデオの現在の遅延オフセット。
// Display or remove the Genvid Overlay
private toggleGenvidOverlay() {
if (this.genvidOverlay.getAttribute("data-isHidden")) {
this.genvidOverlay.setAttribute("data-isHidden", "");
this.genvidOverlay.style.visibility = "visible";
this.genvidOverlayButton.classList.remove("disabled");
} else {
this.genvidOverlay.setAttribute("data-isHidden", "true");
this.genvidOverlay.style.visibility = "hidden";
this.genvidOverlayButton.classList.add("disabled");
}
}
onHelpActivation¶
onHelpActivation()
onHelpActivation メソッドは、ヘルプオーバーレイの表示、非表示を切り替えます。
// Display or remove the help overlay
private onHelpActivation() {
if (this.help_overlay.style.visibility === "visible") {
this.help_overlay.style.visibility = "hidden";
}
else {
this.help_overlay.style.visibility = "visible";
}
}
onCheer¶
onCheer(cubeName: string)
onCheer メソッドは、プレイヤーを応援するボタンをクリックしたときに、クライアントにイベントを送信します。イベントにはオブジェクト名が含まれます。
// Upon cheering a player
private onCheer(cubeName: string) {
this.client.sendEventObject({ cheer: cubeName });
}
onReset¶
onReset(cubeName: string)
onReset メソッドは、プレイヤーをリセットするボタンをクリックしたときに、イベントを送信します。イベントにはオブジェクト名が含まれます。
// Reset the position of the cube
private onReset(cubeName: string) {
this.client.sendEventObject({ reset: cubeName });
}
onColorChange¶
onColorChange(cube: string, color: string)
onColorChange メソッドは、プレイヤーの色を変更するボタンをクリックしたときにイベントを送信します。イベントには、オブジェクト名と色が含まれます。
// Method used when clicking on a color to change the color of a cube
private onColorChange(cube: string, color: string) {
let evt = {
key: ["changeColor", cube],
value: color,
};
this.client.sendEvent([evt]);
}
onSelect¶
onSelect(cubeName: string, selectionInterface: boolean)
onSelect メソッドは、ビデオストリームの下に表示されるプレイヤーテーブルをクリックした時に UI を変化させます。各テーブルの色をリセットし、選択したテーブルにのみ色を適用し、その後、WebGL の輪を選択します。
// Select the cube from the interface
private onSelect(cubeName: string, selectionInterface: boolean) {
for (let nameSelect of this.cubeDiv) {
nameSelect.style.backgroundColor = "#181818";
}
let cubeDiv = <HTMLDivElement>document.querySelector(".cube" + cubeName);
this.lastSelection = cubeName;
cubeDiv.style.backgroundColor = "#32324e";
if (selectionInterface) {
this.setSelection(cubeName);
}
}