みなさま、初めまして。コミュニティ事業本部所属のマキと申します。現在は、575で気軽につぶやくアプリ、『ごーしちご』のデザイナーとして日々邁進しております。

今回は、いつもと違う1pixelとなります!美術史の捉え方です。

いきなりですが。デザインは、応用美術と言われるくらい、美術の発展と共にその技法が生み出されています。
ここでは、いざアートの話を持ち出されても、概要だけでも理解できるように、
特に美術を学びはじめの方向けに、おさらいをお話できればと思います。


1.大まかに掴む!


みなさんが美術館、あるいは教科書で見たことがあると思う絵画や彫刻などの『美術作品』。作品として素晴らしいというのは、オークションやキュレーターの方々からの情報で言い尽くされていると思います。

そして、デザインは応用美術とも言われるので、
まずはその源の美術史を大まかになぞって見ようかと思います。
下の図は、代表的な西洋の美術史の名称を時系列に並べたものです。

nempyo_1

(現代の美術は、技術発展と共に細分化されているため、一旦、省きます。)
また、親しみやすく、西洋と日本を並べました。

おそらく、よく見かける年次表だと思います。しかし、これでは、具体的にどのような思想で美術の歴史が築かれて来たのか分からず、美術作品の良さが単なる『奇麗』の一言で終わってしまいます。綺麗と感じた作品なのに、その作品の背景を知らないのは、非常にもったいないことだと思います。

従って、まずは、トレンドがどのような感じで流れたのか?を捉えるために、○○主義等の表記をとり、トレンドを表記しようかと思います。

nempyo_2

諸処、はしょりすぎと言われるかもしれません。(各主義・美術の詳細は、それぞれを参照した方がわかります。)

しかし、点の名称の細かさや多さよりも、線のながれで捉えた方が、どんな思想で作られたのか把握しやすいかと思います。

また同時に考えるべきなのは、誰に向けられた作品や制作物だったのかということです。
原始、先史は小さなコミュニティから始まり、やがてコミュニティが合併し、王や国、宗教布教で盛んになり始め、貴族などの上流階級(宮廷画家)で栄え、市民運動や産業革命により、民衆にも親しみやすくなっていきました。

西洋に限ってですが、

1. 狩猟や子孫繁栄など、祈願造形物の創造
2. 国家形成や宗教信仰、布教活動のため
3. 神中心から、人間、自然に目を向けた創作の復興
4. 哲学、個性の表現の追求

により、今日の美術、デザインがあったのだと考えられています。

2. つまんでおいたほうがいい項目


大まかな流れをふまえて、いよいよ、歴史を歩んでいきたいと思います。
しかし、何万何千年と歩んでいくと、とてもじゃないですが、ブログにも収まりきらないので、
デザイナーとして、知っておいてみては?思うものを少しだけチョイスしたいと思います。

1. 祈願、布教活動


◎ショーヴェ洞窟の壁画
現在、もっとも古い美術作品は「フランスのショーヴェ洞窟の壁画」といわれています。
昨年、この洞窟が世界遺産に登録されました。

◎カリグラフィー
古代ローマ、トラヤヌス帝が建立した石碑の文字が有名。1世紀後半から2世紀において、文字を美しく装飾する手法。印刷技術がまだ無い時代、オリジナルの写本を作成するために発達しました。

2.人間性の美術(ルネッサンス~)


◎遠近法
一点透視法を完璧に絵に組み込んだジョットをはじめ、ルネッサンス期に、研究され、線遠近法、空気遠近法が確立された。
→以後から、空間的な絵画が主流に。

※ルネッサンスは、他にもいっぱいあります!

