そーす

福岡在住のプログラマ

Fuse Sketchからインポートする

f:id:saburesan:20160216214704p:plain

今回はSketchからインポートしてアプリを作成します。

Fuseプロジェクト作成

先にプロジェクトを作っておく必要があります

% fuse create app SketchSample

Sketchのプロジェクトを作成

今回はサンプルで以下のようなアプリのデザインっぽいのを作りました。 Design.sketch

f:id:saburesan:20160216221840p:plain

作成したデザインデータはFuseプロジェクトのルートディレクトリに置きます

% ls
MainView.ux           Design.sketch   SketchSample.unoproj

SketchをFuseプロジェクトにインポートする

プロジェクトルートに移動して以下を実行

% fuse import Design.sketch
Analyzing Design.sketch. This can take a while if the file is big.
Analyzing file structure...
Extracting font: Roboto Bold
Extracting font: Roboto Regular
Extracting image: Design.Main.row_birthday.row_birthday_background
Extracting image: Design.Main.row_city.city_background
Extracting image: Design.Main.row_country.country_background
Extracting image: Design.Main.icon
Extracting image: Design.Main.icon_frame
Extracting image: Design.Main.cover_over_lay
Extracting image: Design.Main.cover
Writing resource library: Design.sketch.ux
Analyzing Design.sketch. This can take a while if the file is big.
Analyzing file structure...
Extracting font: Roboto Bold
Extracting font: Roboto Regular
Extracting image: Design.Main.row_birthday.row_birthday_background
Extracting image: Design.Main.row_city.city_background
Extracting image: Design.Main.row_country.country_background
Extracting image: Design.Main.icon
Extracting image: Design.Main.icon_frame
Extracting image: Design.Main.cover_over_lay
Extracting image: Design.Main.cover
Writing resource library: Design.sketch.ux

All done!

お、成功したようです。

% ls
Design.sketch         Design.sketch.ux      SketchSample.unoproj
Design.sketch-assets/ MainView.ux
  • Design.sketch.ux
  • Design.sketch-assets/

が増えてますね。 Design.sketch.uxを見てみます。

<Panel>
    <Font File="Design.sketch-assets/Roboto-Bold.ttf" ux:Global="Roboto_Bold" />
    <Font File="Design.sketch-assets/Roboto-Regular.ttf" ux:Global="Roboto_Regular" />
    <Image ux:Class="Design.Main.row_birthday.row_birthday_background">
        <MultiDensityImageSource>
            <FileImageSource File="Design.sketch-assets/Main.row_birthday.row_birthday_background@1x.png" Density="1" />
            <FileImageSource File="Design.sketch-assets/Main.row_birthday.row_birthday_background@2x.png" Density="2" />
        </MultiDensityImageSource>
    </Image>
    <Image ux:Class="Design.Main.row_city.city_background">
        <MultiDensityImageSource>
            <FileImageSource File="Design.sketch-assets/Main.row_city.city_background@1x.png" Density="1" />
            <FileImageSource File="Design.sketch-assets/Main.row_city.city_background@2x.png" Density="2" />
        </MultiDensityImageSource>
    </Image>
    <Image ux:Class="Design.Main.row_country.country_background">
        <MultiDensityImageSource>
            <FileImageSource File="Design.sketch-assets/Main.row_country.country_background@1x.png" Density="1" />
            <FileImageSource File="Design.sketch-assets/Main.row_country.country_background@2x.png" Density="2" />
        </MultiDensityImageSource>
    </Image>
    <Image ux:Class="Design.Main.icon">
        <MultiDensityImageSource>
            <FileImageSource File="Design.sketch-assets/Main.icon@1x.png" Density="1" />
            <FileImageSource File="Design.sketch-assets/Main.icon@2x.png" Density="2" />
        </MultiDensityImageSource>
    </Image>
    <Image ux:Class="Design.Main.icon_frame">
        <MultiDensityImageSource>
            <FileImageSource File="Design.sketch-assets/Main.icon_frame@1x.png" Density="1" />
            <FileImageSource File="Design.sketch-assets/Main.icon_frame@2x.png" Density="2" />
        </MultiDensityImageSource>
    </Image>
    <Image ux:Class="Design.Main.cover_over_lay">
        <MultiDensityImageSource>
            <FileImageSource File="Design.sketch-assets/Main.cover_over_lay@1x.png" Density="1" />
            <FileImageSource File="Design.sketch-assets/Main.cover_over_lay@2x.png" Density="2" />
        </MultiDensityImageSource>
    </Image>
    <Image ux:Class="Design.Main.cover">
        <MultiDensityImageSource>
            <FileImageSource File="Design.sketch-assets/Main.cover@1x.png" Density="1" />
            <FileImageSource File="Design.sketch-assets/Main.cover@2x.png" Density="2" />
        </MultiDensityImageSource>
    </Image>
</Panel>

Panelクラスをルートにして新しいクラスが定義されているようです。
順に見ていきます。

ux:Global

これはアプリケーション内で自由使えるでコンポーネントを定義できます

Global resources are shared objects that are created once and used throughout your application. Global resources are recommended for objects that never change during the application lifetime, such as fonts, colors and sounds.

