デザインとエンジニアリングをつなげる取り組み

こんにちは、Komerco事業部デザイナーの藤井(@kenshir0f)です。
主にKomercoのサービスデザイン全般とView周りの開発を担当しております。

今回はKomercoの開発チームで実践している「デザインとエンジニアリングをつなげる取り組み」についてお話します。

なぜデザイナーが実装に入るのか

Komercoではユーザーさんへスピーディーに価値を届けるための取り組みを積極的に採用しています。
素早くリリースすることによって、早い段階でフィードバックをもらうことができるほか、
手戻りなどの失敗リスクを最小限に抑えることもできます。

デザイナーがデザインして、エンジニアが実装する、という流れの中で、
実機でのデザイン確認や細かい調整などで想定以上に工数がかかることがあるため、
見た目に関する部分はデザイナーが実装に入ることで、デザイン確認や調整の時間を巻き取とっています。

実践している取り組み

では実際に行っているデザインとエンジニアリングをつなげる取り組みをいくつかご紹介します。

KomercoFont

Komerco内で使われているアイコンフォントです。
iOSリリース時はアイコン画像をpngファイルで (@1x), @2x, @3x を用意していました。
新しいアイコンが出来上がったらPull Requestで画像を追加するフローでしたが、アイコン画像の管理コストが高いことや、画像容量も大きくなってきたためバージョン管理によるフォント形式に移行しました。

なおアイコンはGithubPagesに静的ページを用意することで、現在どのアイコンが利用可能か見えるようにしています。

f:id:kenshir0f:20181107144230g:plain

アイコンフォントを用意したので次は実際に使えるよう準備します。
Komercoでは管理画面をReactで開発しているため、IconのReactComponentを用意することでエンジニアがサクッと使えるようにしています。

// エビのアイコン
<Icon name={ 'shrimp' } />

同様にiOSではこのような感じに使います。
ここはチームのエンジニアがKomercoFont導入の話をした時にシュッと作ってくれました。すごい。

// UILabel
label.kf.icon = .crab

// UIButton
button.kf.setIcon(.heart)

これでアイコンフォント(ttf)を更新するだけで各アイコンが簡単に使えるようになります。

Komercomponents

ReactのComponent集です。名前は仮なのでかっこいいやつに差し替えたいですね。。
上で述べたとおり管理画面のViewはReactで開発しているため、事前にデザインが当たっているコンポーネントを用意しておくことでエンジニアの見た目の調整に関する負担を減らし、裏側のロジックに時間をさけるようにしています。

import { Icon, Button } from './../Komercomponents'

// ユーザーアイコン(20px)
<Icon name={ 'user' } size={ 20 } />

// プライマリーのボタン
<Button color={ 'primary' } disabled={ this.state.isLoading } onClick={ this.deleteElement() }>削除</Button>

意図しない挙動を防ぐため、propsはホワイトリスト方式で受け取れるようにしました。
こちらもミニマムで作っていき、必要なステータスを受け渡したくなったら徐々に拡張して行く予定です。
TypeScriptで開発しているため事前に受け取れるpropsを提示したり、許可しない型を警告してくれるため安心してReactComponentを開発することができます。型便利ですね。

f:id:kenshir0f:20181107142320p:plain

またCSSはCSS Moduleを使うことで表示のロジックと見た目の責任を切り分けるだけでなく、新たに入るデザイナーでも簡単に編集できるようにしています。

import * as style from './style.css'

<Icon className={ style.primaryColor } name={ 'komerco' }>

Komercomponentsは当初npmで管理しようと考えていましたが、
開発中にComponent化することが多いためGit Submoduleでインポートするようにしました。
このKomercomponentsは現在非公開ですが、公開しない理由も特に無いため充実してきたらOSSにしようという流れで開発を進めています。

Komercomponents API document

上記KomercomponentsのAPI仕様ページです。
Doczを用い、FirebaseのHostingに静的ページを置くことでwebからComponentsの仕様を把握できるようにしています。

f:id:kenshir0f:20181107145020p:plain

初めはStorybookも検討しましたが、作成・管理するコストがDoczの方が低いと感じたためこちらを採用しました。
propsに仕様のコメントを残すと自動で読み込むため、仕様書の作成コストが低くすばやく開発を進めることができます。

Lottieによるアニメーションの導入

アニメーションにはOSSライブラリのLottieを採用しています。
デザイナーがAfterEffectsからjsonファイルを書き出してそのまま実装まで行えるほか、軽量かつwebでも同じアニメーションを使うことができます。

f:id:kenshir0f:20181107142429g:plain:w400

現在は主に「スキ」のインタラクションで使用していますが、リッチな体験を提供するために今後アニメーションを使うシーンが多くなることを見越して「デザイナーがアニメーションを作成してそのまま本番に載せる仕組み」を用意しました。
KomercoではRxSwiftで書かれた処理が多いのでその部分に関してはエンジニアに相談しつつ、デザイナーが実装してPRでレビューをもらうことでエンジニアの負担を減らしながらデザイン要素を取り入れることができます。

f:id:kenshir0f:20181107142204p:plain

AutoLayoutを使ったデザイン調整

個人的に「デザイナーがやったほうがいいと感じたデザイン調整ランキング1位」はiOSのAutoLayoutでした。

f:id:kenshir0f:20181107143327p:plain:w300

主な理由として、

  • フォント周りにおいて、デザインデータのマージンとXcodeで入力した値は同じでも見た目は微妙に異なる
  • 「数px調整 -> ビルド -> 確認 -> 調整 ...」でビルドによる待ち時間と確認のコミュニケーション回数が多い

などがあります。調整のたびに毎回ビルドするのは大変ですね。。。 AutoLayoutは最初とっつきにくいと感じましたが、エンジニアとペアプロしつつ

  • leading, trailingなどの用語とそれらの位置関係の把握
  • Constraintsによる要素間のつなげ方

などを理解したうえで、簡単なPRを出すところから少しずつ慣れていきました。
それ以降は軽微なデザイン修正はデザイナーがAssignされて調整するようにしています。

おわりに

Komercoにおけるデザインとエンジニアリングをつなげる取り組みについてご紹介しました。今ある技術を使って少ないコストで開発効率を上げる仕組みを積極的に取り入れています。
体験設計やUIデザインだけでなくどうしたらユーザーさんにすばやく価値を届けられるか、その仕組みをデザインするのもデザイナーの腕の見せどころなので引き続き開発にも取り組んでいきたいと思います。

ではでは👋

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/