Go言語+WebAssemblyでマウスイベントを実装する


前書き

Goで記述したファイルをwebAssemblyにコンパイルする形で一通りのマウス操作を検知できるようになったのでまとめました。
Go言語+Webassemblyでフロントエンドを実装しようとしてる方の参考になれば幸いです。
勉強中なので、間違いがあればご指摘ください。
今回のコードはこちら:Github

画面サンプル

実行環境

OS:Windows 10 64bit
言語環境:go version go1.14.1
ブラウザ:Firefox バージョン: 74.0

ディレクトリ構成
MouseAction
|-index.html(アクセスするWebサイト)
|-main.go(WebAssemblyのソースファイル)
|-main.wasm(上記をコンパイルしたファイル)
|-wasm_exec.js(実行に必要なスクリプトファイル)
|-image(html内で使う画像)
 |-image1.png
 |-image2.png

「main.go」はあくまでソースファイルなので実行する際にディレクトリに置いておく必要はありません。コンパイルの方法やテスト用webサーバは、過去の記事をご参考ください。
(Go言語)WebAssemblyで簡単なWebサイトを作ってみた

コード解説

コードの一部を抜粋しながら説明します。

html内のid属性で操作対象のオブジェクト検索しています。
(html内に対象のidがなければ開発者コンソールにエラーがでます)

index.html(抜粋)
<img id="image1" src="image/image1.png" title="サラリーマン" alt="image1"><br>

main関数
main関数内では、操作を個別に記述し引数に操作対象のid属性を渡しています。

main.go
func main() {
    //対象のアクション(html上の対応するID)
    click("image1")
    text_change("image1", "text1")
    mouseIn("image2")
    mouseOver("image3")
    get_mouthXY("image4", "text2")
    //touch("image3")
    // プログラムが終了しないよう、チャネルの待ち受けをする
    <-make(chan struct{}, 0)
}
click(stirng)
func click(id string) {
    //idから対称のオブジェクトを取得
    object := js.Global().Get("document").Call("getElementById", id)
    //操作内容
    action := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        //画像の差し替え処理
        ~~~省略~~~
        //objectに対して画像の変更
        object.Set("src", string("image/image2.png"))
        ~~~省略~~~
        return nil
    })
    //アクションの呼び出し
    object.Call("addEventListener", "click", action)
}

マウスアクションの種類

実装したマウスアクションの一覧です。

main.goから抜粋
    object.Call("addEventListener", "click", action)        //クリック
    object.Call("addEventListener", "mouseover", action)    //オブジェクトに対してマウスカーソルが入った瞬間
    object.Call("addEventListener", "mouseout", action)     //オブジェクトに対してマウスカーソルが出た瞬間
    mx := args[0].Get("clientX").Float()                //マウスのX座標
    my := args[0].Get("clientY").Float()                //マウスのY座標

html要素への操作

main.goから抜粋
//<imgタグ>の操作
    object.Set("src", string("image/image2.png"))   //画像の差し替え
    object.Set("alt", string("image2"))             //画像の名前はalt属性で判断
//<div id="ID名">の操作
    object.Set("innerHTML", tmp)                    //テキストの変更

html要素から数値を取得する場合は、いったんString型で受け取ってstrconv.Atoi()で数値型に変更しないと動作しませんでした。

感想

Javascriptができる人ならすぐに実装できていたと思いますが、
DOM操作等の知識がなかったので時間がかかりました。

しかしgo言語だけで、Webサーバーからフロントエンドまで構築できるので
Go言語の幅広さを実感できました。

今後もgo言語の知識をつけていきたいと思います。
関西圏でGo言語の勉強会等知っていましたら是非コメントください。

参考にしたサイトや画像の提供元

参考記事:https://www.agent-grow.com/self20percent/2018/09/03/golang-wasm-support/
画像:https://icooon-mono.com/