◎強い光と影
ルネッサンスから、さらに力強い絵画を目指したバロック主義。その手法のひとつは、陰影の強い表現を用いて、主従関係をはっきりとさせることです。明暗関係がわかりやすいので、色のグルーピングが上手く行かない方は参考にしてみてはいかがでしょうか?(f-1

The Cardsharpsf-1 カラヴァッジオ『トランプ詐欺師』、引用元:wikipedia





3. 哲学、個性の表現(18世紀、産業革命以降)


◎モネ(印象主義)
印象主義は、アカデミー(教育施設)、サロン(展覧会)で、空間的で古典な価値観の絵が高く評価されるのに対し、抗うように出てきた画家たちの主義。
光によって生み出される、観察する場所によって変わる色の変化をできるだけそのまま表現しようとしました。1810年にゲーテの『色彩論』が発表されてから約半世紀、印象派も光と影の色の関係をはじめ、色の研究が盛んに行われました。
参考:モネ『ルーアン大聖堂連作

◎デザイン
産業革命により、意識され始める。
ちなみに、“design”の語源は、
ラテン語の動詞“desingnare”(指示・表示する)に由来し、
これには更に“signare”(印を付ける)と言う言葉が大元にあります。
引用元:コトバンクレファレンス協同データベース

◎アーツ&クラフト運動
ウィリアム・モリスの主導によるデザイン運動。産業革命後、大量生産の供給により、粗悪な質の製品が大量に世の中に出回ったのを受け、『実用と美』を兼ね揃えた中世の手工芸に立ち返り、生活の芸術化が図られました。後のアールヌーボーにも影響を与えています。

3. さいごに


今回は、ざっくりと導入するところをお話させていただきました。
デザインが意識されてからの時間に比べて、いく分も長い時間で発展してきた美術史。

僕が感じているのは、日々の生活に近い、古代や、宗教活動で用いている、聖書、イコン、教会、どれをとっても、広義のデザインをされていたのだと思います。

今、自分がしているデザインも、どこがルーツなのかを探すのも、自分が作るものの説得力に繋がるよう、これからも、色々なものに向き合っていきたいと思います。

また別の機会があることを楽しみにしております!

ありがとうございました。


ごーしちご デザイナー
マキ

はじめまして。
アメーバ事業本部キュレーション事業部の渡邊 (@mnemoniqs) です。
デザイナーとして、SpotlightRecolleGAMYなどの主にバイラルメディアの制作を担当しております。

デザイナーは日々インプット!ってことで、これは特にいいな~って思ったデザインに関するブログ記事をいくつかまとめてみました。
知っている記事もあると思いますが、もし新しい発見や出会いがあれば。


おすすめブログ記事16選


デザイナーとして成長するために重要なたったひとつのこと

個人的に考え方がすごく似ていて、印象に残っています。神は細部に宿る。




マージンを制するものがスマートフォンデザインを制す!~iPhone6/6Plusの登場で、マージンがどう変化したのか~

マージンに気をつかうことがどれだけ重要か再確認。eurekaさんのCouplesというアプリはほんとにキレイに出来てきてヨダレものですので、是非DLして見てみてください。




ウェブサービス開発の現場におけるデザイナー不要論と5~10年後の生存戦略

目を背けられない問題だと思います。こういうことを考えるのをやめた時点でデザイナーとしては終わるんでしょうね。


こちらの記事もグッときます。
技術は発想やデザインの限界にならない




UIの改悪がUXを改善させる場合

有名なUXの話。これを知っているか知らないかで、デザインの意識に幅がでると思います。


この話を元に考察した記事はこちら
ユーザーが待っている間のUIデザイン
空港の待ち時間を解決したデザインへの考察




デザイナーという人達の仕事

意識的な話。デザイナーとはどうあるべきか。





A Good User Interface

デザインが上手な方って、こういうところしっかりしてますよね。






デザイン作業のスピードアップ

当ブログ1pixelの記事から。駆け出しの方は必読です。あ、駆け出しじゃない方も必読です。






色を色で見ないで

当ブログ1pixelの記事から。1ヶ月ごとに読み返してもいいんじゃないかって思うくらい。






感覚派デザイナーも知っておいて損はない「デザインの要素と原則」

「色を色で見ないで」と共通点もありますが、こちらのほうが堅く専門的な感じ。




スマホUI考(番外編) なぜ機能追加をし続けるとアプリが破綻するのか?

有名な記事です。笑えないくらい笑えます。そして未来を予知したかのような現状のTwitterアプリ・・・





http://stat.ameba.jp/user_images/20141006/19/ca-1pixel/68/16/j/o0800087313089650791.jpg






ノンデザイナーこそ押さえておきたい! UI/UXが学べる神スライド7選

スライドのまとめです。時間があれば全部読んでみるのも。




Webデザインのスキルを磨く10のポイント

ひとつひとつに説得力があります。実際この方のアウトプットはその通り、ステキです。




ワンランク上のデザインにはかかせないPhotoshopの文字詰め「カーニング・トラッキング」のまとめ

「メトリクス」と「オプティカル」が未だによくわかっていない人は是非。

こちらも参考になります。
Webタイポグラフィの基本




ズルいデザインテクニック2013 + セミフラット version

ズルいってのはデザイナーにとって褒め言葉だと思っています。





最後に


クオリティの高いものをアウトプットするには、それ以上のインプットが必要だと思います。
デザイナーとしての目や感覚を鍛えるために、こういうネタを元に、他のデザイナーとデザイン談義を交わして行きたいですね!

最後までお読み頂き、ありがとうございました。
こんにちは。サイバーエージェント 人事本部の清水です。テクノロジー/デザインコースの採用や技術研修を担当しています。

今回の1Pixelは、2016年度卒学生の皆様へ、秋に実施する採用イベントのご案内をしたいと思います。第1弾として、クリエイター向けのコースを1つ。エンジニア向けのコースを2つをご紹介します。

あなたの最高傑作を見せてください!GitHubChallenge!


就職活動をイメージした時、学生のみなさんは、エントリーシートを書いて面接をして~という流れをまず想像するかと思います。サイバーエージェントでは、GitHubにアップしているソースコードを拝見させて頂き、学生のみなさんのプログラミングスキルを見させていただく採用フローをご準備しています。

当社主席エンジニアが中心となって、みなさんが開発したアプリや、開発プロジェクトを審査いたします。この選考を通過した方は、通常数回ある本選考の面接をスキップすることができます。

・プログラミングスキルに自信がある!という方
・一人でアプリを作ってきたけど、仕事でアプリを作っているエンジニアからのフィードバックがもらいたい!
・自分の書いたプログラムを、現場の最前線で活躍するエンジニアに見てもらいたい!

という方からのエントリーをお待ちしています。詳しくはこちらをご覧ください。


あなたのデザインスキルを腕試し!Oneday Design


Oneday Designは、ある課題にもとづき、参加者が1日で作品をつくりあげ、当社デザイナーの前で完成した作品を発表するデザインコンペです。



あるひとつの課題に対して「どういうアプローチで表現するか」、「デザインの切り口をどこに置くか」など、それぞれのセンスが問われるコンペになります。当社デザイナーからのフィードバックがありますので、「多くのユーザに支持されるポイントはどこにあるか」や、「伝えたい世界観を伝えるための見せ方」など、現場デザイナーならではのアドバイスがもらえたりします。

・ポートフォリオを、現場の最前線で活躍するデザイナーに見てもらいたい!
・スマートフォンアプリをテーマに、ユーザーをあっと言わせるものを創りたい!
・自己流でデザインしてきたけど、プロのデザイナーから現場のデザインのノウハウを教えて欲しい

という方からのエントリーをお待ちしています。詳しくはこちらをご覧ください。

ワクワクする技術にチャレンジしよう!Dogenzaka hack


新しい技術に触れた時のワクワク感、おもしろそうな課題にチャレンジするドキドキ感、Dogenzaka hackでは、そういったワクワクするようなテクノロジーにチャレンジすることをコンセプトにした、道玄坂発のハッカソン企画です。




第1回は「Swift 1Day」。iOS向け新開発言語「Swift」を用いて、1日でアプリを開発するイベントです。新しい技術に触れた時、わからないことだらけだけど、とにかく手を動かして、アプリが動いた時の新鮮さや楽しさ。Dogenzaka hackの第1弾となるSwift 1Dayでは、このワクワク感をコンセプトに、アプリ開発のハッカソンを開催します。

あるひとつの課題に対して、Swiftならではの実装方法、動かし方や表現方法など、様々なアプローチを試しながら、アプリを開発するイベントです。

Swiftをサービス開発に導入している当社エンジニアがナビゲーターとなり、開発事例やライトニングトークなどを交える予定です。優秀な作品を開発した方は、通常数回ある本選考の面接をスキップすることができます。





・iOSアプリを開発することが大好きな方
・Swiftを使ったおもしろいアプリを作ってみたい方
・アプリ開発好きな仲間を見つけて、一緒にアプリを作ってみたい方
・自分の技術力を見てもらい、現場の最前線で活躍するエンジニアからフィードバックをもらいたい方

という方からのエントリーをお待ちしています。詳しくはこちらをご覧ください。



以上になります。今回は第1弾として3つのイベントをご紹介しました。今後も様々な企画を予定していますので、楽しみにしていただけたらと思います。

こんにちは。
Unityエンジニア/フロントエンドディベロッパーをしている山内です。

業務では、Unityでのゲーム開発やWebサービスのフロントエンド開発を行っています。 またこのブログ(1Pixel サイバーエージェント公式エンジニアブログ)の運営委員もしています。

社内では新規ネイティブアプリ開発、既存アプリのネイティブ化に力を入れており、各部署でネイティブ開発や勉強会などが活発に実施されています。

本日は、先日 社内で行われたネイティブゲーム/アプリ開発イベント『モッカソンのご紹介とレポートをします。

モッカソンとは?

最近、ハッカソンというイベントをよく耳にすることと思います。
ハッカソンは「24時間でひとつのサービスを作り上げ、壇上で発表する」というものですが、
「モッカソン」は「24時間でひとつのゲーム/サービスのモックアップ(プロトタイプ)を作り上げ、壇上で発表する」というものです。

本イベントでは、お題をUnity, iOS, Androidの"ネイティブゲーム/サービス"に絞ってイベントが開催されました。

優秀なアプリを制作したチームはリリース化を目指して開発が続けられるかも!?とあって、各チームの鼻息は荒いです!!

開発開始!

開発は、1チーム3~4名 全8チームで行われました。

チームにはエンジニアの他、デザイナー、3Dクリエイターも含まれています。


エンジニアの中には、新卒エンジニアやフロントエンドやサーバーサイドエンジニアから、ここ数ヶ月でUnityやObjective-C、Javaなどのネイティブ開発技術を習得した方など、様々な背景を持つエンジニアが含まれています。


またデザイナーも最近3Dモデリングを習得した方もいます。

こちらのチームは2種類のアプリ開発を目指していました!

ホワイトボードでしっかりと進捗管理をして開発しています。

24時間しかないため、コードを打つエンジニアの手にも力が入ります!

各種のテスト端末やペンタブレットなどを持込み、万全の開発環境で望んでいます。


各チーム話しかけるのが怖いほど集中して、開発は夜遅くまで続けられました。
そこには”ネイティブ開発への熱気”と、ヒットを狙うという”強い情熱”が感じられました。

開発モック発表!

開発から24時間。いよいよ各チームで開発したアプリの発表です!
制限時間ギリギリまで調整を続けているチームが多く、会場はピリピリした雰囲気に包まれています。

ここではそのいくつかを紹介します。

こちらのチームは、写真撮影アプリとめざましアプリを掛けあわせたiOSアプリを発表しました。
写真撮影の際には、オーディエンスから思わず笑いが起きました!

こちらはUnityで開発した3Dゲーム。
ジェンガのような塔を破壊していき、破壊したブロックでスコアを競います。
プレイしていても、見ているだけでも迫力と気持ちよさを感じられる作品です。

こちらのチームはパズルゲームを制作しました。
ブロックの動き、気持ちのよいエフェクトへの拘りが感じられ、24時間で作ったとは思えないクオリティに目を見張りました!

フリック操作を基本としたカジュアルゲームアプリ。
フリック時のキャラクターの変化、モードチェンジなどバランスの良いアプリです。
Unity4.6 Bataからの新しいGUIシステム(uGUI)を取り入れるなどの挑戦も行っていました。


どのアプリもバラエティに富んでいて、可能性を感じる非常に面白いものばかりでした。
技術的挑戦を試みたチームも多く、実務での活用も期待です!

さいごに

発表されたアプリは、どのアプリも短時間で制作されたものとは思えない力作ばかりでした。
改良を加えればリリース化も期待できるアプリもあり今後に期待です!


またここで制作された数件のアプリは、実際にリリース化を目指して開発中であり、いずれ目に触れる機会があるかもしれません。


フロントエンドエンジニアとして業務を行っていた筆者としては、ネイティブ開発の面白さ実現できる表現の幅広さに改めて感動を憶えたイベントとなりました。また、チームで集中してネイティブ開発に取り組むことで知識とノウハウが更に深まったと考えています。


今後もこのようなイベントを通じて、アイデアの具現化と発信、エンジニアとクリエイターのスキルアップを目指していけたら最高ですね!


最後まで閲覧いただきありがとうございました。

こんにちは。フロントエンドエンジニアをしている岐部(@beryu)と申します。
WEBサービスのフロントエンド開発や、iOS用ネイティブアプリ開発を担当しています。

先日、弊社内で行われたTOTEC 2014というチューニンガソンのフロントエンドチューニング部門で優勝することが出来たので、その時の様子や私が行ったチューニングの内容をご紹介します!
(普段の業務で行っているチューニングというより、競技に特化したレポートになっていますのであしからず。。)


フロントエンドのチューニンガソンって、具体的に何を競うの?

課題となるウェブサイト(左記のスクリーンショットのページ)の描画をどれだけ高速にできるか、を競います。

チューニング対象は1ページのみで、画面遷移はありませんが画像のスライドショー機能が実装されています。
勝手にレイアウトを変更したり、機能や効果(アニメーション等)を変更したりするのはNGで、高速化しつつも性能以外のユーザー体験は維持することが求められます。


ここで「フロントエンドの性能測定には指標がたくさんあるはずだけど、どうやって優劣を競うんだろう?」と思われた方も多いのではないでしょうか?
今回のチューニンガソンでは、当日の競技開始直前にレギュレーションの説明が行われ、以下の8項目で評価される事が明示されました。
  • HTMLファイルサイズ
  • CSSファイルサイズ
  • JavaScriptファイルサイズ
  • 画像ファイルサイズ
  • リクエスト数
  • DOM要素数
  • JavaScriptのエラー有無(1つでもエラーがあればNG)
  • チューニング前後の表示差異(ImageMagickによる平均画素数比較で閾値を超えるとNG)
評価はWebKitベースのヘッドレスブラウザを使って行われ、社内で選ばれた100名弱のエンジニアでスコアを競います。
以上のルールで、11:00~18:00の7時間に渡って競技が行われました。

なお、エンジニアの順位は会場のプロジェクタやイントラネットでリアルタイムに公開される他、上位の順位は専用のTwitterアカウントでも実況されます。

作戦

発表されたレギュレーションを受けて、私は以下のような作戦で進めることにしました。

スコアに関係無さそうなチューニングは行わない

幸いなことに評価項目が明示されたので、行うべき施策の取捨選択が重要だと考えました。
例えば、「ブラウザのレンダリング負荷の軽減」や「アニメーションのfps改善」などは今回時間を費やすべきでないチューニングになりそうです。

一つ一つのチューニングに時間をかけない

性能改善策はいくつもある反面、作業時間は7時間しかないので、改善策をどれだけ多く適用できるかが勝敗を分ける事になりそうです。
時間との勝負なので、普段なら気にするような細部の実装も今回は放っておき、数をこなす事を意識しました。

チューニング開始

ここから、当日行ったチューニングの内容を時系列でご紹介します。
(時刻はgitのコミットログから予測したものなのでだいたいです)

11:00 初期状態のファイルを別名で保存

目的:チューニング後のデグレード確認環境の準備
チューニング対象のコードはgitリポジトリごと渡されたのでバージョン管理されているのですが、あえてローカルに別ファイルとしてコピーしておきました。
サクッとオリジナルのファイルが参照できる状態にしておけば、デグレードの確認が手軽に行えるので気持ち的にも安心です。

11:00 Gruntをインストール

目的:各種作業効率化ツールの利用
業務でGruntを使用していたので、このチューニンガソンでもGruntを使うことにしました。
(エンジニアさんによってはgulp.jsを使っている方も居らっしゃったみたいです。)

インストールしたGruntプラグインは以下の通りです。

プラグイン名目的
grunt-contrib-concat複数のJavaScriptファイルを1つのファイルに結合する
grunt-contrib-uglifyJavaScriptをminify(スペース・改行を除去、変数名や関数名を短縮)する
grunt-contrib-cssminCSSをminifyする
grunt-contrib-htmlminHTMLをminifyする
grunt-image画像ファイルを軽量化する
grunt-uncss使われていないCSSプロパティを取り除いたCSSファイルを生成する(後述)


11:10~ 課題ページの確認&PageSpeed Insightsの実行

目的:チューニング対象のウェブサイトの改善の余地を調査
上記のgruntプラグインをインストールする npm install コマンドを実行しながら、ブラウザやIDEでチューニング対象のウェブサイトを確認し始めました。
少し見ただけでもCSSの構文エラーがあったり、使っていないJavaScriptライブラリがインポートされていたり…。
まるで無茶な運用を数ヶ月続けたかのような、カオスなファイル群でした。

ここで実行した PageSpeed Insights に画像サイズの最適化をオススメされたので、まずはそこから行うことにしました。

11:20~ 画像ファイルの最適化

目的:画像ファイルサイズの削減
30 x 30pxで表示している画像ファイルが実際には150 x 150pxで保存されていたりする画像がそこそこあったので、それらのリサイズを行いました。
ここは画像毎にリサイズしたい解像度が異なっていたので地道にPhotoshopで縮小していったのですが、横幅を基準にリサイズした結果、高さが割り切れない数値になって1px狂ってしまったものがいくつかあり、それらが原因で評価項目の一つである
チューニング前後の表示差異(ImageMagickによる平均画素数比較で閾値を超えるとNG)
のチェックがNGになる問題が多数発生しました。
しょっぱなから解像度の微調整に結構な時間を食われてしまったので、悔いが残る工程となってしまいました…。

画像のリサイズとは別に、殆どの画像がPNGで保存されていたので、アルファチャンネルが必要無さそうな画像をPNG形式からJPG形式に変換する作業もここで一緒に行いました。

12:XX~ お昼ごはん

いつのまにか会場の後方でサンドイッチが配布されていました。
(ノイズキャンセリングイヤホンを付けて集中して作業していたので、昼食のアナウンスに気付けなかったのだと思われます…)

とは言え食べる時間も惜しいので、とりあえずサンドイッチは受け取るだけ受け取って作業の合間にちまちまと食べていく事にしました。

12:20~ jQueryのバージョンアップ

目的:JavaScriptファイルサイズの削減
ページ内でjQuery1.11.1が使用されていたのですが、WebKitブラウザでしかチェックしないレギュレーションだったのでjQuery2.1.1に変更しました。
jQuery2.X系は、jQuery1.X系から一部の古いブラウザ対応用の実装を取り除いたバージョンで、その分ファイル容量が軽くなっています。

本当はZepto.jsにしたかったんですが、jQueryからZepto.jsに置き換えるだけだとJavaScriptエラーが発生してしまっていたので、今回は諦めました。

12:25~ 不要そうなJavaScriptライブラリの削除

目的:JavaScriptファイルサイズの削減
たくさんのJavaScriptライブラリが読み込まれていたので、1行1行削除してみてJavaScriptエラーの発生しないものは取り除いていきました。

初期状態のscript要素(29行)

<script src="javascripts/jquery-1.11.1.js"></script>
<script src="javascripts/underscore.js"></script>
<script src="javascripts/underscore.string.js"></script><!--[if lte IE 6]>
<script src="javascripts/DD_belatedPNG_0.0.8a.js"></script>
<script>DD_belatedPNG.fix('body *');</script><![endif]-->
<script src="javascripts/backbone.js"></script>
<script src="javascripts/bootstrap.js"></script>
<script src="javascripts/coffee-script.js"></script>
<script src="javascripts/createjs-2013.12.12.min.js"></script>
<script src="javascripts/imgLiquid.js"></script>
<script src="javascripts/jquery-ui.js"></script>
<script src="javascripts/jquery.bxslider.js"></script>
<script src="javascripts/jquery.cycle.all.js"></script>
<script src="javascripts/jquery.ellipsis.js"></script>
<script src="javascripts/jquery.heightLine.js"></script>
<script src="javascripts/jquery.localscroll.js"></script>
<script src="javascripts/jquery.maximage.js"></script>
<script src="javascripts/jquery.scrollto.js"></script>
<script src="javascripts/jquery.slides.js"></script>
<script src="javascripts/jquery.smarttruncation.js"></script>
<script src="javascripts/masonry.pkgd.js"></script>
<script src="javascripts/paper-full.js"></script>
<script src="javascripts/tabulous.js"></script>
<script src="javascripts/trunk8.js"></script>
<script src="javascripts/jquery.smoothScroll.js"></script>
<script src="javascripts/modernizr.custom.86912.js"></script>
<script src="coffeescripts/templates.coffee" type="text/coffeescript"></script>
<script src="coffeescripts/jsons.coffee" type="text/coffeescript"></script>
<script src="coffeescripts/main.coffee" type="text/coffeescript"></script>

整理後のscript要素(20行)

<script src="lib/jquery-2.1.1.min.js"></script>
<script src="lib/underscore.js"></script>
<script src="lib/underscore.string.js"></script>
<script src="lib/backbone.js"></script>
<script src="lib/bootstrap.js"></script>
<script src="lib/coffee-script.js"></script>
<script src="lib/createjs-2013.12.12.min.js"></script>
<script src="lib/imgLiquid.js"></script>
<script src="lib/jquery.bxslider.js"></script>
<script src="lib/jquery.ellipsis.js"></script>
<script src="lib/jquery.heightLine.js"></script>
<script src="lib/jquery.localscroll.js"></script>
<script src="lib/jquery.maximage.js"></script>
<script src="lib/jquery.scrollto.js"></script>
<script src="lib/masonry.pkgd.js"></script>
<script src="lib/paper-full.js"></script>
<script src="lib/jquery.smoothScroll.js"></script>
<script src="coffeescripts/templates.coffee" type="text/coffeescript"></script>
<script src="coffeescripts/jsons.coffee" type="text/coffeescript"></script>
<script src="coffeescripts/main.coffee" type="text/coffeescript"></script>


12:40~ 無駄なCSSを削除

目的:CSSファイルサイズの削減
JavaScriptと同様、CSSも結構な数のファイルをロードしていて、相当な数が削減できることが予想できました。

初期状態のlink要素

<link rel="stylesheet" href="stylesheets/bootstrap-theme.css">
<link rel="stylesheet" href="stylesheets/bootstrap.css">
<link rel="stylesheet" href="stylesheets/jquery-ui.css">
<link rel="stylesheet" href="stylesheets/jquery-ui.structure.css">
<link rel="stylesheet" href="stylesheets/jquery-ui.theme.css">
<link rel="stylesheet" href="stylesheets/jquery.bxslider.css">
<link rel="stylesheet" href="stylesheets/jquery.maximage.css">
<link rel="stylesheet" href="stylesheets/normalize.css">
<link rel="stylesheet" href="stylesheets/tabulous.css">
<link rel="stylesheet" href="stylesheets/main.css">

この工程では11:00にインストールした grunt-uncss を使用してCSSを整理しました。
grunt-uncssは、特定のHTMLから使用されているCSSプロパティのみを抽出してくれるgruntプラグインです。


ちなみに、今回のチューニング対象ページは一部Ajaxで書き換えている箇所があったため、Chrome DevToolsのElementsタブからAjax通信後の状態のHTMLをコピーして別ファイルに保存してから実行しました。
※こうしないと、JavaScriptで後から描画するDOM要素で使用されているCSSプロパティが出力されません。

必要無いCSSプロパティを一気に省いたことでスコアもぐーんと伸び、この時点で初めてリアルタイムランキングで1位になりました。
この「ランキングがリアルタイムに見える」仕組み、チューニンガソンらしい臨場感があって楽しいです(常時他人と比較され続けるプレッシャーもかなりのものですが…)。

13:10~ CSSスプライト用の画像とCSSの生成

目的:HTTPリクエスト数の削減
CSSスプライト化が一切施されていなかったので、ページ内に含まれている画像をスプライト化する作業に入りました。
とはいえ、意地悪なことに提供されたファイル群には使用されていない画像ファイルも含まれています。
そこで、Chromeブラウザで開いたページを [ファイル] - [ページを別名で保存] から保存して、ページ内で使用されている画像ファイルだけを取り出しました。
ただ、この方法だとCSS内で背景画像に設定されている画像はローカルに保存されないので、それらだけはCSSファイル内を ".png" のようなキーワードで検索して手作業で保存しました。

スプライト画像とCSSはglueを使用して生成しました。

13:40~ CSSスプライトを適用しながらマークアップの掃除 Part.1

目的:HTTPリクエスト数の削減、DOM要素数の削減、HTMLファイルサイズの削減
上記作業の続きです。地味にこの工程が一番時間がかかったかもしれません。
ひたすらimg要素を削除し、親要素に上記のCSSスプライト画像を適用するクラスを付与していきます。
更に、無駄に深い入れ子構造になったマークアップが散見されたので、それらもどんどん削っていきました。

この辺りでそこそこ疲れてきたので、途中で止めていったん別の作業へ移ることにしました。

14:10 スプライト画像の減色

目的:画像ファイルサイズの削減
画像の圧縮は grunt-image を使用して行いました。
PNG画像の場合は少々画質が落ちてしまいますが、ファイルサイズが半分以下になる場合も多いので積極的に使います(普段の業務でも)。

14:20 JPG画像の画質向上

目的:スコア計測システムによるチューニング前後の表示差異検出回避
PNG画像の画質が荒くなったところで、評価項目の一つである
チューニング前後の表示差異(ImageMagickによる平均画素数比較で閾値を超えるとNG)
でFailになるようになってしまいました。
差分ファイルを見ると、特にJPG画像の圧縮ノイズが差分としてたくさん検出されてしまっていました。

そこで、11時台に画像ファイルの最適化を行った時に保存してあったpsdファイルから、再度画質をあげてJPGファイルを保存しなおしました。
念のためpsdファイルを取っておいて良かった…!

14:50~ CSSスプライトを適用しながらマークアップの掃除 Part.2

13:40の作業の続きです。
なんとかCSSスプライト化とDOM要素の削減がほぼ完了しました。

16:30~ 無駄なJavaScript実装を削除

目的:JavaScriptのファイルサイズの削減
CreateJSなど、アニメーションライブラリをロードするscript要素がHTMLに含まれていたのですが、ページ内には特に凝ったアニメーション演出は見当たりませんでした。
しかし、このライブラリのscript要素を削除するとJavaScriptエラーが起きてしまったので、アニメーションライブラリを使用した何かしらの実装が入っているようでした。

ページ内で読み込まれているJavaScriptファイルを参照すると、案の定canvas要素の初期化コードが入っているのを見つけました。
「画面内にcanvas要素が存在しなければこれらのコードは必要ない可能性が高い」と考え、Chrome DevtoolsのConsoleタブから下記のJavaScriptを実行して確認しました。

実行したJavaScript

document.getElementsByTagName('canvas');

結果

[]

上記のJavaScriptは、DOMツリーにcanvas要素が存在するか確かめるためのコードです。
結果が`[]`(=空っぽの配列)だったことから、今開いている画面にcanvas要素は一つも存在しないことが確認出来ました。
この結果からcanvas要素の初期化コードは無駄な実装だと判断し、該当箇所の実装をぱっと見で判断できる範囲で取り除きました。
厳密にはcanvas要素自体を追加/削除する実装が入っている可能性もゼロでは無いですが、そこまで実装を追うと時間がかかり過ぎるため確認は上記の内容程度にし、あとは「JavaScriptコードを削除した後にざっくりと動作確認する」という手法で進めました。

また、CoffeeScriptファイル(*.coffee)もJavaScriptファイル(*.js)に変換し、それに伴って不要になったcoffee-script.jsをロードするscript要素も削除しました。

17:20~ CSSの圧縮

目的:CSSのファイルサイズの削減
11:10に見つけていたCSSの構文エラーを修正してから、grunt-contrib-cssminを使用してcssを圧縮します。
HTML内のlink要素も圧縮版をロードするように書き換えました。

17:25~ JavaScriptの結合・圧縮

目的:JavaScriptのファイルサイズの削減、HTTPリクエスト数の削減
JavaScriptファイルの結合にはgrunt-contrib-concatを、圧縮にはgrunt-contrib-uglifyを使用しました。
CSSと同様に、HTML内のscript要素も圧縮版をロードするように書き換えました。

17:30~ JavaScript、CSSをインライン化

目的:HTTPリクエスト数の削減
今回のレギュレーションはキャッシュも考慮する必要がないので、JavaScriptファイルとCSSファイルを別ファイルとして保存するのではなく、HTMLファイル内にソースを丸ごと埋め込む施策を実施してみました。
これがうまくいけば、JavaScriptとCSSの2ファイル分のHTTPリクエストが削減できることになります。

しかしこれは暗黙のルール違反だったようで、スコア判定システム側でFailになってしまったので元に戻しました…。残念。

17:30~ 全画像の圧縮

目的:画像ファイルサイズの削減
スプライト画像だけはgrunt-imageで圧縮したものの、他のほとんどの画像はそのままだったので、このタイミングで全画像に対してgrunt-imageで圧縮処理を動かし始めました。
20分程度で全画像の圧縮が終ったので、その後JPGファイルだけImageOptimも通してからコミット。

17:35~ HTMLの圧縮

目的:HTMLファイルサイズの削減
HTMLファイルを圧縮するとチューニングしにくくなるのでこの時間まで避けていたのですが、そろそろ残り時間もなくなってきたのでgrunt-contrib-htmlminを使用してHTMLファイルを圧縮しました。
念のため、残りの時間は本体のコードを触らない事にします。

17:40~ .htaccess追加

目的:JavaScriptファイルサイズの削減、CSSファイルサイズの削減、HTMLファイルサイズの削減
たぶん無理だろうなあと思いつつも、試しにgzip圧縮を有効にする設定を記述した .htaccess をコミットしてスコアに反映されるか試してみました。
結果、やっぱり反映されませんでした。。

17:55~ 昼食の残りを食べる

やっとゆっくり出来る状況になったので、お昼に頂いたサンドイッチの残りを食べながら終了時刻を待ちました。

18:00~ 審査タイム

他の参加者のエンジニアさん達と、どんなチューニングをしたか等を雑談しながら結果発表を待ちます。

19:00~ 結果発表

優勝してた!

勝因は何だったのか

フロントエンドのチューニング技術は社内外の優秀なエンジニアが積極的に展開してくださっているので、恐らくどのプロジェクトもある程度似た事をされているのではないかと思います。

そんな状況下で勝負するには「何よりも作業スピードが肝心」と考え、割り切って次々に施策を実装する動き方が出来たのが良かったのかなぁと思っています。

最後に

この日に行った主なチューニングをまとめておきます。
  • 使用していないJavaScriptライブラリの削除
  • 使用していないCSSを削除
  • 無駄なDOM要素の削除
  • 無駄なJavaScript実装の削除
  • CSSスプライト化
  • HTML・JavaScript・CSSの結合およびminify
  • 画像解像度、容量の最適化
上記のチューニングを行った前後の数値は以下のようになりました。
チェック項目オリジナルチューニング後
HTMLファイルサイズ10547 バイト2688 バイト
CSSファイルサイズ292780 バイト22183 バイト
JavaScriptファイルサイズ1952540 バイト229505 バイト
画像ファイルサイズ12235961 バイト904482 バイト
リクエスト数14747
DOM要素数578449

自分の知識の範囲でやるべきと考えたチューニングを取捨選択して優勝できたので、とても嬉しい結果でした。
優勝賞金は、個人的な研究用に来年発売されるApple Watchを購入する資金にしようと思います!

最後までお読み頂き、ありがとうございました。
はじめまして。CyberSS所属の水野 寛と申します。普段はディレクター/HCD専門家として、Webサイトの分析や改善を担当しています。

Webサイトやアプリ制作の現場では、UXを向上させるにはどうすればよいか、試行錯誤が求められます。しかし、そのUXについて、いまいち捉え方がわからないと感じられている方が多いのではないでしょうか。

そこで今回は、ズバリ「UXとは何か」について、ご説明させていただきます。さらに、今すぐ制作に活かせる考え方として「UXをデザインするためのポイント」「UXを検証するための視点」について、事例を交えてご紹介いたします。

1.UXとは何か


国際規格であるISOには、UXが次のように定義されています。
製品やシステム、サービスの利用、および/もしくは予想された使い方によってもたらされる人々の知覚と反応。 (ISO 9241-210)

ちょっとわかりづらい表現ですよね。言い換えると、UX(ユーザーエクスペリエンス)とは、ユーザーがサービスの利用を通して感じる気持ちの動きです。
 ※以降、本文中の「サービス」はWebサービスに限定して説明を進めることにします。

■UXは目的でUIは手段

よく制作の現場では、言葉の表現として「UX/UI」のように、UI(ユーザーインターフェース)と一緒に用いられることがありますが、この2つは本質的に意味が異なります。

 ・サービスを通してユーザーに良いUXを提供する(目的)ために、
 ・どのようなUIにするか(手段)を考える

このように、作り手から見た場合のUXとUIは、「目的」と「手段」の関係です。
例えば写真投稿SNSのInstagramを例にすると、次のように説明ができます。

 ・UX=日常の瞬間を印象的に残して、友達同士で共有できる体験
 ・UI=撮った写真に味わいのあるフィルタをかけて、簡単にシェアできる写真投稿画面

サービスを通してユーザーにどんな体験をしてもらいたいかを描き出す。そして、描き出した体験(UX)を届けるために、UIを含めてどうやってサービスを提供すればよいかを設計する。この一連の作業をUXデザインといいます。

描き出された体験の全体像は、制作の道標として、プロジェクトの様々な局面で機能します。
例えば、一緒に手を動かすチームの間でも、ユーザーについての共通認識をもてる。その結果、自分たち本位でUIを考えてまったり、UIの方向性が迷走する、といった事態を防ぐことができます。

■UXに影響を与える3つの要素

提供するUXを明確にするには、UXをとりまく周辺の要素を把握しておくことが重要です。その要素とは、ユーザー・UI・コンテキストの3つです。

まず、ユーザーとUIの関係をみていきます。

ユーザーは何らかの「目的」をもってサービスを使いはじめます。例えば、1pixelブログを見に来るユーザーは「制作業務に活かせるノウハウを継続的にチェックする」といったの目的をもっています。
サービスの利用は、PCサイト等のUIを介して行います。そのやりとりの結果として、良いUX(達成感や充足感)を感じるわけです。



一方で、UIとユーザの間には、コンテキスト(文脈)が介在します。コンテキストは、一連の行動に制約を与える外部要因。具体的には、ユーザがいる場所、時間帯、心理状況があります。1pixelブログを例にすると「会社のオフィスでの昼休み中に見ているけれど、あまり十分な時間がとれない」といった状況がコンテキストです。


2.UXをデザインするためのポイント


UXデザインは、ユーザー・UI・コンテキストの3つの要素をはっきりさせることから始めます。これらの要素をヌケモレなく検討するには、「5W1H」の枠組みで考えると効果的です。先ほどの図にプロットすると、次のようになります。



今回は、社内のUX勉強会で「音楽SNSアプリ」のモックアップを制作した事例を通して、「5W1H」でUXの要件を整理する流れをご紹介したいと思います。
 ※ 制作したアプリは勉強会用の成果物なので、サービスリリースはしていません。

■ユーザーを定義する(Who/Why/What)

まずは、誰が、どんな理由で、何をしようとしているか、はっきりさせます。
今回は、社内インタビューによる現状把握を行いました。そこから分析できた洞察にもとづいて、ターゲットとなるユーザー像をまとめています。

Who(ユーザーの属性)
ライトな音楽好き、30歳前後の男性。日常的にスマホで音楽を聞いている。音楽は生活の中に自然にあるもので、感情を調整できる手段だと思う。
Why(目的)
ほぼ毎日音楽を聞いているものの、昔から聞いている特定のジャンルやアーティストに限定されてしまっていて、ちょっと飽き気味。幅広くいろいろな音楽と出会いたいと思っている。そのために、時間やお金は掛けたくない。
What(ゴール)
自分にぴったりの音楽を見つける。



インタビュー結果からユーザーのニーズを分析

勉強会では、ユーザの目的とゴールを描けたタイミングで、実際に提供するサービスの大枠をブレストしました。
いろいろ出てきたアイデアの中から、「自分の生活のシーンや気分にぴったりの曲を、気軽に見つけられる音楽SNS」という構想を考えてみました。特徴は次の2つです。

 ・気に入った曲を投稿する:ミュージックアプリを聴いているときに自分の感情が動いたら、その曲の内容と、その時の気分を添えて投稿することができる
 ・気分にピッタリの曲を探せる:他の人が投稿した曲のなかから、今の気分にあった新しい曲を探せる

■コンテキストを想定する(When/Where)

次は、ユーザーとサービスの接点(タッチポイント)を特定し、具体的なサービスの利用場面をイメージします。利用場面は複数あるのが普通ですが、すべてを網羅的に洗い出すのではなく、ユーザとの接触頻度の高い主要な場面に絞り込むようにします。
今回はその中の一場面を例としてあげてみます。

When(時間)
会社からの帰宅途中。
Where(場所/環境)
電車の中。へこんでいたり、応援してほしいと思った時。気分をあげるために曲を探そうと思った。

■アクティビティからUIを考える(How)

ユーザーとコンテキストが特定できたら、サービスを使ってどんなアクティビティ(行動)をとるか、を考えます。アクティビティにそってユーザーが満足するはずの手順をイメージすることで、自ずと必要な機能やコンテンツがみえてきます。次ののように、シナリオの形式でまとめると、具体的なシーンが想起されやすくなります。

How(アクティビティ)

場面:帰宅中の電車の中。気分の上げる曲を見つける

シナリオ:癒し系の曲と言うよりは、自分を応援してくれるソウルフルな曲を探したい。ついでに、まだ出会ったことの無いアーティストが見つかるといいな。このサービスを使うと自分の『憂鬱な気分』と『今の時間帯』で曲をリクエストできる。リクエストすると、自分と音楽の趣味が近くて、かつ同じ状況におかれたから人から紹介されたおすすめ楽曲を、いくつか確認できた。


アクティビティシナリオ(上)と対応するUIスケッチ(下)

各場面ごとに、ユーザーがどのような行動をとるか、できるだけ詳細に描くことがポイント。簡単なイラストがあると、さらにイメージが想起されて、アイデアが出やすくなります。
行動のステップはユーザーのタスクに分割します。このタスクに基づいて必要な画面上の要素を考えます。これによって、コンテキストに沿ったUIを検討することができます。

以上の手順を踏むことで、作ろうとするサービスが提供するUXを明確にしながら、要件を詰めていくことができます。

3.UXを検証するための視点


実際に制作に入ったら、ユーザーが求めるUXを提供できているか、制作の要所でチェックしましょう。
UXには、時間軸に応じた3つの段階があり、それぞれの段階で満たすべき要件が違ってきます。順番に見ていきます。

① 一時的・瞬間的UX

UIを操作する際に直接的に感じる時の印象が、「一時的・瞬間的UX」です。例えば、1画面の中でのわかりやすさや、デザインの良さ、気持ちいいと感じられる操作感といった、表現やインタラクションに関わる反応。サービス完成前でも、UIのスケッチ、ビジュアルデザイン、実装前のモックアップの段階でそれぞれ検証できます。


完成した音楽SNSのデザイン

しかし、この観点だけを追求してしまい、コンテキストを考慮することを忘れてしまうことがあります。例えば、見た目はキレイだけど必要な機能がみあたらない、といった問題が出てしまいます。これを防ぐために、次のエピソード的UXを意識します。

② エピソード的UX

あるコンテキストに置かれたユーザーが、サービスの一連のアクティビティを通して感じる印象が「エピソード的UX」。アクティビティをエピソードとして捉え、ユーザーがサービス側の想定通りに行動し、満足感を得られるかをチェックします。
この段階のUXを検証するには、5W1Hで作成したシナリオに沿って、試しに、ユーザーになりきってサービスを利用してみると効果的です。「一時的・瞬間的なUX」の観点では気づかなかった、思わぬ問題点を見つけることがあります。


アクティビティシナリオを用いて一連の体験を検証する

③ 意味的・累積的UX

サービスは、ユーザーに繰り返し利用してもらわないと、ヒットサービスに成長しません。そのために、「また使いたい!」という利用後の必要性を感じてもらわなければいけません。
一方で、サービスを初めて知った時に、「使ってみたいかも」と利用前の期待感をもってもらえなければ、そもそも利用すらしてもらえません。
このような、サービスを使う必要性や、事前の期待感は、ユーザーにとってのサービスを使う意味とも言い換えることができます。これが「意味的・累積的UX」です。この段階のUXは、2つの視点でチェックします。

 ・サービスのキャッチコピーに魅力があるか
 ・キャッチコピーの内容がサービス全体に適用されているか

キャッチコピーは、サービスの提供価値をあらわしたものです。作るサービスのキャッチコピーには、競合サービスには無い差別化ポイントや、魅力を感じられる特徴がちゃんと落とし込まれているでしょうか。そして、ユーザーの気持ちでサービスを利用してみた場合、キャッチコピー通りの実感が得られるかを確認しましょう。


音楽SNSのキャッチコピー例

最後に


良いサービスを生み出すには、ユーザーについての十分な理解が欠かせません。そうは思っていても、いつのまにか、作り手本位で要件を考えてしまうものです。もちろん、作り手の発想や思いを中心に考えていくことは重要ですが、サービスの価値は最終的にユーザが判断をします。

UXデザインを制作フローに組み込むことにより、制作側の視点をユーザへの「共感」に向けさせてくれます。制作の道標を見失ってしまった際は、ぜひ5W1HをつかってUXの要件を整理してみてください。

最後までお読みいただいて、ありがとうございました。
みなさま、こんにちは!
2013年度新卒入社の吉成祐人(@y_yoshinari)と申します。

昨年の12月に社内フレームワークに関する記事を執筆させていただいたので、9ヶ月ぶりの執筆です。⇒近日公開予定JSフレームワークBeez

現在私はなぞってピグキッチンというサービスのフロントエンドの実装を担当しています。

先日、弊社のインターンシップで『フロントエンドの実装作業の効率化』に関する講義をさせていただいたので、今回はその講義スライドを共有したいと思います。


ではでは。



って感じで終わらせても良いのですが、さすがに既に公開しているスライドをペケっと貼っただけだと味気ないですね。

なので、今回はこのスライドの中で紹介している社内ライブラリbucks.jsに関しても簡単にですが書きたいと思います。

フロー制御ライブラリbucks.js

bucks.jsは弊社がオープンソースで公開しているフロー制御ライブラリです。
Github: https://github.com/CyberAgent/bucks.js

フロー制御ライブラリを用いるとプログラムの処理の流れを制御できるようになります。
それにより、非同期処理が入った際にプログラムを綺麗に書けるようになります。

1つ例を挙げるとすると、しばしばJavaScriptに対する批判の対象となるコールバック地獄が減ったりします。

非同期処理

まず、非同期処理の説明をします。

非同期処理というのは単純に言うと、通常のフローから外れて実行される処理です。
例として、setTimeoutによる遅延処理やXMLHttpRequestによる通信処理があります。

・setTimeout
setTimeoutは第2引数に与えたミリ秒後に第1引数に与えたコールバック関数を実行します。
第1引数のコールバック関数は非同期の処理となり、この関数の実行を待たずにsetTimeout以降の処理は実行されます。

例を挙げます。
console.log('a')
setTimeout(function() {
console.log('b');
}, 1000);
console.log('c');
出力は下記のようになります。
a
c ← setTimeoutのコールバック関数の実行を待たずに出力される
b ← 1000ミリ秒後に出力される

・XMLHttpRequest
XMLHttpRequestの通信も同様です。
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function(e) {
if (xhr.readyState === 4) {// 通信処理が終わったとき
if (xhr.status === 200) {// 通信が成功したとき
console.log(xhr.responseText);// 通信結果
}
}
}, false);
xhr.open('GET', 'data.json');
xhr.send(null);
これはreadystatechangeのイベントが走ったタイミング(xhrオブジェクトの状態が変わったタイミング)で、コールバック関数が実行されます。

