HTMLとJavaScriptを使いブラウザ上でターミナル風の見た目を表現できないだろうかと考えて作成した。
確認リンクは以下から(それがどうしたの!なんて言わないで下さいね)
textareaタグを使ってブラウザをターミナル風に装う
現時点の仕様は、コマンドは受け付けず、見た目だけターミナル仕様。(と言うかこれ以降の仕様があるのか!?)
F11キーで全画面表示にすると時代が遡ったかのような錯覚をうけます!
作成の道のり
では作成の流れを順を追って説明する。
HTMLでサイト内にtextareaタグを1つだけ配置(HTML)
HTML部分。bodyタグに直接textareaタグを1つだけ配置しているだけのシンプル仕様。
textareaタグのポイントを1つ挙げるとすれば、spellcheckプロパティにfalseを指定している点。
<textarea id="terminal" rows="5" cols="20" spellcheck="false"></textarea>
これがtrueになっていると(デフォルトではtrue)文字を入力した際、スペルチェック機能が働き、文字の下に赤い波線が表示されてしまう。
こんな感じ。
これだけでターミナルの雰囲気が台無しになったので、今回spellcheck=falseを指定した。
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,user-scalable=no"> <link rel="stylesheet" href="style.css"> <script src="main.js" type="text/javascript"></script> <title>Terminal</title> </head> <body> <textarea id="terminal" rows="5" cols="20" spellcheck="false"></textarea> </body> </html>
上記、スペルチェック機能のによるちょっとした見た目の違和感に関しては、以下に少々まとめたので参考にして欲しい。
textareaタグをブラウザ画面いっぱいに引き伸ばす(JavaScript)
つづいてJavaScript部分。
まず、ブラウザサイズを取得してtextareaタグをブラウザのサイズに合わせる関数setTerminalを作成しておき、
/* * ターミナルのサイズをブラウザ画面いっぱいに設定する関数 */ function setTerminal(){ // ブラウザのウインドウサイズを取得 let innerWidth = window.innerWidth; let innerHeight = window.innerHeight; // textareaのサイズをウインドウにフィットさせる terminal.style.innerWidth = innerWidth + "px"; terminal.style.innerHeight = innerHeight + "px"; }
この関数を起動時に実行するようにして画面いっぱいにtextareaタグを広げている。
起動時の処理としては、そのほかプロンプトの表示とカーソルを点滅させるためにフォーカスをtextareaタグに移動している。
/* * 起動時の処理 */ window.addEventListener("load", function(){ // textareaのDOM取得 terminal = document.getElementById("terminal"); // ターミナルのサイズをブラウザ画面いっぱいに設定 setTerminal(); // ターミナルの初期状態(textareaタグの文字列にプロンプトを表示) terminal.value = operater; // ターミナル(textareaタグ)にフォーカス ==>カーソルが点滅する terminal.focus(); });
また、画面リサイズ時もその都度ブラウザサイズを取得して画面サイズが変更されてもフィットするようにしている。
注)Chromeでは、この処理を入れずに実行してもきちんとフィットしていた。(原因は不明)
/* * ブラウザ画面をリサイズした際に再度ターミナルのサイズをブラウザ画面いっぱいにする関数 */ window.addEventListener("resize", function(){ setTerminal(); });
あとJavaScript部分では、後述するtextareaタグ上(ターミナル上)でEnterキーを押した際の処理を行っている。
Enterキーを押した時、改行して再度プロンプトを表示する(JavaScript)
プロンプト表示の文字列用とtextareaの内容保存用に2つの変数を用意した。(operater変数の内容は適当に変えてください)
var operater = "Command> "; // コマンド入力時のプロンプト文字 var value = ""; // ターミナル画面上の文字列取得用
キーイベント発生時にキーコードを取得し、Enterキーである判定をしている。(ちなみにEnterキーは13番)
/* * ターミナル上(textareaタグ)でキー入力した際のイベント処理 */ window.addEventListener("keyup", function(e){ // キー番号を取得 let key = e.keyCode; // Enterキーが押されたとき if(key == 13){ // Enterキーが押された時の処理 // : } });
実際にテストしてみると漢字変換の際にEnterキーを押すことがあるため、漢字変換の際のEnterキーイベントなのか、コマンドを入力して実行(あくまでイメージですが)とした際のEnterキーのイベントなのか判断する必要がでてきた。
具体的に言うと、漢字変換でEnterキーを押した場合、新しいプロンプトを表示させたくないのだが、「漢字変換の時のEnterキーだよ!」という判定をしておかないと新しいプロンプトが表示されてしまうのだ。
そこで、正規表現を使った判定(match)を利用して、textareaの文字列の最後が改行文字でない場合は、新しいプロンプトを表示しないようにした。
(直接入力では、Enterキーを押すと改行されるため、textareaの最後の文字が改行文字となる)
他にも方法はあるだろうが、今回はこの方法で落ち着いた。
value = terminal.value; // textareaの文字列を取得 if(value.match(/\n$/) == null){ // 漢字変換でEnterキーを押した場合 return; // 取得した文字の最後が改行文字ではないので何もしない }
漢字変換かどうかの判定が出来れば、あとは簡単で、
1.新しいプロンプトを表示し
2.textareaにフォーカスを移動(一応)
すればターミナル風に見えるようになる。
// 新しいプロンプトを追加表示 terminal.value = value + operater; // フォーカスを常にtextareaにしておく terminal.focus();
最後はターミナル風の見た目にするためのCSS(スタイルシート)設定。
textareaタグをターミナル風の見た目にする(CSS)
当初は、見た目だけなら背景色を黒、文字色を白とすれば問題ないかと考えていたが、意外にスクロールバーが表示されたりtextareaの拡大縮小ができるようになっていたりとデフォルト設定を見なおす必要があった。
最低限、以下の4つのプロパティ(overflow display, border, resize)設定は必要だった。
overflow: auto; /* IEでは設定しておかないとスクロールバーが表示されしまう */ display: block; /* 指定しないとスクロールバーが表示される */ border: none; /* 変な余白が出ないように */ resize: none; /* リサイズできると格好悪いので */
上記4つのうちどれが欠けても正直かっこ悪い。
こんな感じ。
overflowに関してはIEで実行した際、右端にスクロールバーが表示されてしまうため、必要。
結果的に落ち着いたのが以下のCSS。
/* ターミナル表示用textareaタグ */ #terminal{ font-family: 'courier new', Futura, Helvetica, '游ゴシック', 'メイリオ', Osaka; width: 100%; height: 100%; overflow: auto; /* IEでは設定しておかないとスクロールバーが表示されしまう */ display: block; /* 指定しないとスクロールバーが表示される */ border: none; /* 変な余白が出ないように */ resize: none; /* リサイズできると格好悪いので */ background-color: black; color: white; font-size: 12pt; line-height: 1.4em; /* 全角文字を入力時にこれ以上の高さがないと入力時にぎくしゃくするため */ }
その他
font-familyには、個人的に好きな「courier new」を指定しているが、ここはお好みで。
line-heightに1.4em以下を指定すると、全角モードにしたとき行が若干ずれてぎくしゃくして見える。
以下にindex.html, main.js, style.cssの全ソースコードを示す。(使い道があるか分かりませんが…)
コメント