1度定義するとアプリケーション内ではどこでも使える。しかし、変更しない事が推奨されるのでフォントとか色定義とか変わらない奴に使えと。

ux:Class

これは新しいクラス定義です。例えばDesign.Main.row_birthday.row_birthday_backgroundクラスを定義すると

<Design.Main.row_birthday.row_birthday_background/>

というタグが使えるようになります。
クラス定義といってもこのファイルだけで使えるわけではありません。 実はFuseはこの定義からUnoというC#っぽいコードを吐き出します。
例えばDesign.Main.row_birthday.row_birthday_backgroundの場合

namespace Design.Main.row_birthday
{
    public partial class row_birthday_background: Fuse.Controls.Image
    {
        static row_birthday_background()
        {
        }
        public row_birthday_background()
        {
            InitializeUX();
        }
        internal void InitializeUX()
        {
            var temp = new Fuse.Resources.MultiDensityImageSource();
            var temp1 = new Fuse.Resources.FileImageSource();
            var temp2 = new Fuse.Resources.FileImageSource();
            temp.Sources.Add(temp1);
            temp.Sources.Add(temp2);
            temp1.Density = 1f;
            temp1.File = new global::Uno.UX.BundleFileSource(import global::Uno.BundleFile("../../../../../Design.sketch-assets/Main.row_birthday.row_birthday_background@1x.png"));
            temp2.Density = 2f;
            temp2.File = new global::Uno.UX.BundleFileSource(import global::Uno.BundleFile("../../../../../Design.sketch-assets/Main.row_birthday.row_birthday_background@2x.png"));
            this.Source = temp;
        }
    }
}

上記のようなクラスを生成します。 これは自前で書くこともできますが、その話はまたおいおいやっていきます。 ちなみに、Fuseが自動生成する場合は./build/Simulator/local* 内に生成されます。

MultiDensityImageSource

これは他端末対応するためのリソース定義ですね。
Sketchはスマホアプリのための書き出し機能があるのでそれを用いて自動で出し分けているようです。
クラス定義から解像度別の対応までやってくれるのはありがたいですね。

<Image ux:Class="Design.Main.icon">
        <MultiDensityImageSource>
            <FileImageSource File="Design.sketch-assets/Main.icon@1x.png" Density="1" />
            <FileImageSource File="Design.sketch-assets/Main.icon@2x.png" Density="2" />
        </MultiDensityImageSource>
    </Image>

デザインどおりに組んで見る

インポートも上手くいき、生成されたコードもざっくりと読み終えたのでデザインどおりにレイアウトを組みたいと思います。 完成品が以下。

<App Theme="Basic" Background="#F5F5F5">
  <ScrollView AllowedScrollDirections="Vertical">
    <StackPanel>
      <Panel>
        <Text TextColor="#FFF" Alignment="BottomCenter" Font="Roboto_Bold" Margin="0, 0, 0, 50" FontSize="30">Sabure Jr</Text>
        <Panel>
          <Design.Main.icon Width="100" />
          <Design.Main.icon_frame Width="106" />
        </Panel>
        <Design.Main.cover_over_lay Alignment="Bottom" />
        <Design.Main.cover />
      </Panel>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">Birthday</Text>
            <Text TextColor="#777" Alignment="CenterRight" Font="Roboto_Bold">2016.1.1</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">City</Text>
            <Text TextColor="#777" Alignment="CenterRight" Font="Roboto_Bold">Fukuoka</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">Country</Text>
            <Text TextColor="#777" Alignment="CenterRight" Font="Roboto_Bold">Japan</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">Edit</Text>
            <Text TextColor="#CCC" Alignment="CenterRight" Font="Roboto_Bold">---</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">Edit</Text>
            <Text TextColor="#CCC" Alignment="CenterRight" Font="Roboto_Bold">---</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">Edit</Text>
            <Text TextColor="#CCC" Alignment="CenterRight" Font="Roboto_Bold">---</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">Edit</Text>
            <Text TextColor="#CCC" Alignment="CenterRight" Font="Roboto_Bold">---</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">Edit</Text>
            <Text TextColor="#CCC" Alignment="CenterRight" Font="Roboto_Bold">---</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
      <Design.Main.row_birthday.row_birthday_background Margin="0, 0, 0, 1">
          <Panel Margin="20,20,20,20">
            <Text TextColor="#AAA" Alignment="CenterLeft">Edit</Text>
            <Text TextColor="#CCC" Alignment="CenterRight" Font="Roboto_Bold">---</Text>
          </Panel>
      </Design.Main.row_birthday.row_birthday_background>
    </StackPanel>
  </ScrollView>
</App>

f:id:saburesan:20160217060055p:plain

取りあえずSketch通りになりました。

まとめ

Sketchからインポートしてアプリを作成しました。
正直Sketchどおりにアプリの雛形が出来上がるのかなーと思ってたので少し違いました。
しかしながら、画像のインポートの手間が省けるのと、多端末対応の処理まで自動でやってくれるのはいいなーと思いました。
今回の気になる点として

  • 画像の名前及びグルーピングがname spaceやクラス名に直接関係するので注意が必要
  • テキストや色、マージンなどのリソース管理

が上げられます。
次回そのあたりを調査していきたいです。