ウィジェットを任意の場所に自由に動かす方法

#目次
1. はじめに
2. 実装方法
    3. widgetの用意
    4. コーディング
    5. Actionの紐付け
    5. ソースコード全体
3. まとめ
4. 参考


#はじめに
今回はWidgetを自分の任意の場所に動かす実装方法について紹介します！
完成イメージ
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/T2GbWkkt0K">pic.twitter.com/T2GbWkkt0K</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1341243192914538497?ref_src=twsrc%5Etfw">December 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#実装方法
###1. widgetの用意
まず動かす対象のWidgetを用意します。
今回は、flxMoveという名前で作成しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/66164a87-e7e7-7650-5754-7d956498640b.png" width=70%>

今回は、flxMoveを固定の位置ではなくドラック&ドロップして任意の場所に動かしたいので、
**Widgetの位置(Left/Right/Top/Bottom)は、defaultに設定するようにしてください**。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/3502230e-7049-c9c0-0752-f39ddd185fcb.png" width=50%>

Widgetの位置は、このあとそれぞれのアクション設定の説明で、
ユーザーが動かした位置に移動するように設定していきます。


###2. コーディング
次にWidgetを任意の場所に移動させるコードを`FormMainController`に書きます。

ユーザーが対象のものに触れた時、動かす時、動かし終わった後に
それぞれ座標が決まるように設定をしていきましょう。
アクションは以下を使っていきます。

| アクション名 | 説明 |
|:-----------|:------------|
| onTouchStart |対象のものに触れた時に呼び出されるアクション| 
| onTouchMove|対象のものを動かすときに呼び出されるアクション| 
| onTouchEnd |対象のものから指を離すときに呼び出されるアクション | 


```FormMainController1.js
  x: null,
  y: null,
  isMove: false,

  onTouchStart:function(eventobject, x, y){
    this.x = x;
    this.y = y;
    this.isMove = true;
  },
```
まず、onTouchStartではflxMoveに触れた時の座標を保存します。

その他のコードについて説明します。
isMoveは、対象物が動いたかどうかわかるよう設定している値です。
デフォルトは、falseとし、アクションがスタートしたらisMoveフラグをtrueにします。

`eventobject`は、触れている対象widgetの情報で、`x`と`y`は対象widgetの座標となります。
（Konyでは左上から位置を設定しており、左からの距離を`x`、上からの距離を`y`として設定します。）
onTouchStartが呼ばれたら、座標を保存するように設定しています。

`eventobject`の取得方法については、
アクション設定の際に返却する値を指定できますので、3.Actionの紐付けでご説明します。

```FormMainController2.js
  onTouchMove:function(eventobject, x, y){
    if(this.isMove){
      // 移動距離
      var moveX = x - this.x;
      var moveY = y - this.y;
      // flxMoveの座標に加算
      eventobject.left+=moveX;
      eventobject.top+=moveY;
      // レイアウトを更新する
      this.view.forceLayout();
    }
  },
```

onTouchMoveでは、isMoveフラグがtrueの時、flxMoveの座標を移動させます。
保存したxとy(元の位置)から移動した距離を求め、
flxMoveのleftとtopにそれぞれの距離を加算します。

最後に`this.view.forceLayout();`で変更を更新します。

```FormMainController3.js
  onTouchEnd: function(eventobject, x, y){
    this.isMove = false;
  },
```
onTouchEndでisMoveフラグをfalseにして、flxMoveの移動を終了させます。


###3. Actionの紐付け
関数の準備ができたらActionと紐づけていきます。

今回は、`onTouchStart`、`onTouchMove`、`onTouchEnd`を使用してflxMoveを任意の場所に動かせるようにします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/a3c5df7c-5dc2-21c3-b583-78dda3f2eeb3.png" width="300dp">

対象のwidget(flxMove)を選択した状態で、Actionタブを開いてください。

まず、onTouchStartのEditをクリックしてActionの紐づけを行います。
![スクリーンショット 2020-12-22 11.58.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/0c66fcac-dae9-5186-a0be-2ce4a9ddb460.png)
先ほどコントローラーに設定した`eventobject`は、
Input ParametersのValue列にあるEditをクリックすることで、設定することができます。
![スクリーンショット 2020-12-22 12.08.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/fc038bba-6883-aeb4-b099-c4c6eadd2c55.png)

onTouchMoveとonTouchEndも同様にActionを紐づけていきましょう！

###4. ソースコード全体

```FormMainController.js
define({
  x: null,
  y: null,
  isMove: false,
  
  onTouchStart:function(eventobject, x, y){
    this.x = x;
    this.y = y;
    this.isMove = true;
  },

  onTouchMove:function(eventobject, x, y){
    if(this.isMove){
      var moveX = x - this.x;
      var moveY = y - this.y;
      eventobject.left+=moveX;
      eventobject.top+=moveY;
      this.view.forceLayout();
    }
  },

  onTouchEnd: function(eventobject, x, y){
    this.isMove = false;
  },
});
```

最後に、実際に動作を見てみましょう。
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/T2GbWkkt0K">pic.twitter.com/T2GbWkkt0K</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1341243192914538497?ref_src=twsrc%5Etfw">December 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

flxMoveを好きな場所に移動できていると思います。

#まとめ
今回はWidgetを任意の場所に自由に移動させる実装方法についてご紹介しました。
簡単な画像加工アプリやパズルゲームアプリなどに活用できるかと思います！
Konyでしたら簡単に実装できるので、ぜひ試してみてください！


#参考
ActionProperties：
https://qiita.com/Kony_Team/items/2239d4bcb1d4bace8da3#5action%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3