データバインディングコンテキストのViewportオブジェクト
Alexa Presentation Language(APL)ドキュメントのデータバインディングコンテキストには、表示デバイスの動作特性を示すviewportプロパティが含まれています。
viewportプロパティは、APLドキュメントでデータバインディングコンテキストの一部として使用できます。これはスキルに送信されたリクエストに含まれるViewport情報とは別のもので、こちらの情報にはスキルコードからアクセスできます。Viewportオブジェクトの例
たとえば、初代のEcho ShowのViewportオブジェクトでは次のプロパティが報告されます。
{
"viewport": {
"width": 1024,
"height": 600,
"pixelWidth": 1024,
"pixelHeight": 600,
"shape": "rectangle",
"dpi": 160,
"theme": "dark",
"mode": "hub",
"autoHeight": false,
"autoWidth": false,
"minHeight": 600,
"minWidth": 1024,
"maxHeight": 600,
"maxWidth": 1024
}
}
ドキュメントで条件付きロジックを使用することで、Viewportに応じて異なるエクスペリエンスを提供できます。
プロパティ
viewportオブジェクトには、次の表に示すプロパティがあります。
| プロパティ | 型 | 説明 |
|---|---|---|
|
|
ブール値 |
|
|
|
ブール値 |
|
|
|
整数 |
Viewportのピクセル密度です。 |
|
|
正のディメンション |
デフォルトの高さをディスプレイ非依存ピクセル(dp)単位で示します。 |
|
|
正のディメンション |
最大の高さをディスプレイ非依存ピクセル(dp)単位で示します。 |
|
|
正のディメンション |
最大の幅をディスプレイ非依存ピクセル(dp)単位で示します。 |
|
|
正のディメンション |
最小の高さをディスプレイ非依存ピクセル(dp)単位で示します。 |
|
|
正のディメンション |
最小の幅をディスプレイ非依存ピクセル(dp)単位で示します。 |
|
|
モード |
動作モードです。 |
|
|
整数 |
デフォルトの高さをピクセル単位で示します。 |
|
|
整数 |
デフォルトの幅をピクセル単位で示します。 |
|
|
有効な値: |
Viewportの形状です。 |
|
|
文字列 |
選択されている色スキーマです。 |
|
|
正のディメンション |
デフォルトの幅をdp単位で示します。 |
autoHeight
trueの場合、APLドキュメントの高さはminHeightからmaxHeightまでの範囲で調整される可能性があります。falseの場合、Viewportは常に正確にheightの高さになります。
autoHeightプロパティは、Viewportの高さが可変かどうかをすばやく確認できる便利なプロパティです。このプロパティは${viewport.height != viewport.maxHeight || viewport.height != viewport.minHeight}と同じです。
autoWidth
trueの場合、APLドキュメントの幅はminWidthからmaxWidthまでの範囲で調整される可能性があります。falseの場合、Viewportは常に正確にwidthの幅になります。
autoWidthプロパティは、Viewportの幅が可変かどうかをすばやく確認できる便利なプロパティです。このプロパティは${viewport.width != viewport.maxWidth || viewport.width != viewport.minWidth}と同じです。
dpi
ディスプレイ非依存ピクセル(dp)は、携帯電話を見るときの距離で画面を持ち、画面のピクセル密度が1インチ(3cm)あたり約160ピクセルであると仮定した場合の画面のビジュアルサイズを表す測定単位です(初代iPhoneの画面では1インチあたり163ピクセルでした)。物理的な大きさが同じ2つの画面を同じ距離から見た場合、画面の実際のピクセル密度にかかわらず、2つの画面のdpディメンションはほぼ同じになります。
Viewportのdpi(インチあたりのドット数)とは、人が見たとおりのポイントまたはピクセルのサイズを表した値であり、画面の実際のインチあたりのピクセル数とは異なります。dpiを求める公式は次のとおりです。
dpi = 160 *(ピクセルサイズ / dpサイズ)
サポートされているDPIの値は、 120、160、213、240、320、480、640です。
実際には、画面のdpiサイズは物理的な寸法と想定される視聴距離に基づいてメーカーによって選択され、そのdpiを基にdpサイズが計算されます。たとえば、1080pのテレビでメーカーが推奨する視聴距離は、実際の画面サイズにかかわらず、テレビ画面の対角線の長さの約2倍です。視聴者に対するテレビの見た目の大きさは一定のため、すべての1080pのテレビはdpiが320、pixelHeightが1080、heightが540になります。
height
Viewportのheightプロパティは、Viewportの推奨される高さ(ディスプレイ非依存ピクセル単位)です。autoHeightがfalseの場合、この高さが厳密に適用されます。画面上でViewportが占める高さは、指定されたとおりの値になります。autoHeightがtrueの場合、この高さは推奨されるデフォルト値ですが、実際の高さはminHeightからmaxHeightまでの範囲で変わる可能性があります。Viewport内に表示されるAPLドキュメントは、Viewportの境界で切り抜かれます。
サイズに関する各プロパティが互いにどのように影響するかの詳細については、Viewportのサイズについてを参照してください。
maxHeight
ViewportのmaxHeightプロパティは、Viewportで許容される最大の高さ(ディスプレイ非依存ピクセル単位)です。autoHeightがfalseの場合、Viewportのheightと同じになります。
サイズに関する各プロパティが互いにどのように影響するかの詳細については、Viewportのサイズについてを参照してください。
maxWidth
ViewportのmaxWidthプロパティは、Viewportで許容される最大の幅(ディスプレイ非依存ピクセル単位)です。autoWidthがfalseの場合、Viewportのwidthと同じになります。
サイズに関する各プロパティが互いにどのように影響するかの詳細については、Viewportのサイズについてを参照してください。
minHeight
ViewportのminHeightプロパティは、Viewportで許容される最小の高さ(ディスプレイ非依存ピクセル単位)です。autoHeightがfalseの場合、この値はViewportのheightと同じになります。
サイズに関する各プロパティが互いにどのように影響するかの詳細については、Viewportのサイズについてを参照してください。
minWidth
ViewportのminWidthプロパティは、Viewportで許容される最小の幅(ディスプレイ非依存ピクセル単位)です。autoWidthがfalseの場合、Viewportのwidthと同じになります。
サイズに関する各プロパティが互いにどのように影響するかの詳細については、Viewportのサイズについてを参照してください。
mode
modeプロパティは、想定されるデバイスの用途を表します。modeプロパティは、次のいずれかの値を返します。
| 値 | 説明 | 一般的な入力方法 | 例 |
|---|---|---|---|
auto |
車内で運転手によって使用されます。 | タッチ | 自動車のダッシュボード、航空機搭載用ディスプレイ |
hub |
卓上型または据え置き型のデバイスです。 | タッチ(近くにいるとき) | Amazon Echo Show、キッチン家電 |
mobile |
ユーザーが持ち運べる携帯デバイスです。 | タッチ | 携帯電話、タブレットコンピューター |
pc |
デスクトップコンピューターまたはノートパソコンです。 | キーボード、マウス、トラックパッド | デスクトップコンピューター、ノートパソコン |
tv |
テレビまたは投影型ディスプレイです。 | リモコン | テレビ、電子広告板 |
上の表に記載されている入力方法は代表的な例であり、特定のデバイスモードに必ずしも当てはまるとは限りません。
1台のデバイスが、さまざまな状況に応じて異なるモードで報告されることもあります。たとえば、タブレット型コンピューターは、ほとんどの場合はmobileデバイスとして報告されますが、ドッキングステーションに接続しているときはhubデバイスとして報告されます。近接するデバイスから異なるモードが報告されることもよくあります。たとえば、自動車の場合、ダッシュボードに組み込まれているデバイスはauto、後部座席の天井に設置されたデバイスはtv、同乗者が所持する携帯電話はmobileになります。
モードのリストは変更される可能性があります。modeを条件付きロジックで使用する場合は、認識できない値がプロパティから返される可能性があることを想定に入れてください。モードに依存するプロパティやコンポーネントには、常にデフォルトの定義を指定してください。
pixelHeight
pixelHeightプロパティは、Viewportのheightをピクセル単位で表します。これは${viewport.height * viewport.dpi / 160}と同じです。pixelHeightプロパティは、適切な表示用ビットマップを選択するときに便利なように提供されています。
pixelWidth
pixelWidthプロパティは、Viewportのwidthをピクセル単位で表します。これは${viewport.width * viewport.dpi / 160}と同じです。pixelWidthプロパティは、適切な表示用ビットマップを選択するときに便利なように提供されています。
shape
画面のshapeは、roundまたはrectangleを返します。
theme
themeには、デバイスで使用されている基本色スキーマが反映されます。themeは文字列値です。APLドキュメントのthemeプロパティでテーマを設定できます。ドキュメントで設定されていない場合は、デバイスによって「light」または「dark」に設定されます。
light: 明るい背景に暗いテキストdark: 暗い背景に明るいテキスト
themeは、ドキュメントまたはパッケージでスタイルを定義するときに使用できます。次の例は、themeに基づいて調整される2つのスタイルを示しています。
{
"styles": {
"styledText": {
"values": [
{
"color": "${viewport.theme == 'dark' ? 'white' : 'black'}"
}
]
},
"styledFrame": {
"values": [
{
"backgroundColor": "${viewport.theme == 'dark' ? '#096484' : '#74B6CF'}"
}
]
}
}
}
ドキュメントでは、テーマを完全に無視することも、デバイスが提供する値をカスタムテーマでオーバーライドすることもできます。たとえば、以下のドキュメントではカスタムの「fancy」テーマを作成しています。themeプロパティの値を変更して、テキストの色が変わることを確認してください。
このアプローチを使用すると、スタイルとリソースが別のAPLパッケージに分離されている場合に柔軟に対応できます。テーマを1つ選択するだけで、カスタマイズしたさまざまなデザインを簡単に切り替えることができます。
Viewportのサイズについて
viewportオブジェクトには、APLドキュメントの描画サイズを定義する高さのプロパティ(autoHeight、height、minHeight、maxHeight)と幅のプロパティ(autoWidth、width、minWidth、maxWidth)があります。
通常、Viewportは固定サイズです。たとえば、Viewportのサイズが画面のサイズに固定されたAlexaデバイスでは、APLドキュメントが全画面に表示される可能性があります。
次の例は、1280x1024、320dpiの画面にAPLドキュメントが全画面表示されるviewportオブジェクトを示しています。
"viewport": {
"autoHeight": false, // 高さは固定
"autoWidth": false, // 幅は固定
"dpi": 320,
"height": 512, // 1024ピクセル @ 320dpi = 512dp
"maxHeight": 512, // heightと同じ
"maxWidth": 640, // widthと同じ
"minHeight": 512, // heightと同じ
"minWidth": 640, // widthと同じ
"pixelHeight": 1024,
"pixelWidth": 1280,
"shape": "rectangle",
"width": 640 // 1280ピクセル @ 320dpi = 640
}
場合によっては、Viewportのサイズの高さや幅が可変になることもあります。このようなViewportでは、autoHeightプロパティまたはautoWidthプロパティがtrueとして報告されます。
たとえば、高さが400dpに固定されたAPLドキュメントが表示されていて、ドキュメントの幅は200dp~600dpの間で変わる可能性があるとします。この場合、Viewportオブジェクトは次のように報告されます。
"viewport": {
"autoHeight": false, // 高さは固定
"autoWidth": true, // 幅は可変
"dpi": 320,
"height": 400, // 高さは400dpに固定
"maxHeight": 400, // heightと同じ
"maxWidth": 600, // 最大の幅は600dp
"minHeight": 400, // heightと同じ
"minWidth": 200, // 最小の幅は200dp
"pixelHeight": 800, // 400dp @ 320dpi = 800ピクセル
"pixelWidth": 800, // 400dp @ 320dpi = 800ピクセル(デフォルトの幅)
"shape": "rectangle",
"width": 400 // デフォルトの幅は400dp
}
APLが可変Viewportでのトップレベルコンポーネントのサイズをどのように計算するかの詳細については、Viewportのレイアウトを理解するを参照してください。
コンポーネントはViewportのサイズと一致しなくても構わない
ビュー階層のトップレベルコンポーネントのサイズは、Viewportのサイズと一致しなくても構いません。サイズが一致しない場合、クリッピングが発生するか空白の領域が表示されます。コンポーネントの左上隅はViewportの左上隅に揃えられます。たとえば、サイズが640dp x 512dpに固定されているViewportに次のAPLドキュメントを表示するとします。
"mainTemplate": {
"item": {
"type": "Frame",
"width": 2000,
"height": "50vh",
"backgroundColor": "green"
}
}
トップレベルのFrameは、幅が2000dpで高さが256dpですが、640x512のViewportの境界内に表示されます。デバイスはドキュメントの下に空白の領域を表示し、ドキュメントの背景が設定されている場合はその背景で塗りつぶします。Frameの右側は画面の端から外れて見えなくなります。
Viewportの高さと幅には現在の画面の向きが反映される
Viewportの高さと幅には、現在の画面の向きが反映されます。1024x768ピクセルの画面を持つタブレットコンピューターで全画面のAPLドキュメントを表示している場合、ViewportのpixelWidthは、縦向きモードでは768、横向きモードでは1024として報告されます。画面の回転はAPLドキュメントに報告されません。
Viewportのレイアウトを理解する
このセクションでは、ViewportのサイズとAPLドキュメントのトップレベルコンポーネントのサイズがどのように相互に作用するかを説明します。次の定義を確認してください。
- Viewport - APLランタイムによって定義されます。Viewportは、APLドキュメントがレンダリングされる領域を表します。
- トップレベルコンポーネントのサイズ - APLドキュメントで定義されます。ドキュメント内のほかのすべてのコンポーネントは、トップレベルコンポーネントの境界に合わせて切り抜かれます。トップレベルコンポーネントは多くの場合
Containerですが、任意のコンポーネントにすることができます。
幅と高さの計算には同じアルゴリズムが使用されます。以下のセクションでは、APLによるViewportとトップレベルコンポーネントの出力幅の計算方法を説明します。Viewportとトップレベルコンポーネントの出力高さも同じように計算されます。
ここで説明しているアルゴリズムは、実際のFlexbox Box Layout ModuleとCSS Box Sizing Moduleのロジックを簡略化したものです。詳細については、これらのドキュメントを参照してください。
このセクションでは、Viewportとコンポーネントのプロパティが適切に定義されていることを前提としています。つまり、次のルールに従っている必要があります。
viewport.minWidth <= viewport.width <= viewport.maxWidth (両方が定義されている場合)
component.minWidth <= component.width <= component.maxWidth(両方が定義されている場合)
これらのプロパティが適切な大小関係になっていない場合の相互作用については、CSS Box Sizing Moduleの仕様を参照してください。
固定Viewport
ほとんどのAPLランタイムでは、固定サイズのViewportにドキュメントが配置されます。固定Viewportでは、Viewportのwidth、minWidth、maxWidthが同じ値になります。
viewport.minWidth == viewport.width == viewport.maxWidth
viewport.autoWidth = false
トップレベルコンポーネントの出力幅は、以下のルールにより、コンポーネントのwidth、minWidth、maxWidthの各プロパティを使用して決定されます。
コンポーネントの幅が絶対ディメンションの場合
コンポーネントのwidthが絶対ディメンションの場合、出力幅は、指定されたwidthの値を、コンポーネントのmaxWidthプロパティとminWidthプロパティの範囲に制限した値になります。Viewportのサイズは計算に使用されません。絶対ディメンションの例として、25px、10vw、30などの値があります。
以下は、この計算を示す擬似コードです。
if TypeOf( component.width ) == AbsoluteDimension:
w = Clamp( component.width, component.minWidth, component.maxWidth )
component.output.width = w
Layout( component, width=w )
コンポーネントの幅が相対ディメンションの場合
コンポーネントのwidthが相対ディメンションの場合、出力幅は、コンポーネントのwidthとViewportのwidthの積を、コンポーネントのmaxWidthとminWidthの範囲に制限した値になります。相対ディメンションの例として、25%や50%などの値があります。
以下は、この計算を示す擬似コードです。
if TypeOf( component.width ) == RelativeDimension:
w = component.width * viewport.width
w = Clamp( w, component.minWidth, component.maxWidth )
component.output.width = w
Layout( component, width=w )
コンポーネントの幅がautoの場合
コンポーネントのwidthがautoの場合、出力幅はmaxWidthに値が設定されているかどうかによって変わります。maxWidthに値がある場合、コンポーネントはその子を厳密にラップし、出力幅をコンポーネントのmaxWidthとminWidthの範囲に制限します。maxWidthに値がない場合、コンポーネントはViewport全体を占有します。
以下は、この計算を示す擬似コードです。
if TypeOf( component.width ) == AutoDimension:
if IsDefined( component.maxWidth ):
w = Layout( component, width=Undefined ).getWidth()
w = Clamp( w, component.minWidth, component.maxWidth )
else:
w = viewport.width
component.output.width = w
Layout( component, width=w )
上記の3つのどのシナリオでも、トップレベルコンポーネントの出力幅は、Viewportのwidthよりも小さくなる可能性があります。APLは、コンポーネントの左上隅をViewportの原点(左上隅)に配置します。コンポーネントの出力幅がViewportのwidthよりも大きい場合は、Viewportによってコンポーネントの右側が切り取られます。コンポーネントの出力幅の方が小さい場合は、Viewportの右側にドキュメントのbackgroundが表示されます。
可変Viewport
一部のAPLランタイムは、可変サイズのViewportをサポートしています。可変Viewportでは、幅と高さの一方または両方が、APLドキュメントのサイズに合わせて拡大または縮小されます。たとえば、APLドキュメントの水平リストを表示するランタイムでは、個々のドキュメントの幅を可変にして、一部のドキュメントの領域を水平方向に広げることができます。可変Viewportでは、width、minWidth、maxWidthの値がそれぞれ異なります。
viewport.minWidth <= viewport.width <= viewport.maxWidth
viewport.minWidth < viewport.maxWidth
viewport.autoWidth = true
最終的なViewportの出力幅は、[minWidth, maxWidth]の範囲内になります。
Viewportのwidthは、Viewportのデフォルトの出力幅を表します。この値は次の2つの方法で使用されます。
- コンポーネントの
widthが相対ディメンションに設定されている場合、Viewportの出力幅はViewportのwidthに固定されます。通常、コンポーネントのwidthは100%です。これは、コンポーネントをViewportのデフォルトの幅に合わせることを示しています。 - APLドキュメント内のリソース計算では、通常、Viewportのサイズに依存するリソースを定義するときにViewportの
widthを使用します。リソース値はドキュメントが最初に読み込まれるときに計算されますが、その時点では、Viewportの最終的な出力幅はまだ計算されていません。このため、計算にはViewportのデフォルトの幅が便利な基準値として使用されます。
トップレベルコンポーネントの出力widthとViewportの出力widthは、以下のルールにより、トップレベルコンポーネントのwidth、minWidth、maxWidthの各プロパティから決定されます。
トップレベルコンポーネントの出力幅は、以下のルールにより、コンポーネントのwidth、minWidth、maxWidthの各プロパティを使用して決定されます。
コンポーネントの幅が絶対ディメンションの場合
コンポーネントのwidthが絶対ディメンションの場合、コンポーネントの出力幅は、コンポーネントの[minWidth, maxWidth]の範囲に制限されます。Viewportの出力幅は、コンポーネントの出力幅をViewportの[minWidth, maxWidth]の範囲に制限した値になります。絶対ディメンションの例として、25px、10vw、30などの値があります。
以下は、この計算を示す擬似コードです。
if TypeOf(component.width) == AbsoluteDimension:
w = component.width
w = Clamp( w, component.minWidth, component.maxWidth )
component.output.width = w
viewport.output.width = Clamp( w, viewport.minWidth, viewport.maxWidth )
Layout( component, width=w )
次に例を示します。
前提 Viewport: { minWidth: 100, width: 200, maxWidth: 300 }
コンポーネント:{ minWidth: 0, width: 250, maxWidth: Undefined }
結果 viewport.output.width = 250
component.output.width = 250
コンポーネントの幅が相対ディメンションの場合
コンポーネントのwidthが相対ディメンションの場合、コンポーネントの出力幅は、コンポーネントのwidthとViewportのwidthの積を、コンポーネントの[minWidth, maxWidth]の範囲に制限した値になります。Viewportの出力幅はViewportのwidthになります。
以下は、この計算を示す擬似コードです。
if TypeOf(component.width) == RelativeDimension:
w = component.width * viewport.width
w = Clamp( w, component.minWidth, component.maxWidth )
component.output.width = w
viewport.output.width = viewport.width
Layout( component, width=w )
次に例を示します。
前提 Viewport: { minWidth: 100, width: 200, maxWidth: 300 }
コンポーネント:{ minWidth: 0, width: "80%", maxWidth: 150 }
結果 viewport.output.width = 200
component.output.width = 150
相対ディメンションを100%よりも小さく設定すると、Viewportの右側に背景が表示されます。相対ディメンションを100%よりも大きく設定すると、コンポーネントの右側が切り取られます。
Viewportとコンポーネントの両方をデフォルトのViewportサイズから一定の割合だけ拡大縮小する場合は、Viewportの幅を参照する絶対ディメンションを使用します。たとえば、コンポーネントとViewportをデフォルトのViewportのwidthから25%拡大するには、コンポーネントのwidthを125vwに設定します。この値はViewportのwidthの125%に相当する絶対ディメンションであるため、絶対ディメンションのルールに従います。
コンポーネントの幅が「auto」の場合
コンポーネントのwidthがautoの場合、出力幅はmaxWidthに値が設定されているかどうかによって変わります。maxWidthに値がある場合、コンポーネントはその子を厳密にラップし、出力幅をコンポーネントのmaxWidthとminWidthの範囲に制限します。maxWidthに値がない場合、コンポーネントはViewport全体を占有します。
コンポーネントのwidthがautoの場合、レイアウトエンジンは、コンポーネントの内部要素を「自然」な幅でレイアウトすることで、コンポーネントに対する中間的なViewportの出力幅を計算します。次に、その中間Viewportの出力幅を、コンポーネントの[minWidth, maxWidth]の範囲とViewportの[minWidth, maxWidth]の範囲に制限します。制限を適用した値がコンポーネントの出力幅として設定され、コンポーネントが再度レイアウトされます。
以下は、この計算を示す擬似コードです。
if TypeOf(component.width) == AutoDimension:
w = Layout( component, width=Undefined ).getWidth()
w = Clamp( w, component.minWidth, component.maxWidth )
w = Clamp( w, viewport.minWidth, viewport.maxWidth )
viewport.output.width = w
Layout( component, width=w )
たとえば、トップレベルコンポーネントが、長いテキストの段落を含むTextコンポーネントであるとします。
前提 Viewport: { minWidth: 100, width: 200, maxWidth: 300 }
コンポーネント:{ minWidth: 0, width: auto, maxWidth: Undefined }
テキストの合計幅(単一行)= 430
結果 viewport.output.width = 300
component.output.width = 300
コンポーネントのwidthプロパティがautoに設定されているため、レイアウトアルゴリズムの実行が2回必要になります。最初に、コンポーネントの内部要素が「自然」な幅であるという想定で、コンポーネントがレイアウトされます。Textコンポーネントの自然な幅は、単一行にレイアウトされたテキストの幅です(この例では430)。次に、この幅が、Viewportによって指定された有効な幅の範囲に制限されます(この例では300)。最後に、この値に幅を固定した状態で、コンポーネントが再度レイアウトされます。この2回目のレイアウトパスでは、テキストが複数行に折り返されます。
コンポーネントの幅と高さが両方とも「auto」の場合
Viewportの幅と高さが両方とも可変で、トップレベルコンポーネントのwidthプロパティとheightプロパティが両方ともautoの場合、APLは次のアルゴリズムを使用します。
if TypeOf(component.width) == AutoDimension AND TypeOf(component.height) == AutoDimension:
// Viewportの幅を計算します。
w = Layout( component, width=Undefined, height=Undefined ).getWidth()
w = Clamp( w, component.minWidth, component.maxWidth )
w = Clamp( w, viewport.minWidth, viewport.maxWidth )
viewport.output.width = w
// Viewportの高さを計算します。
h = Layout( component, width=w, height=Undefined ).getHeight()
h = Clamp( h, component.minHeight, component.maxHeight )
h = Clamp( h, viewport.minHeight, viewport.maxHeight )
viewport.output.height = h
// 最終的な幅と高さでレイアウトします。
Layout( component, width=w, height=h )
最初のレイアウトパスは、Viewportの出力幅を計算します。2回目のレイアウトパスは、Viewportの出力高さを計算します。最後のレイアウトパスは、Viewportの出力幅と出力高さを使用してコンポーネント階層をレイアウトします。
関連トピック
最終更新日: 2025 年 11 月 26 日