ChienomiChienomiテキストをスクロール表示させるプログラムについて諸兄も一度はYouTubveで見たことがあるのではないだろうか。文字がただ流れるだけの動画を。作業ウィンドウ以外で流しておくことでウィンドウフォーカスを切り替えなくて済む、というメリットもある。mpvを使うと、右クリックで再生/停止ができるし、再生速度もコントロールできてまあまあ便利だ。検索性がないのでやっぱりストレスである。そこで、テキストリーダーに自動スクロール機能が欲しい、と思った。ありそうだが、見当たらなかった。一行単位であればsleepとreadでも組み合わせればいいのだが、これはパッと動いてしまうため目の追従が難しく、読みづらい。1ピクセルずつ動かしたいのだ。xdotoolを使う、という方法も考えたのだが、意図したようにはうまくいかなかった。JavaScriptを使えばすごく簡単なのに...というわけで、JavaScriptを使う方向でがんばることにした。すごーーーーく単純に一時ファイルでHTMLを作ってQtWebengineで表示すればいいと思って、Pythonで作ったのだが......Surfでよかった。配布するならSurfみたいなマイナーなものは入れたくないなんていう天邪鬼さん1や、Surfは入っていないなんていう弱小ディストリさんはいっぱいいると思うので良しとしよう。珍しく日本語READMEもある。BGM機能があるのは、YouTubeでよく見るものをリスペクトしたものであり、背景画像がほしければCSS編集でOKだ。やっていることはごく単純で、Pandocで処理することを前提として一時ファイルを活用している。プレーンテキストの場合はsedを使ってラインブロック化している。この場合改行されなくなってしまうので、pre-wrapするようにデフォルトのスタイルシートで変更している。スクロール制御はJavaScriptでものすごく入門的なコードだ。右クリックでも再生・停止できるようにしているのは、コントロールをウィンドウフォーカスしてからでなくても行えるようにするためである。ちなみに、今回のJavaScriptは互換性をあまり気にしない贅沢なコードでもある。これはかなり新しいGtkWebkit、あるいはQtWebengineを使うという前提が成り立っているためだ。解説それでは恒例の初心者向けコードJavaScript部分せっかくなので、入門的なJavaScriptコードを解説しよう。スクロール部分まずスクロール自体はwindow.scroolByによって実現できる。自動スクロールをするためにはこれを繰り返すようにしなくてはいけない。単純なループでもできるのだが、JavaScriptはシングルスレッドなので操作不能になってしまう。このような反復はJavaScriptではタイマーイベントで行う。タイマーにコールバック関数を登録することで、タイマー起動時にコールバック関数が実行される。他の処理が実行中の場合は処理をキューに入れ、順番がきたら実行される。どちらかといえばタイマーイベントを都度登録するsetTimeoutのほうがコントロールしやすい。関数オブジェクト、クロージャという考え方になれていないとそもそもコールバック関数が使えないので、ここはしっかりと理解しておく必要がある。関数オブジェクトは実行可能なコード群をオブジェクト化したものである。スイッチを押せば実行される物体になっているとでも思えばいい。コールバック関数は、それを呼び出すタイミングでそのスイッチを押すように動作する。指定した時間が経過したときにコールバックを行う。呼ぶことでループさせることができる。「スクロールの開始」はその関数を呼べば良い。しなければ次回の実行がなされないため、停止する。停止方法はタイマーをキャンセルするのではなく、次回のタイマーセットを行わないというものである。使用した場合はタイマーをセット/キャンセルして制御する。対してイベントリスナーを設定する。設定する情報はやや少ない。オブジェクトが渡される。特定のキーをキャプチャするわけではなく、キーボード入力全てをキャプチャしてコールバック関数が呼び出される。コールバック関数内でキーを判別する。コールバック関数が時間がかかるとフリーズしていると感じることになるため注意が必要。