【Fuse】スプラッシュスクリーンをつくろう

今回は[こちら](https://www.fusetools.com/docs/tutorial/splash-screen)のページに沿って進めていきます。
 
###イントロ

前回は`ux:Class`を使って、既存のコンポーネントをカスタマイズし、自作のコンポーネントを利用してアプリの見た目を整えました。

今回は最後のページとなるスプラッシュスクリーンを追加し、アプリを完成させます。スプラッシュスクリーンはアプリ起動後に立ち上がる画面で、ユーザーの気分をそのアプリの雰囲気とマッチさせます。前のチュートリアルまででやってきたことを最大限生かしながらつくっていきます。

###スプラッシュスクリーンを構築する
まずは見た目をつくっていきます。`Page`ディレクトリに`SplashPage.ux`ファイルを作成してください。

```SplashPage.ux
<Page ux:Class="SplashPage">
</Page>
```

前回作成した`hikr.Page`クラスを使用していないのは、背景に画像ではなく動画を指定する予定だからです。後で追加するので、それまでは単一の背景色を適用します。

ページを作成したら、`Navigator`にそのテンプレートを追加しましょう。また、スプラッシュスクリーンは最初に表示される画面となるので、`DefaultPath`も変えておきます。

```MainView.ux
<Navigator DefaultPath="splash">
	<SplashPage ux:Template="splash" />
	<HomePage ux:Template="home" router="router" />
	<EditHikePage ux:Template="editHike" router="router" />
</Navigator>
```

ライブリロードでは、Fuseが履歴をキャッシュしているので、この状態でプレビューしても、起動後にスプラッシュスクリーンが出ないかもしれません。一度プレビューを閉じて再度実行してみてください。

スプラッシュスクリーンのデザインは下記です。

![splash.png](https://qiita-image-store.s3.amazonaws.com/0/100937/6bb4b4c3-aba6-9aef-b376-23e2600ccba7.png)
※公式サイトより

######スプラッシュスクリーンとは言ってますが、これが本当のホーム画面のような気が…

必要なのは、タイトル、キャッチコピーと開始ボタンです。画面の上半分と下半分にわけ、それぞれの中央に配置されています。なのでまずはページを上下二つに分けて、タイトルを配置しましょう。センターに表示されるように`Alignment`プロパティも追加し、`FontSize`も指定しましょう。

```SplashPage.ux
<Page ux:Class="SplashPage">
	<Router ux:Dependency="router" />
	<Grid RowCount="2">
		<StackPanel>
			<hikr.Text Alignment="HorizontalCenter" FontSize="70">hikr</hikr.Text>
		</StackPanel>
	</Grid>
</Page>
```

続いて、タイトルの下に置くテキストを配置します。こちらもいくつかプロパティを設定します。

```SplashPage.ux
<StackPanel>
	<hikr.Text Alignment="HorizontalCenter" FontSize="70">hikr</hikr.Text>
	<hikr.Text Alignment="HorizontalCenter" Opacity=".5">get out there</hikr.Text>
</StackPanel>
```

最後に縦の中央ぞろえを親の`StackPanel`に指定します。

```SplashPage.ux
<StackPanel Alignment="VerticalCenter">
	<hikr.Text Alignment="HorizontalCenter" FontSize="70">hikr</hikr.Text>
	<hikr.Text Alignment="HorizontalCenter" Opacity=".5">get out there</hikr.Text>
</StackPanel>
```

続いて、スタートボタンを追加します。前回作成した`hikr.Button`を使いましょう。余白やフォントサイズも調整します。

```SplashPage.ux
<Grid RowCount="2">
	<StackPanel Alignment="VerticalCenter">
		<hikr.Text Alignment="HorizontalCenter" FontSize="70">hikr</hikr.Text>
		<hikr.Text Alignment="HorizontalCenter" Opacity=".5">get out there</hikr.Text>
	</StackPanel>
	<hikr.Button Text="Get Started" FontSize="18" Margin="50,0" Alignment="VerticalCenter" />
</Grid>
```

自作した`hikr.Button`は`<Button>`ではなく、`<Panel>`から作られています。なので`FontSize`プロパティは持っていませんでした。でも大丈夫です。`Text`プロパティを追加したように、`FontSize`も追加しましょう。`<Text>`プロパティを追加するときは`<string>`を使いましたが、`FontSize`は数値なので、`<float>`を使いましょう。参照する側も修正します。

```hikr.Button.ux
<Panel ux:Class="hikr.Button" Margin="10" Padding="10">
    <string ux:Property="Text" />
    <float ux:Property="FontSize" />
    ...
    
    <hikr.Text Value="{ReadProperty Text}" FontSize="{ReadProperty FontSize}" TextAlignment="Center" />
    ...
```
これで、`FontSize`を自由に設定することができるようになりました。でも、ちょっと待ってください。今までこのコンポーネントを使用してきた箇所では、`FontSize`を指定していません。なので、デフォルトの値をセットしましょう。デフォルトの値は親となる`Panel`に設定します。

```hikr.Button.ux
<Panel ux:Class="hikr.Button" Margin="10" Padding="10" FontSize="16">
```

こうすることで、インスタンス時に指定しなかった場合は16が指定されます。

つづいて、ボタンを押した時にホームページ画面に進む機能を実装し、設定します。`Pages`ディレクトリの中に、`SplashPage.js`を作り、`goToHomePage`という関数を作ります。

```SplashPage.js
function goToHomePage() {
}

module.exports = {
	goToHomePage: goToHomePage
}
```

`.ux`のほうでこのJSを読み込み、ボタンの`Clicked`イベントに設定します。

```SplashPage.ux
<Page ux:Class="SplashPage">
    <JavaScript File="SplashPage.js" />

    <Grid RowCount="2">
    	...
    	
    	<hikr.Button Text="Get Started" FontSize="18" Margin="50,0" Alignment="VerticalCenter" Clicked="{goToHomePage}" />
    	
```
あとは、画面遷移に必要な`Dependency`などを追加していきます。

```SplashPage.ux
<Page ux:Class="SplashPage">
	<Router ux:Dependency="router" />
	<JavaScript File="SplashPage.js" />
```

```MainView.ux
<Navigator DefaultPath="splash">
	<SplashPage ux:Template="splash" router="router" />
	<HomePage ux:Template="home" router="router" />
	<EditHikePage ux:Template="editHike" router="router" />
</Navigator>
```
最後に、関数の中身を記述します。

```SplashPage.js
function goToHomePage() {
	router.push("home");
}
```

実際はこの画面に戻ることは想定できないので、"push"ではなく、"goto"を使うのが一般的でしょう。開発中はとりあえず"push"にしておきます。

###ビデオ背景をつける

最初に言ったように、スプラッシュスクリーンの背景には動画を使いたいと思います。動画素材は[こちら](https://github.com/fusetools/hikr/blob/master/Assets/nature.mp4)。

さて、この動画は[Graham Uhelski](https://vimeo.com/mankindfilms)さんの、["The Valley"](http://mazwai.com/#/videos/220)という作品です。ライセンスが[CC BY 3.0](https://creativecommons.org/licenses/by/3.0/)とされています。なので、クレジットを表示する必要があります。ライセンス大事！！！

.mp4を取得、`Assets`フォルダに含めて下さい。そして、画像を背景に指定した時と同じように、`<Video>`を使って背景を設定します。今回は自動で再生されるように`AutoPlay`プロパティを`true`に設定します。また、再生が終わった後も繰り返すようにしたいので、`IsLooping`プロパティも設定します。

```SplashPage.ux
<JavaScript File="SplashPage.js" />
<Video Layer="Background" File="../Assets/nature.mp4" AutoPlay="true" IsLooping="true" />
```

さて、背景画像の時もそうだったように、デバイスのサイズが変わると、余白ができてしまう場合があります。`<Image>`同様、アスペクト比を保ちながら、動画が入りきるように拡大・縮小されるためです。これを解消するには`StrechMode`を指定します。

```SplashPage.ux
<Video Layer="Background" File="../Assets/nature.mp4" AutoPlay="true" IsLooping="true" StretchMode="UniformToFill" />
```

これで背景に動画を設定することができました。しかし、ちょっと背景が強すぎて、タイトルなど、メインの要素が目立たないので、少しエフェクトを加えます。ぼかしと透明度を加えてあげましょう。

```SplashPage.ux
<Video Layer="Background" File="../Assets/nature.mp4" AutoPlay="true" IsLooping="true" StretchMode="UniformToFill" Opacity=".5">
	<Blur Radius="4.75" />
</Video>
```

これだけで、ビデオにブラーをかけつつ、背景色と馴染ませることができます。さて、最後に、動画の作者である、Grahamさんのクレジットを追加します。まずは今まで作ったものを`<DockPanel>`に移動しましょう。

```SplashPage.ux
<Page ux:Class="SplashPage">
    <Router ux:Dependency="router" />

    <JavaScript File="SplashPage.js" />

    <DockPanel ClipToBounds="true">
        <Video Layer="Background" File="../Assets/nature.mp4" IsLooping="true" AutoPlay="true" StretchMode="UniformToFill" Opacity="0.5">
            <Blur Radius="4.75" />
        </Video>

        <Grid RowCount="2">
            <StackPanel Alignment="VerticalCenter">
                <hikr.Text Alignment="HorizontalCenter" FontSize="70">hikr</hikr.Text>
                <hikr.Text Alignment="HorizontalCenter" Opacity=".5">get out there</hikr.Text>
            </StackPanel>

            <hikr.Button Text="Get Started" FontSize="18" Margin="50,0" Alignment="VerticalCenter" Clicked="{goToHomePage}" />
        </Grid>
    </DockPanel>
</Page>
```

画面の一番下にクレジットを追加します。

```SlashPage.ux
<DockPanel ClipToBounds="true">
    <Video Layer="Background" File="../Assets/nature.mp4" IsLooping="true" AutoPlay="true" StretchMode="UniformToFill" Opacity="0.5">
        <Blur Radius="4.75" />
    </Video>
    <hikr.Text Dock="Bottom" Margin="10" Opacity=".5" TextAlignment="Center" FontSize="12">original video by Graham Uhelski</hikr.Text>
```

これでだいたいOKです。こっそり追加した`ClipToBounds`ですが、先ほどブラーを施したので、隣の画面（ホーム画面）に、にじんで広がった部分が見えてしまう場合があります。それは望ましくないので、動画を`SplashPage`の範囲でクリップするための設定です。

さて、最後に、画面遷移時の`push`を`goto`に直しておきましょう。

```SplashPage.js
function goToHomePage() {
	router.goto("home");
}
```

###今回の成果
これで私たちのアプリは完成です！お疲れ様でした！見た目はこんな感じです。

![hikr.gif](https://qiita-image-store.s3.amazonaws.com/0/100937/0b39b96a-83b7-f216-31fa-1d839b5fbf1b.gif)
今回も公式チュートリアルの動画をgifにしています。

かなりスムーズに動いているので、ぜひ手元の端末で動かしてみてください:)
今回のチュートリアルで変更したコードを載せます。

```Components/hikr.Button.ux
<Panel ux:Class="hikr.Button" Margin="10" Padding="10" FontSize="16">
    <string ux:Property="Text" />
    <float ux:Property="FontSize" />

    <Rectangle Layer="Background" Color="#125F63" CornerRadius="4">
        <DropShadow Angle="90" Distance="1" Spread="0.2" Size="2" Color="#00000060" />
    </Rectangle>

    <hikr.Text Value="{ReadProperty Text}" FontSize="{ReadProperty FontSize}" TextAlignment="Center" />

    <WhilePressed>
        <Scale Factor=".95" Duration=".08" Easing="QuadraticOut" />
    </WhilePressed>
</Panel>
```

```MainView.ux
<App Background="#022328">
    <iOS.StatusBarConfig Style="Light" />
    <Android.StatusBarConfig Color="#022328" />

    <Router ux:Name="router" />

    <ClientPanel>
        <Navigator DefaultPath="splash">
            <SplashPage ux:Template="splash" router="router" />
            <HomePage ux:Template="home" router="router" />
            <EditHikePage ux:Template="editHike" router="router" />
        </Navigator>
    </ClientPanel>
</App>
```

```Pages/SplashPage.ux
<Page ux:Class="SplashPage">
    <Router ux:Dependency="router" />

    <JavaScript File="SplashPage.js" />

    <DockPanel ClipToBounds="true">
        <Video Layer="Background" File="../Assets/nature.mp4" IsLooping="true" AutoPlay="true" StretchMode="UniformToFill" Opacity="0.5">
            <Blur Radius="4.75" />
        </Video>

        <hikr.Text Dock="Bottom" Margin="10" Opacity=".5" TextAlignment="Center" FontSize="12">original video by Graham Uhelski</hikr.Text>

        <Grid RowCount="2">
            <StackPanel Alignment="VerticalCenter">
                <hikr.Text Alignment="HorizontalCenter" FontSize="70">hikr</hikr.Text>
                <hikr.Text Alignment="HorizontalCenter" Opacity=".5">get out there</hikr.Text>
            </StackPanel>

            <hikr.Button Text="Get Started" FontSize="18" Margin="50,0" Alignment="VerticalCenter" Clicked="{goToHomePage}" />
        </Grid>
    </DockPanel>
</Page>
```

```Pages/SplashPage.js
function goToHomePage() {
    router.goto("home");
}

module.exports = {
    goToHomePage: goToHomePage
};
```

###今回初登場したFuseのコンポーネントたち
- [float](https://www.fusetools.com/docs/uno/float)
- [Video](https://www.fusetools.com/docs/fuse/controls/video)
- [Blur](https://www.fusetools.com/docs/fuse/effects/blur)

###明日は
アプリの実装は完了しました。明日は予定では、チュートリアルのまとめですが、記事単独で見た時の有用性があまりなさそうなので、もしかしたら違うこと書くかも。