Alexa APL, 第3回 背景に画像をつけてみる

#はじめに
画面付きのAlexa対応デバイスもだんだん増えてきました。
echo spot、echo show、Fire TVなど。
画面サイズに応じて、画面構成の変更も必要になることもあります。
そのための仕組みがAPLにも準備されています。
今回はその方法をまとめます。
Alexa APLの第2回で作成したスキルをベースに説明を記載しますが、内容は第1回がわかれば十分かと思います。

##今回実施する内容
Echo Spot、Echo Show 5、Echo Show用に背景画面をつける。

#環境
OS:Windows 10 JP
Alexaスキル言語：Node.js
Editor：Visual Studio Code
APLバージョン：1.0, 1.1

#参考
・[Alexa ハローAPL、Alexaスキルの画面への対応](https://qiita.com/Mount/items/72d9928ff2c0ae5de737)
第1回のAlexa APLの記事です。タイトル通り、ハローAPLを表示させるだけのAPLです。

・[APLトレーニングシリーズ第1回: 初めての Alexa Presentation Language (APL)](https://developer.amazon.com/ja/blogs/alexa/post/a3712152-cd02-4fda-9d33-3b64ef3a13af/jp-alexa-presentation-language-part1
)
AmazonのAlexa Blogsに画面非対応Echoへの対応の記載がありました。

#用語
##APL
Alexa Presentation Language
amazonの画面つきのAlexaの画面表示用の言語。
JSONを使用した記載方法です。
インターネットのホームページはHTMLとCSSで作成しますが、AlexaはAPLで作成するということです。

##APLオーサリングツール
APL作成を視覚的に見ながらAPLのJSONファイルを作成するツール。
サンプルテンプレートも準備されており、その中から選択していくだけで、だいたいの画面は作成できる。

#前提条件
前提条件はとくにないといえばないですが、本まとめを読むにあたり、以下がわかっていることが前提です。
・alexa developer consoleのアカウントがある
・Alexaスキルを開発したことがある
・JSONの記載方法を知っている
・「Alexa ハローAPL、Alexaスキルの画面への対応」の記事をみている

#マルチデバイスへ対応
##マルチデバイス対応では同じデザインが必要
[画面付きのAlexa搭載デバイスの表示の違い](https://developer.amazon.com/ja/docs/custom-skills/display-and-behavior-specifications-for-alexa-enabled-devices-with-a-screen.html#display-differences-among-alexa-enabled-devices-with-a-screen)によると、以下のように記載されています。

>すべての画面表示で同一のデザインにしてください。画面表示をデザインする際は、以下の特定の表示動作に留意してください。これらのデバイスを直接テストできない場合は、Alexaシミュレーターを使用してEcho ShowまたはEcho Spotをテストできます。

文脈飛ばして抜粋しましたが、画面表示をEcho SpotでもEcho showでも同じにする必要があるように思いました。
同じというのが、どこまでのことを示しているのかは定かではないですけど。

##画像を入れてみる
背景に方眼の画像をつけてみて、どういった見た目になるか確認します。
方眼のサイズは、以下の通りで、1024×600pxで、Echo showの解像度に合わせました。
また、マス目は、32×19マス目にしました。
![echo_show5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/232211f9-190c-f72b-10e3-36aaa2ffdf48.jpeg)

[Alexa ハローAPL、Alexaスキルの画面への対応](https://qiita.com/Mount/items/72d9928ff2c0ae5de737)で作成したJSONファイルとAPLオーサリングツールを使って、画像を追加してみます。

1. APLオーサリングツールで画像の読み込みを実施する。「スキルの表示方法」を選択する画面では、**コードをアップロード**を選択して、前回保存した「ハローAPL」が表示されるだけのJSONファイルを読み込む。
2. 「レイアウト画面」で、「Container」を選択し、「追加」ボタンを押して、「Add Component」ウィンドウで、「Image」を選択して、「{type}を追加」ボタンを押す。
すると、「Text」のしたに「Image」が階層として追加される。

    ![imageレイアウト.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/f9529b5d-bfcf-4390-d8bd-fa8844719bec.jpeg)

    コードは、以下の通り。

    ```json
    {
        "type": "APL",
        "version": "1.1",
        "settings": {},
        "theme": "dark",
        "import": [],
        "resources": [],
        "styles": {},
        "onMount": [],
        "graphics": {},
        "commands": {},
        "layouts": {},
        "mainTemplate": {
            "parameters": [
                "payload"
            ],
            "items": [
                {
                    "type": "Container",
                    "justifyContent": "center",
                    "items": [
                        {
                            "type": "Text",
                            "textAlign": "center",
                            "text": "${payload.hello.text}"
                        },
                        {
                            "type": "Image",
                            "source": "https://方眼目1_1024x600.jpg"
                        }
                    ]
                }
            ]
        }
    }
    ```

3. 「レイアウト画面」で「Image」を選択して、「詳細設定画面」の「source」に画像のリンクのURLを記載する。すると以下のようになりました。
    小型デバイス（Echo Spot用）
    ![show方眼目1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/986608ea-5b91-f6f0-7db8-91a254306f85.jpeg)
    中型デバイス（Echo Show用）
    ![spotの方眼目1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/fea99e86-4592-1859-0d4c-28b39c8953a6.jpeg)
解像度にあわせて画面表示するのかと思ったら、そうでもないようです。
このサイズは何を基準にしているのか？
amazonのドキュメントのどこかに記載があったような気がしますが、ちょっと今は見つかりませんでした。
また、ハローAPLの下に画像が入ってくるんですね。背景画像のイメージだったため、ちょっとイメージが違いました。デフォルトはコンポーネント順に縦に並ぶということなんですね。

##画像を背景になるようにしてみる
1. 幅と高さを調整するため、「レイアウト画面」で「Image」を選択して、「詳細設定画面」の「width」に「100vw」を、「height」に「100vh」を設定してみる。
    この「width」や「height」については、[APLコンポーネント](https://developer.amazon.com/ja/docs/alexa-presentation-language/apl-component.html)に説明があります。また、「100vw」や「100vh」は、[絶対ディメンジョン](https://developer.amazon.com/ja/docs/alexa-presentation-language/apl-data-types.html#absolute-dimensions)に説明があります。
要は、このImageの幅や高さを画面の幅や高さの100%に設定するということですね。
実はこれを実施すると、画像の比率には影響を与えないようで、画面がゆがむことはありません。しかし、1024x600pxの画像をEcho Spotにあてると、上下が以下のようにあいてしまいました。
また、ハローAPLの文字は、上のほうにいって切れてしまいました。
小型デバイス
![spot方眼目2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/72f6d513-cc84-9329-40ce-8d0d71f489d5.jpeg)

2. 「レイアウト画面」で「Image」を選択して、「position」に「absolute」を設定すると、「ハローAPL」は消えてしまいますが、画像は真ん中に位置するようになる。
「レイアウト画面」でのコンポーネントの記載潤に従って並ぶようで、画面が被るような場合は、どんどん上書きされるようです。したがって、「ハローAPL」の「Text」と「Image」を「レイアウト画面」で、ドラッグ＆ドロップで入れ替えてあげると、「Image」が背景になり、その上に「Text」がきて、「ハローAPL」が表示される。が文字は非常に見づらい。

3. 「レイアウト画面」で「Image」を選択して、「overlayColor」に「rgba(0,0,0, 0.6)」を設定すると、「Image」Imageが暗くなって、「ハローAPL」がよく見えるようになる。
rgbaは関数（hsl関数というらしい）で、赤、緑、青、アルファ（透明度）で色を設定し、上記だと、RGBが0で黒を示し、透明度が0.6でオーバーレイするということですね。「rgba(black, 0.6)」でも同じように表示されるのを確認しました。
[色](https://developer.amazon.com/ja/docs/alexa-presentation-language/apl-data-types.html#color)に説明があるのですが、わかりづらいかな。
小型デバイス
![spot方眼目3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/3e58686e-4aa7-70b0-dc51-b55aefb5a28f.jpeg)
縦方向が埋まらないのは想定と違います。

4. 「レイアウト画面」で「Image」を選択して、「scale」に「fest-fill」を設定する。すると以下のようになります。
小型デバイス
 ![spot方眼目4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/31b90f0e-9dfe-a80f-c9a6-005627536f43.jpeg)

    期待通りです。でも、どこか切り取っているんですよね。想像通りならば真ん中を切り取っているはず。
ということで、画像の真ん中を少し赤くした画像ファイルを作って改めて表示してみると、以下のようになりました。
赤い部分は、480×480pxよりは小さくしてあります。
小型デバイス（Echo Spot）
    ![spot方眼目5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/4322bce1-2476-eb95-cab4-0ac359d8a821.jpeg)
小型デバイス（Echo Show 5）
![show2方眼目2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/2963add9-1197-d931-1fdc-a54cb19a38a7.jpeg)
中型デバイス
    ![show方眼目2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/532a0065-aa70-6cf1-e555-bd0fcb8267b0.jpeg)

なるほど、「画像の真ん中に設定している」ということですね。
これで、「Echo Spot」、「Echo Show 5」、「Echo Show」で画面いっぱいに表示されます。
「Echo Show」ではしっかり画面一杯画像を表示するのかと思ったら、若干端の画像が切れているような気がしました。
数pxは消えるのかもしれません。
また、背景画像はマルチデバイスで切り取られるのを理解したうえで、柄のようなどこをとってもいいようなものがいいのかなと思いました。

最後にAPLソースコードを載せます。

```json:
{
    "document": {
        "type": "APL",
        "version": "1.1",
        "theme": "dark",
        "import": [],
        "settings": {},
        "resources": [],
        "styles": {},
        "onMount": [],
        "graphics": {},
        "commands": {},
        "layouts": {},
        "mainTemplate": {
            "parameters": [
                "payload"
            ],
            "items": [
                {
                    "type": "Container",
                    "justifyContent": "center",
                    "items": [
                        {
                            "type": "Image",
                            "width": "100vw",
                            "height": "100vh",
                            "source": "https://方眼目1_1024x600.jpg",
                            "scale": "best-fill",
                            "overlayColor": "rgba(0,0,0, 0.6)",
                            "position": "absolute"
                        },
                        {
                            "type": "Text",
                            "textAlign": "center",
                            "text": "${payload.hello.text}"
                        }
                    ]
                }
            ]
        }
    },
    "datasources": {
        "hello": {
            "text": "ハローAPL"
        }
    }
}
```

##設定値をもう少しいじってみる
ここからはおまけです。
###scaleをいじる
amazonのAPLの[scale](https://developer.amazon.com/ja/docs/alexa-presentation-language/apl-image.html#scale)によると、scaleには、以下の5つの設定があるようです。

- none
- fill
- best-fill　（デフォルト)
- best-fit
- best-fit-down
 
でも、APLオーサリングツール上で、「Image」の「scale」には、以下の通り8つの設定があります（適当な文字列をいれるとエラーになって以下のものをいれるように指示される）。

- fill
- best-fill
- best-fit　（デフォルト）
- best-fit-down
- none
- contain
- cover
- scale-down

この違いはなぜなのかわかりませんが、APLがv1.1になったせいなのかもしれません。
でも、[Changes Introduced in APL Version 1.1](https://developer.amazon.com/ja/docs/alexa-presentation-language/apl-latest-version.html)にそれっぽいことは書いていないようで、不明です。
デフォルト値も変わっていますが、「best-fit」になっているように思います。
私の持っているEcho show 5の実機で、「scale」に何も入れないで試したところ、以下にようになりました。やはり「best-fit」のようです。
![show2方眼目1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/ca3f21f2-214d-3e0b-c4ef-a61bbe373f84.jpeg)

もしかすると、古いEcho showなどでは、新しい値を使えないかもしれないので注意する必要がありそうです。時間があれば少し調べようと思いますが、APLオーサリングツールだと動作してしまっているようなので、私の環境では調べきれないかもしれません。
また、上記の値についても説明読むだけではよくわからないことも多いため、設定値と表示サンプルを出すといいかなと思いました。
この辺は今回記載しませんが、そのうち記事を記載するかもしれません。

###alignをいじる
「scale」の説明を読むと、さきほど「画像の真ん中に設定している」と書いた内容について説明があり、「align」で調整するようなのです。
amazonのAPLの[align](https://developer.amazon.com/ja/docs/alexa-presentation-language/apl-image.html#align)によると、alignには、以下の9つの設定があるようです。

- left
- right
- center
- top
- bottom
- top-left
- top-right
- bottom-left
- bottom-right

これは、APLオーサリングツールでも同じ内容でした。

では、「scale」に「best-fill」を設定して、「align」に「left」を設定すると、期待通り画像の左側が表示されるようになりました。
![spot方眼目6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/e9f91500-26ab-3507-0b3a-bc2adce21ba6.jpeg)

でも、「align」に「top-left」を設定すると、今回の場合ならば「left」と同様になるのかと思ったら、そうでもなく、「center」相当の動作と思いました。「bottom-left」にしたら、期待通り「left」と同じでした。
![spot方眼目5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/d12c7afe-01e6-22e1-6712-6008a9500738.jpeg)

なんか、癖がありそうですね。開発時は画面の動きをよく把握しながらやっていかないとはまりそうですね。

#おわりに
今回は、背景に画像をつけてみました。ポイントだけ簡潔に記載します。

- 背景画像は、Containerの一番最初に設定するのがよい（レイアウトは上から順に設定されるため）
- 背景画像は、「position」に「absolute」を設定し、他のContainerと位置関係を関連付けない。
- 背景画像は、「width」と「height」に「100vw」、「100vh」を設定するのがよい。
- 背景画像は、「overlayColor」を設定して文字を見やすくする。
- 背景画像は、「scale」に「best-fill」を使って、画面一杯に設定する。
- 背景画像は、繰り返しの柄のようなものがよく、どこをきりとってもよいものにする。

本当はマルチデバイス対応でデバイスに応じた画面レイアウトなどを記載しようと思ったのですが、思ったよりも長くなったため、いったん記事を切ります。
次回は、「マルチデバイス対応」か、「上記で期待とは違った動作」について記載していこうかと思います。

それにしても、画面開発は、ドキュメントに書いてある内容と動作が期待に反することもありますし、そもそもドキュメントと設定値が違うこともあるようです。
Alexaのスキル開発がまだまだ発展途上だということだと思います。
いったん、画面を作っても、その動作がずっと保証されるかどうかも疑わしいなとも思いましたので、動作が違うからと、その癖を悪用というか信じて、面倒な実装はしないように気をつけたほうがよさそうですね。