bucksの説明

それではフロー制御ライブラリのbucksを使い方と合わせて見ていきます。

まず、newを用いてbucksのオブジェクトを生成します。
var bucks = new Bucks();
bucksのaddメソッドを用いて走らせたい処理を順番に追加します。
各々の処理は、nextが叩かれたタイミングで次の処理へと進みます。
bucks.add(function(err, res, next) {
// 行いたい処理1
next();// 次にaddされている処理に進む
});
bucks.add(function(err, res, next) {
// 行いたい処理2
next();// 次にaddされている処理に進む
});
bucks.add(function(err, res, next) {
// 行いたい処理3
next();// 次にaddされている処理に進む
});
ただ、この時点ではbucksに処理が追加されているだけでまだ実行はされていません。

bucksのendメソッドを呼ぶ事により、追加された処理が逐次実行されていきます。
bucks.end();// 全ての処理を逐次実行
bucksのaddメソッドは自身を返却するので、全ての処理は続けて書く事が可能です。
それにより、上記の処理は下記のようにまとめて書く事が出来ます。
new Bucks()
.add(function(err, res, next) {
// 行いたい処理1
next();// 次にaddされている処理に進む
})
.add(function(err, res, next) {
// 行いたい処理2
next();// 次にaddされている処理に進む
})
.add(function(err, res, next) {
// 行いたい処理3
next();// 次にaddされている処理に進む
})
.end();// 全ての処理を逐次実行
ちなみにコールバック関数の引数の、errとresとnextはそれぞれ下記になります。
err :前の処理でエラーが発生した場合、そのエラー内容が格納される。
res :前の処理でnextに引数を渡して実行した場合、その内容が格納される。
これにより前の処理の結果を次の処理に渡す事が出来る。
next:次の処理へと処理を進める為のコールバック関数。
また上記の逐次処理だけでなく、parallelというメソッドを用いることで並列処理を実現する事もできます。
new Bucks()
.parallel([// 処理1~3を並列で実行する
function(err, res, next) {
// 行いたい処理1
next();
},
function(err, res, next) {
// 行いたい処理2
next();
},
function(err, res, next) {
// 行いたい処理3
next();
}
])
.add(function(err, res, next) {// 処理1~3のnextが全て叩かれてから処理が走る
// 行いたい処理4
next();
})
.end();
他にもBucksを用いるといろいろと出来るのですが、詳しくはGithubのREADME.mdを見ていただければと思います。
Github: https://github.com/CyberAgent/bucks.js

