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

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-165026621-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-165026621-1');
</script>

#前書き

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

###画面サンプル
<img width="300" alt="click" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436464/1ca0a162-371c-33cc-1ff8-b1ce2e14ab7d.gif"><img width="280" alt="click" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436464/46c65b5d-f7a7-4c77-1b0e-86c1029c76ad.gif">


#実行環境
 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サイトを作ってみた](https://qiita.com/daemonkimura/items/df58dd5e4843542b1389)

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

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

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

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

```main: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/