はじめに
この記事は 第2のドワンゴ Advent Calendar 2018 の16日目の記事です。
先週は9日目の記事として、「dwango.co.jpをReact/TypeScript/Storybookでリメイクしてみた。」を書きましたが、今週はその続き。
先週はdwango.co.jpのデザインをそのままReactで作り直したのですが、それだけだとやっぱり物足りなかったので、今週はモバイルページを自分でデザインして実装してみました!
実装のときに工夫したことや、大変だったことを共有していきます。
※今回の作成物の一切は個人によるもので、弊社の意向とは全く関係ありません。
作ったもの
dwango.co.jp(モバイル端末からご覧ください)
デザインについて
デザインの要点は、**「多くのサービスを抱えるdwangoという会社をいかに楽しく見せるか」**だと思ったので、多くのサービス絵、ロゴ、バナーを使いつつ、かつ窮屈感のない構成を目指しました。
最初のうちは、とにかくたくさんの素材を引っ張ってきて、Sketchで切り貼りしながらレイアウトを固めて。
ヘッダーと背景デザインについては、dwango採用ページのデザインを踏襲しました。
ただ、今回のデザインは、サービス絵とロゴの雰囲気に合わせて多くの色を使いたかったので、背景の線もそれぞれ固有の色にしてみたり。
結果的にdwangoという会社の多様性を表現できたのではないかなと思います(後付け)。
Sketchで以下の画像を作って全体像をまとめて。背景線とか、お知らせ、フッターとかは雰囲気で作ってます。まあ実装していくうちになんとかなるだろうと。
こんな感じで、2時間くらいでデザインがまとまったので、コードを書いていきます。
webとmobileの分岐
コードは先週作成したwebに付け足していくことにしたので、そもそもどこでモバイルを分岐させるか迷いましたが、結論としてRootで分岐させて、コンポーネント自体を独立させました。
Rootでwindowサイズを計測して、コンポーネントを分岐させています。
// Rootコンポーネント
const Root = () => (
<React.Fragment>
{window.innerWidth > 768 ? <PcRoot /> : <SpRoot />}
</React.Fragment>
);
export default Root;
ファイル構成としては、このような感じに。
src
|-components
|└-Common
|└-PC
|└-SP
|-img
|-styles
完全にコンポーネントを分離させることで、別々に開発することができて、お互いへの影響を考えずに済んだのはよかったです。
cssのメディアクエリで色々と指定すると、webの変更をしたときにmobileへの影響を考えないといけなかったりして、結構大変なので。
スタンダードがどうなっているのかはわからないのですが、この方法で開発自体はとてもやりやすかったです。
storybookの設定
mobileの画面を作成するときには、storybookもmobileで表示されるようにすると便利です。
@storybook/addon-viewportというライブラリを追加することで、特定のデバイスで表示される画面をstorybookで確認することができます(画像はiPhone6で見たときの表示デモ)。
また、viewportをコンポーネントごとにいちいち切り替えるのは手間なので、storybookの設定時に、viewportのデフォルトを設定すると楽です。
import React from "react";
import { storiesOf } from "@storybook/react";
// viewportライブラリを読み込む
import { withViewport } from "@storybook/addon-viewport";
import Top from "./Top";
const story = storiesOf("SP/pages", module);
// デフォルトのviewportを設定する
story.addDecorator(withViewport("iphone6"));
story.add("Top", () => <Top />);
こうすると、webのコンポーネントの場合はwebのサイズで、mobileのコンポーネントの場合はiPhone6のサイズで確認できます。
いちいち端末で確認したり、Googleの開発者オプションで確認する必要がないので、けっこう便利だったりします。
ランダムに動くアイコン
アイコンはそのままでも良かったのですが、せっかくなら動いた方が楽しいかと。
このアイコンが動くタイミングはランダムに生成していて、かつリロードするたびに動くタイミングが変化するようになっています。
基本的なアニメーションの動作はcssで管理しつつ、タイミングを管理するanimation-delayだけはjsでランダムに生成することで、リロードごとにタイミングが変化しています。
コードだとこんな感じ。
// ロゴを表示するコンポーネント
const LogoDisplay = () => (
<div className={styles.container}>
// ロゴの配列を回して、それぞれ表示する
{logos.map(logo => (
<div
className={styles.logo}
key={logo.src}
// animation-delayだけ動的に後付けすることで、ランダムなタイミングを実装
style={{ animationDelay: `${Math.random() * 4}s` }}
>
<a href={logo.href} target="_blank">
<img src={logo.src} />
</a>
</div>
))}
</div>
);
export default LogoDisplay;
動き自体は、ロゴの大きさを変えつつ、位置の移動と回転を同時に行って、自己主張モーションを実現しました。
40%~60%のときだけ動くようにしています。
@keyframes shake {
40% {
transform: translate(0, 0) rotate(0deg) scale(1);
}
45% {
transform: translate(5px, 5px) rotate(2deg) scale(1.2);
}
50% {
transform: translate(0, 5px) rotate(0deg) scale(1.2);
}
55% {
transform: translate(5px, 0) rotate(-2deg) scale(1.2);
}
60% {
transform: translate(0, 0) rotate(0deg) scale(1);
}
}
ランダムでふるふると動くアイコンを楽しんでいただければ。
まとめ
といった形で、カラフルでスッキリとしたモバイルページを作成してみました。
ソースコードはこちらに置いてあるので、参考までにどうぞ。
https://github.com/hiraike32/dwango-remake
ただやっぱりデザインは苦手なので、デザイナーさんは偉大だと感じました。いろんなサイトを見て、良いレイアウトや流行のデザインを押さえておくのは大事ですね。
これからも新しい技術を身につけたら、定期的に何かを作ってアウトプットしていこうと思います。