この後は、非同期処理が入ってきた際に逐次処理と並列処理をbucksでどのように書けるのかを見ていきます。

非同期処理の入った逐次処理

1000ミリ秒後にaと出力して、
その2000ミリ秒後にbと出力して、
その3000ミリ秒後にcと出力して、
その4000ミリ秒後にdと出力して、
その5000ミリ秒後にeと出力するプログラムを書くとします。

その際のコードは下記のようになります。
setTimeout(function() {// 1000ミリ秒遅延させる
console.log('a');
setTimeout(function() {// 2000ミリ秒遅延させる
console.log('b');
setTimeout(function() {// 3000ミリ秒遅延させる
console.log('c');
setTimeout(function() {// 4000ミリ秒遅延させる
console.log('d');
setTimeout(function() {// 5000ミリ秒遅延させる
console.log('e');
}, 5000);
}, 4000);
}, 3000);
}, 2000);
}, 1000);
どんどんコールバック関数が入れ子になっていきますね。
これが俗にいうコールバック地獄です。

これをbucksを用いて書くと下記のように書く事が出来ます。
new bucks()
.add(function(err, res, next) {
setTimeout(function() {// 1000ミリ秒遅延させる
console.log('a');
next();
}, 1000);
})
.add(function(err, res, next) {
setTimeout(function() {// 2000ミリ秒遅延させる
console.log('b');
next();
}, 2000);
})
.add(function(err, res, next) {
setTimeout(function() {// 3000ミリ秒遅延させる
console.log('c');
next();
}, 3000);
})
.add(function(err, res, next) {
setTimeout(function() {// 4000ミリ秒遅延させる
console.log('d');
next();
}, 4000);
})
.add(function(err, res, next) {
setTimeout(function() {// 5000ミリ秒遅延させる
console.log('e');
next();
}, 5000);
})
.end();
コード自体は長くなってしまいましたが、コールバック地獄が解消されて処理の流れを追いやすくなったと思います。

