GoogleAppsScriptのDrawing Classでつくってあそぼう!


## はじめに

本記事は先日行われた[【オンライン対談】Google Apps Script 活用トーク #6](https://gaiax.connpass.com/event/175102/)で私が登壇した内容をTech記事としてリライトしたものになります。

登壇感想込のものはブログに後ほど上げるので興味がある方はそちらも御覧ください。

資料: https://docs.google.com/presentation/d/1ouLvrtngVI4ykKftBCYozVS-Nr6FZj54LgCqYsKOx3Y/edit?usp=sharing

## Dowing Classとは

Drawing Classは2020/04/02にリリースされたスプレッドシートサービス内のクラスで図形に関するパラメーターを操作する事ができるものです。  
これによってシート上の図形のサイズを変更したり、位置を変更することができます。

### 実装されてるメゾット

実際に使用できるメゾットの一部を紹介します。  
 より詳しい内容を知りたい方は公式ドキュメント[Class Drawing|Google Developers](https://developers.google.com/apps-script/reference/spreadsheet/drawing)を御覧ください。
 
#### getContainerInfo() 
図面が格納されているコンテナの情報を取得します。  
主に位置を取得するのに使います。(サイズは後述のgetWidth, getHeigeht取ることができます)

```javascript
function printDrawPosition() {
  const drawings =SpreadsheetApp.getActiveSheet().getDrawings();
  // 設置されている列番号
  Logger.log(drawings[0].getContainerInfo().getAnchorColumn())
  // 設置されている行番号
  Logger.log(drawings[0].getContainerInfo().getAnchorRow())
  // 設置されているセルの左上からどれだけx軸で離れているか(pixcel)
  Logger.log(drawings[0].getContainerInfo().getOffsetX())
  // 設置されているセルの左上からどれだyy軸で離れているか(pixcel)
  Logger.log(drawings[0].getContainerInfo().getOffsetY())
}
```

#### drawings.getHeight()
#### drawings.getWidth()

メゾット名の通りで高さと横幅を取得します。返り値はPixel単位です。

```javascript
const drawings =SpreadsheetApp.getActiveSheet().getDrawings();

  // 縦(pixels)
  Logger.log(drawings[0].getHeight())
  // 横(pixels)
  Logger.log(drawings[0].getWidth())

```

#### getZIndex()
Z軸の数値を取ります。 Z軸はオブジェクト同士の重なり順で若い数字ほど手前にあることになります。

#### setWidth()
#### setHeight()
高さや幅を変更できます。単位はpixelです

```javascript
// 横200px に変更する
drawings[0].setWidth(200)
// 縦200pxに変更する
drawings[0].setHeight(200)
```

#### setPosition()

図形の位置を変更します。
指定の仕方は(行番号, 列番号, 横オフセット値(px), 縦オフセット値(px))です。
前半2つの引数で指定したセルの左上のポイントを0として指定されたオフセット値分移動します。

![](https://i.imgur.com/srQe2hw.png)

```javascript
// 4行目4列目に移動して横200lpx縦200ｐｘに移動する
drawings[0].setPosition(4, 4, 200, 200)
```

### できないこと

今回のクラスでは以下のことはできません。今後の追加のリリースに期待しましょう。
- 図形の追加
- 図形の複製
- 図形の形の変形

## 活用例

今回実装されたもので考えた活用例になります。  
まだまだ、未熟な状態のクラスですが、使い方次第でも色々とできるものになっています。

### 1.処理中の操作保護

図形を画面いっぱいに広げる事によってセルの操作を不可能にします。  
重い処理を書いたときセルが操作されることによってエラーで落ちるときなどに使えます

```javascript
function coverCell() {
  const drawings =
          SpreadsheetApp.
          getActiveSheet()
          .getDrawings();

  // 高さと横幅変更[
  drawings[0].setWidth(1920)
  drawings[0].setHeight(1080)
  // 場所変更
  drawings[0].setPosition(1, 1, 0, 0)

  // … 処理後 …

  // 高さと横幅変更
  drawings[0].setWidth(1)
  drawings[0].setHeight(1)
  // 場所変更
  drawings[0].setPosition(1, 1, 0, 0)
}

```

![](https://i.imgur.com/1FKXPlJ.png)

ちなみにサイズ変更時に最小の1pxを指定するとクリックが不可能な状態になります。
0を指定した場合は横は450px縦は325pxに自動出来に設定されます。
![](https://i.imgur.com/hZKlBxr.png)


### 2.プログレスバー


こちらも重い処理の時向けの例です。  
重い処理を書いたときにユーザー化から画面が変わらないので正しく動いてるかわからないというご意見をしばしもらうときがありますが、そういったときに活用できる例になります。 

2つの図形を使用し、処理に合わせてプログレスバーを動かすことに寄って処理中をアピールできます。  

TIPSとして拡大時にアスペクト比が変わる場合は線はあまり使わないほうが良いでしょう。  
拡大時に線はアスペクト比に合わせて再描写はされず縦線横線の幅が変化してしまいます。

```javascript

function progressbar() {

  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const width = 500
  const Height = 100
  const drawings = spreadsheet.getSheetByName('進捗バー').getDrawings()

  window = drawings[0]
  progress = drawings[1]
  // 初期化
  window.setHeight(Height)
  window.setWidth(width)
  window.setPosition(1, 1, 0, 0)

  progress.setHeight(100)
  progress.setWidth(1)  // \進捗ゼロ!/
  progress.setPosition(1, 1, 0, 0)

  for(var i = 1; i <= 100; i++){
    progress.setWidth((width/100) * i)
  }

```
<iframe width="560" height="315" src="https://www.youtube.com/embed/KIwddWEC6ec" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>



### 3.ゲーム

ゲームは近日中に別の記事でにしますのでしばしお待ち下さい。


## まとめ

新しく追加されたDrawingClassですが、例からも感じる通りもう一つ機能がほしい状態でした。
それでもいままで操作できなかった図形周りを動かせるということなので、もしいいつかい方をしたら教えていただけると幸いです。  
私も引き続きウォッチしていこうと思います。