またbucksにはdelayという遅延メソッドも用意されているため、下記のような書き方も可能です。
new bucks()
.delay(1000)// 1000ミリ秒遅延させる
.add(function(err, res, next) {
console.log('a');
next();
})
.delay(2000)// 2000ミリ秒遅延させる
.add(function(err, res, next) {
console.log('b');
next();
})
.delay(3000)// 3000ミリ秒遅延させる
.add(function(err, res, next) {
console.log('c');
next();
})
.delay(4000)// 4000ミリ秒遅延させる
.add(function(err, res, next) {
console.log('d');
next();
})
.delay(5000)// 5000ミリ秒遅延させる
.add(function(err, res, next) {
console.log('e');
next();
})
.end();

・おまけ
setTimeoutは下記のようにやれば、コールバック地獄にならずには済むのですが、XMLHttpRequestの通信だともう通信してみるまでコールバック関数が呼ばれるまでの時間が分からないので、コールバック地獄は避けられないと思います。
setTimeout(function() {
console.log('a');
next();
}, 1000);
setTimeout(function() {
console.log('b');
next();
}, 1000 + 2000);
setTimeout(function() {
console.log('c');
next();
}, 1000 + 2000 + 3000);
setTimeout(function() {
console.log('d');
next();
}, 1000 + 2000 + 3000 + 4000);
setTimeout(function() {
console.log('e');
next();
}, 1000 + 2000 + 3000 + 4000 + 5000);

非同期処理の入った並列処理

互いに依存し合っていない2つの通信(fooとbar)を行う状況があり、その通信の結果を用いて画面を生成したい状況があるとします。
var resFoo = null,
resBar = null,
responseCount = 0,
xhrFoo = null,
xhrBar = null;

// foo.jsonへのGET通信
xhrFoo = new XMLHttpRequest();
xhrFoo.addEventListener('readystatechange', function(e) {
if (xhrFoo.readyState === 4 && xhrFoo.status === 200) {
responseCount++;
resFoo = JSON.parse(xhrFoo.responseText);
onEndRequest();
}
}, false);
xhrFoo.open('GET', 'foo.json');
xhrFoo.send(null);

// bar.jsonへのGET通信
xhrBar = new XMLHttpRequest();
xhrBar.addEventListener('readystatechange', function(e) {
if (xhrBar.readyState === 4 && xhrBar.status === 200) {
responseCount++;
resBar = JSON.parse(xhrBar.responseText);
onEndRequest();
}
}, false);
xhrBar.open('GET', 'bar.json');
xhrBar.send(null);

function onEndRequest() {
// 2つの通信がまだ返ってきていなかったら何もしない
if (respponseCount < 2) {
return;
}
createView();
};

function createView() {
// resFoo と resBar を用いて画面を生成
};
これをbucksを用いて書くと下記のように書く事が出来ます。
new bucks()
.parallel([
function(err, res, next) {
var xhr = new XMLHttpRequest(),
resFoo = null;
xhr.addEventListener('readystatechange', function(e) {
if (xhr.readyState === 4 && xhr.status === 200) {
resFoo = JSON.parse(xhr.responseText);
next(resFoo);// 通信の結果を渡してnextを叩く
}
}, false);
xhr.open('GET', 'foo.json');
xhr.send(null);
},
function(err, res, next) {
var xhr = new XMLHttpRequest(),
resBar = null;
xhr.addEventListener('readystatechange', function(e) {
if (xhr.readyState === 4 && xhr.status === 200) {
resBar = JSON.parse(xhr.responseText);
next(resBar);// 通信の結果を渡してnextを叩く
}
}, false);
xhr.open('GET', 'bar.json');
xhr.send(null);
}
])
.add(function(err, res, next) {
// resにはparallelの中のnextに与えた引数が配列で格納されている
var resFoo = res[0],
resBar = res[1];
createView(resFoo, resBar);
next();
})
.end();

function createView(resFoo, resBar) {
// resFoo と resBar を用いて画面を生成
};
bucksを用いる事で、全ての通信が終わっているかどうかの管理を自分でする必要が無くなり、コードの流れも追いやすくなったと思います。
さらに、これはコードの書き方を工夫すればそもそも減らせはするのですが、グローバル変数も減らす事が出来ました。

また、parallelの引数の配列にメソッドを追加すれば、通信と同時に通信と関係ない処理を走らせておく事も出来ます。

まとめ

すごくザックリとした説明になってしまいましたが、使いやすいライブラリなので是非とも1度使ってみてください!
Github: https://github.com/CyberAgent/bucks.js

記事の内容がbucks.jsの内容ばかりっぽくなってしまいましたが、あくまでこの記事のメインの内容は『フロント作業の効率化』のつもりです!
なので、スライドの方も読んでいただけるとありがたいです!

拙い記事ではございますが、最後まで目を通していただきありがとうございました。


はじめまして。 ガールフレンド(仮)でアニメーションを担当しています。峯岸と申します。
本日はガールフレンド(仮)のぷちガールアニメーションの制作に関してご紹介したいと思います。

ぷちガールちゃんとは?

ガールフレンド(仮)ではぷちガールちゃんという機能があり、ゲーム内でバトルをしたりイベントに参加したりするときに応援してくれる小さなガールがいます。
"会いに行く"機能では、ぷちガールちゃんにアニメーションをつけて可愛く動くよう実装されています。




ボーンアニメーションとは?

体にボーンを階層的に設置してゆき、その骨格のつなぎ目を基準にキーフレームで動きをつけてアニメーションをつけていく技法のことです。 スケルタルアニメーションや、スキンドメッシュアニメーションとも呼ばれています。
ガールフレンドでは、アニメーション制作にFlashを使用しているため、ガールの各パーツを関節ごとにムービークリップ分けをし、ボーンアニメーションを実現しています。


制作上の工夫

・ガール素材のスプライトデータ化

ゲームのパフォーマンス向上のため画像はスプライト化し、画像データ2枚(正面向き・横向き)で管理しています。スプライト化することで1つアニメーションを作れば、他のガール画像に置き換えるだけでどのガールにも対応できます。
スプライト化には、自前でスプライト生成ツールを作り自動化をしています。
ガールフレンドでは、Toolkit For CreateJSでFlashをパブリッシュしているので 下に添付したスプライト画像をFlash内でマスクをして制作しています。
※createJSでのスプライトマスクに関しては、佐藤圭明さんの記事をご覧下さい。

・Flashで扱いやすいように、ガールを1つのムービークリップに集約

1つのガールのムービークリップに正面向き・横向きの2種類を持たせ。各表情(目と口)、動きをjavascript側から制御できるよう実装しています。

実際にアニメーションをつけてみる(歩くモーション)

モーション制作は、TFC(Toolkit For CreateJS)の制約上クラシックトゥイーンのみで実装します。
歩くモーションは7つのキーフレームで構成し、最後のキーフレームでは最初のキーフレームと噛み合うように足を戻しきらないところで止めています。(スクリプトでループ制御する際はキーフレームをつくらなくていいです。)


各キーフレームをクラシックトゥイーンでつなぎます。 この時に同時にイージングもつけます。

※イージングとは、加速度の変化です。徐々に早くする事をイーズイン、徐々に遅くする事をイーズアウトと言います。
今回のモーションだと上の画像の1~2,4~5にはイーズアウトを、2~3,5~6にはイーズインを入れる事でより重力感のあるリアルな動きになります。
↓クラシックトゥイーン適応後のぷちガールちゃん

このような形でモーションをつけてゆきます。
かわいいといいのですが。。( ^ω^ ;)

その他ぷちガールちゃんモーション

・手を振るモーション

・恥ずかしいモーション

・寝るモーション


スケルタルアニメーションのメリット・デメリット

メリット
・人間の骨格毎にアニメーションを独立できる(クオリティ面)
・Flashで制作した場合、フレームをコピーできるためモーションを再利用できる(再利用性)
・アニメーションを直感的につけることができる(オーサリング面)

デメリット
・最初の設計は先を見越して柔軟に制作しなければならない(工数面)
・Flashでのオーサリングは慣れが必要(オーサリング面)

最後に

ぷちガールちゃんでは、弊社のスマートフォンゲームにおいて採用実績が多いcreateJSと連携させることでiPhone/Androidともにクオリティを担保しつつ、運用性の高いアニメーション制作が出来ています。 メリット・デメリットを理解し、ボーンアニメーションを効果的に使う事でゲームのクオリティを上げる事が出来ると感じました。

これからも、アニメーションのクオリティアップを追求してゆきたいと思います。
ガールフレンド(仮)をよろしくお願いします!

10月にはTVアニメーションも始まりますので、ぜひご覧下さい!!
http://girlfriend-kari-anime.jp/
みなさんこんにちは。
本日は、1pixel運営委員よりFacebookページのお知らせをしたいと思います。


1pixel公式Facebookページ

今までご利用いただいていたRSSやTwitterに加え、今回新たにFacebookページを用意しました。
Facebookページでは、更新情報のほかに、イベントレポートや小ネタもはさんでいきますので是非いいねして登録してくださいね!

Facebookページはこちら

今回は1回目のコンテンツとして今年の人気コンテンツを紹介しています。
たとえば今年はこんな記事が人気でした。


第10位 JavaScriptテンプレートエンジン「JsRender」のすすめ

jQuery Templatesの後継といわれるJsRenderのメリットと基本的な使い方をご説明しています。




第9位 デッサン研修レポート

サイバーエージェントの美術系大学出身ではないデザイナー向けの研修制度を取り上げています。




第8位 JavaScriptを学ぶ女性のためのコミュニティJS Girls

社内のディベロッパーが女性がJSを学ぶためのキッカケに開催したイベントを紹介しています。




第7位 ClipMenuをJSで拡張して、素敵なコピペライフを

ユーティリティソフトClipMenuをJSで拡張する方法とサンプルをご紹介しています。




第6位 非エンジニアが知ってると得するUnityの知識

デザイナーでも知っていると得するUnityの基礎知識をご紹介しています。

カエルイラスト




そして気になる5位以上は…






Facebookページにてご紹介しますのでこちらからご覧くださいw
こんにちは。

なぞってピグキッチン
のフロントエンドを担当しているgoohtaniです。

今回、なぞってピグキッチンで使われている機能の一つであるComposition/Componentについて紹介させて頂きます。

どのような機能か?

Composition/Componentは、ネイティブアプリによくみられる画面遷移をサポートする機能です。
例えば、iPhoneの設定アプリではユーザ操作に応じて以下のように画面が遷移します。


これと同等の画面遷移機能を提供するのがComposition/Componentです。

CompositionとComponentの役割

CompositionとComponentは和訳すると
Composition : 組み立てられたもの、構成物、合成物、混合物
Component : 構成要素、成分
という意味になります。

これをふまえて、Composition/Component機能でそれぞれは
Composition : Component群をまとめるもの、またComponent間の連携を担うもの
Component : Compositionの構成要素
な立場にあります。

図にすると以下のようになります。



iPhoneの設定アプリに当てはめて考えると、


となります。
Compositon : 設定アプリ本体
Component : 設定アプリ内の各ページ
考えるとわかりやすいかと思います。

なぞってピグキッチンでは、各モジュールは一つのCompositionと複数のComponentで作られるパターンが多く、クエストモジュールは以下の様な作りになっています。



作成例

簡単にですが、Composition/Componentの作成例を示します。

// CompositionとComponentのコンストラクタを用意
var CompositionView = require('quest/view/composition');
var ComponentFirstView = require('quest/view/first');
var ComponentSecondView = require('quest/view/second');
var ComponentThirdView = require('quest/view/third');

// CM(CompositionとComponentをまとめる作業を行うオブジェクト)
CM.create(
'quest'// 生成された構造体名を指定
CompositionView,// Compositionを指定
[ComponentFirstView, ComponentSecondView, ComponentThirdView]// Componentを順に指定
);
これで構造体が作成されます。

操作方法

次に作成した構造体を操作してみます。

// ①開く(画面内に表示させる)
CM.open('quest');





// ②FirstからSecondへ画面遷移
CM.move('quest', 'second');





// ③SecondからThirdへ画面遷移
CM.move('quest', 'third');





// ④履歴を一つ戻る
CM.back('quest');





// ⑤閉じる
CM.close();



このように、Component間の遷移が可能になっています。

Component間遷移中のタイミング

また、Componentは遷移中の様々なタイミングをキャッチすることが可能になっています。


onBeforeMoveIn - 自身(=Component)が画面内に遷移する直前
onEndMoveIn - 自身が画面内に遷移した直後
onBeforeMoveOut - 自身が画面外に遷移する直前
onEndMoveOut - 自身が画面外に遷移した直後

これにより、
「遷移前後にローディングを表示する」
「遷移後に非同期処理を実行し、完了時に○○する」
といったことが容易に行えるようになります。

さいごに

機能の紹介だけで終わってしまいましたが、
是非、なぞってピグキッチンをプレイして頂ければと思います。