皆様はじめまして、2013年新卒入社の小笠原と申します!
現在アメーバゲーム部門にて、県vs県のカードバトルゲーム・天下統一クロニクルのデザイン全般を担当しています。

今回は、ソーシャルゲームの運用には欠かせないガチャの訴求デザインについて、
天クロが大切にしている考え方やノウハウをご紹介出来ればと思います。

※この先登場するガチャはこの記事の為に用意したサンプルなので、実際にゲーム内で引く事は出来ません…!ご容赦下さい。

天下統一クロニクルとは


「坂本龍馬」「日光東照宮」「ぬらりひょん」など、各地の名物や偉人をテーマにしたカードを武器に、全国47都道府県が戦いを繰り広げるバトルゲームです。
全国の皆様に支えて頂き、この9月にめでたく2周年を迎えます!


ガチャの訴求デザインとは

ソーシャルゲームの中で販売されるガチャの魅力を伝えるための、
バナー等のデザインの事を指します。
ゲームのテイストやルールによってデザインは様々ですが、根本の役目は全て
「お客さんの目を引き、ガチャガチャの魅力を伝え、実際に引いて貰う」事です。


(左が天クロのガチャ訴求バナー、右は天空のクリスタリアのもの)

ユーザーさん達が強く育って上級者向けのガチャが増えると、1本のバナーに入れる情報量も多くなってきます。
そうした時に陥りがちな罠が、沢山の要素を豪華に盛り過ぎて、ゴチャついてしまうこと。


ガチャの魅力を最大限理解して貰うためには、きっちりと情報の優先度を付けた上で、
豪華に盛る所は盛り、抑える所は抑える事が大切です。
一見派手なだけに見える訴求デザインには、お客さんにガチャの魅力を伝え切るための工夫がたっぷり詰まっているのです…


天クロの制作フローをご紹介

★まずはプランナーさんからの仕様共有

ガチャから出てくるカードや貰えるアイテムを始め、
ガチャの仕様と売りとなるポイント、ターゲットとするユーザー層などを一通り共有して頂きます。

天クロではこのタイミングで必ず、
売りとなるポイントを訴求したい順に、優先度を付けて共有して頂くようにしています。



ここをしっかりすり合わせておくと、次にご紹介する情報整理が格段にし易くなる上、「大事な事が全然訴求されていない」等の理由で修正が発生する事も無くなって来るので、オススメです!

今回は上級ユーザー向けの訴求なので、
"MAX攻撃力34731"の優先度が高め(上級者にはその数値がどれだけ魅力なのかが分かるため)
となっています。

逆に初心者ユーザー向けの場合は
マニアックな情報を避け、値段やキャライラストの美しさを押し出して魅力を感じて貰った方が良い場合もあります。

同じ訴求内容でもターゲットとするユーザー層によって情報の優先度は大きく変わって来るので、
今一度「何を目指したガチャなのか?」をしっかり共有する事を心掛けています。


★各画像に盛り込む情報の整理

天クロでは、ガチャ1本につき様々な種類の訴求画像を作成します。
どの画像も掲載位置や、閲覧されるシチュエーションが少しずつ違って来るので、盛り込むべき情報も全て同一ではありません。

各画像の役割は、ざっくり分けると下の図のようになります。



①のマイページバナーからは、ひと目で魅力を伝えるために細かい情報は極力削り、
③のガチャ全体バナーには購入の決め手になり得る情報はなるべく入れ込む事が多いです。

④のガチャ台バナーでは、「SR出現割合○倍中!」など、今引くと何がお得なのかをメインで伝えたり、
「○回引くと○○が貰える!」など、ユーザーさんの目標となる情報を伝えます。

プランナーさんから共有して貰った訴求の優先度を基にして、どの情報を削るか/入れるかを決めて行きます。


★ラフ制作

プランナーさんとの仕様共有が済んだら、まずはラフ制作です。
先に整理した情報を元に、各訴求画像の構成を組み立てて行きます。



ラフを制作する上で特に大切なのが、ユーザーさんの視線の動きを設計することです。
沢山の情報を同時に見せられても、人間の目では処理が追い付きません。

文字の大きさや位置で主張度に差を付け、ユーザーさんの視線を誘導しつつ、
伝えるべき事を重要なものから順に伝えて行くよう意識して構成して行きます。




この時、訴求を順番通りに読み上げて、文章として違和感無く繋がるように組むのがコツです。
上の図の通りに視線が誘導できれば、

「ついに解禁!史上最強SSR!(SSR徳川家康 MAX攻34731) 3回引くとSSR50%チケットGET! 合戦薬も毎回貰える!」

となります。

視線の誘導に失敗すると、極端な例ですが

「史上最強SSR! 合戦薬も毎回貰える!ついに解禁! 3回引くとSSR50%チケットGET! SSR徳川家康 MAX攻34731」

という具合に支離滅裂な訴求となり、情報が綺麗に伝わらないので注意が必要です。


★仕上げ

ラフをプランナーさんと確認してGOが出たら、いよいよ仕上げをして完成となります。




仕上げをする上で大切な事も、根本的にはラフの時と同じです。
重要な情報から順に、主張度に差を付けて装飾することで、ユーザーさんの視線を誘導して行きます。

この時に意識すると仕上がりに差が出るのが、「手前/奥」の概念です。

ドロップシャドウなどの効果や、色のコントラストを駆使して「真っ先に見て欲しい情報は手前」「それ以外は奥」と言う具合に差を付けてやると、
要素が多い画面の中でも視線が迷わなくなって行きます。



特に美麗系のカードゲームなどは、イラストが華美で主張が強い場合も多いので、いかに見やすく仕上げてやるかが腕の見せ所です。


実際にガチャが出た後は…

ガチャが無事リリースされて販売期間が終了したら、プランナーさん達と振り返り会をします。
ガチャを引いて下さったユーザーさんがどんな行動を取ったのか数字から読み取り、次のデザインに活かす場です。

例えば「4回目まで引くとSR確定!」という訴求をした場合、4回目まで引いて止めたユーザーさんが多ければ、その訴求はしっかり伝わっていた可能性が高いです。(4回目を目指して引き続けたユーザーさんが多かった、と考えられるため)

逆に、3回目で止めた人の数や、5回目で止めた人の数と大差がない場合は…お客さんに上手く伝わっていなかった可能性が高いと言えます。次に手掛けるときは、上手く伝える工夫が必要になってきます。



ソーシャルゲームの運用においてデザイナーの役割は「担当施策に必要なデザインをするだけ」ではなく、
「デザインを通して担当施策を成功させる事」です。作りっぱなしで終えるのではなく、
勝因/敗因を分析して次に活かし、より良いデザインを目指す事が大切だと思っています!


駆け足でしたが、ありがとうございました!

基本的な部分しか触れる事ができませんでしたが、天クロのガチャ訴求デザインの考え方、
いかがでしたでしょうか。

偉そうに語ってしまってお恥ずかしい限りですが、天クロの訴求デザインはまだまだ発展途上です。
訴求画像の中だけにとどまらずUIやページ遷移も含め、ベストを目指して日々トライ中です。

今後も分かり易く魅力的に、かつユーザーさんにワクワクして頂けるようなデザインを模索して行きますので、
天下統一クロニクルをよろしくお願いします!

最後までお読み頂き、ありがとうございました!

ご感想・ご質問・ダメ出しなどお待ちしておりますm(_ _)m
facebook

★先輩方の記事も、よろしくお願いします♪

・愛されるカードグラフィックの制作裏~入門編~
・デザイナー視点のイベント開発
・イラストだけじゃない!カードの価値を上げる3つの実例
はじめまして。2012年入社の渡邉です。
現在は雀王でUnityエンジニアをしております。雀王はiOS,Android向けの本格的な2人麻雀ゲームであり、Unityを用いて開発されました。

雀王公式ページ

この記事の内容は少し発展した使用方法であるため、基本的な部分に関しては以前の記事である中川さんの
非エンジニアが知ってると得するUnityの知識
で細かく書かれておりますので、そちらをご参照ください。


1. Unityにおけるシェーダ


Unityとは様々なプラットフォームに書き出すことが可能なゲームエンジンであり、多彩な表現をすることができます。その一つとしてシェーダという機能が用意されています。
シェーダとは画面に画像や図形を描画する機構で、そこに自分で書いたプログラムを組み込むことで光や影の表現やぼかしなど様々な効果を付けることができます。

UnityはShaderLabという記述文法を採用しています。OpenGLのシェーダ言語であるGLSLとは違い、描画系の設定が指定できるようになっているのが特徴です。
ShaderLabの記述は非常に多機能で様々なサイトでも説明されておりますので、今回は雀王のゲーム画面で作成した表現の概要だけに絞って書かせていただきます。

シェーダ - Unity公式リファレンス


図1. 雀王の麻雀プレイ画面

2. 影の表現


麻雀牌が置かれる盤面はゲーム中最も重要な部分ですが、違和感を減らすための表現の一つに「影」があります。
影がある場合とない場合では印象に大きな差が生じます。


図2. 影を適用した場合としない場合の見た目の違い

Unity標準でも影をサポートしていますが負荷が高く、ライトの設定に依存してしまうため独自の影を作成しました。
今回のゲームでは盤面が平らであることが保証されているので、公式から影の位置を求めることが可能です。
平面を P、ライトの位置 L、麻雀牌の頂点 V の時、直線 LV が平面 P と交差する点をV'とするとVからV'に座標変換する行列を生成することで影を表現することができます。


図3. 平面P, ライトL, 頂点V, 影V'の位置関係

こういったタイプの影がちょうどDirectX(Windowsで利用されているグラフィックスライブラリ)にあるのでそれが参考になります。
D3DXMatrixShadow」という関数が用意されていて、
マイクロソフト公式リファレンスに算出方法が載っています。
手順は以下の通りです。

1. 現在のライト情報から行列をC#で生成
2. その行列をシェーダにセット
3. 頂点シェーダのModel-View-Projection変換のModel-Viewの間に投影する行列を挟む
4. 頂点の位置が高いほど色が薄くなるように乗算
5. 影専用のカメラがRenderTextureに結果を書き込み

v2f vert (appdata_t v) {
v2f o;
float4 wv = mul(_Object2World, v.vertex);
float4 pv = mul(_ProjectMatrix, wv);
o.vertex = mul(UNITY_MATRIX_VP, pv);
float d = (wv.y * _FadeLength - 1) * -1;
o.color = _Color * d;
return o;
}



図4. 影専用カメラに書き込まれた影画像

すると図4のような画像が出来上がります。あとはこれを盤面に配置してスケールを合わせれば簡易影の完成です。
ライトの値を変化させることで図5のようなインパクトの有る影を生成することも可能です。


図5. ライトのwパラメータを変更した場合

影の投影先が平面であれば頂点シェーダに行列計算を任せることで低負荷かつインパクトの有る3Dオブジェクトの影をつくることができます。

3. 麻雀牌の表現


麻雀牌自体にも自作のシェーダを適用しています。

一般的な3Dモデルに用いられるDiffuseシェーダでは、ライトの情報のみに基づいて計算されます。そのため、図6のように思った通りの見た目にすることはなかなか難しいです。


図6. Unity標準のMobile/Diffuseシェーダを利用した場合

逆にライト情報も使わない単純に3Dモデルを表示する高速なシェーダでは図7のように見えます。


図7. Unity標準のUnlit/Textureシェーダを利用した場合

これではいかにも3D感が出てしまっています。
雀王では2.5Dのゲーム画面を目指したかったため今回作成したシェーダでは影と馴染むように盤面に近いほど暗くしました。また、アニメ調にすることで1枚画像のような見た目にしています。

Unityでは次のような短いコードで実現できます。
void vert(inout appdata_full v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input, o);
half s = min(_Max, mul(_Object2World, v.vertex).y) / _Max;
o.fadeColor = lerp(_FadeColor, 1, s);
}
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * IN.fadeColor;
}
half4 LightingRamp (SurfaceOutput s, half3 lightDir, half atten) {
half NdotL = dot (s.Normal, lightDir);
half diff = NdotL * 0.5 + 0.5;
half3 ramp = tex2D (_Ramp, half2(diff)).rgb;
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2) * _Color;
c.a = s.Alpha;
return c;
}


この計算によって、雀王の実際の画面では図8のように表示されています。


図8. 自作の麻雀牌シェーダを利用した場合

表面は白く、盤面に近いほど暗くなっているのがわかるかと思います。また、ライティング結果を段階的にする(トゥーン)処理を挟んでいるため明るい部分と陰になっている部分のメリハリもついています。

4. 最後に


シェーダの全てに関しては説明しきれないため今回は紹介程度になってしまいましたが、工夫次第で様々な表現ができることが伝われば幸いです。
Unityは物理演算や描画処理等を統合的に扱え、個人であれば一部制限付きですが無料でも利用することが可能です。
デフォルトの機能のみで作成してもいいですが、シェーダを活用することで一気に出来る表現が広がります。
公式のサンプルもありますので、試してみると面白いと思います。

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

Blog: 太郎Work
こんにちは。オトギアでフロントエンジニアをやってます。atsumoです。
今回は、現在オトギアで使用中のフレームワークAngularJSのお話を少しさせていただければと思います。

※ AngularJSのバージョンに関してはオトギアで使用中のバージョンである、1.2.16をベースに書かせていただきます。

AngularJSとは



https://angularjs.org/

Googleとコミュニティによって開発されているオープンソースのMV*系のJavaScriptフレームワークです。
同じような種類のフレームワークとして、Backbone.jsKnockout.jsなどが挙げられます。

AngularJSを使用した際のメリット/デメリット

個人的な意見になってしまう部分もあるかもしれませんが、AngularJSを使用するようになり感じたメリットやデメリットを挙げたいと思います。

【メリット】

・楽にWebアプリを作ることができる。特に小規模のものを作る際に簡単に作ることができる。

・設計や実装ルールがあるため、それに従うことでコード品質が保たれやすい。

【デメリット】

・独自の概念や多様な機能に慣れるまで戸惑うことがある。特に慣れてきて色々と機能を使い始めた時に戸惑ったことが多かったです。

・アニメーションを多量に使用する場合利点を生かせないことがあり苦労する。


実際に基本的な使い方を見ていただき、フレームワーク選択の目安になればと思います。

基本的な使い方

ng-model



入力画面に入力すると、入力と同時にHello! 〇〇が更新されているのがわかります。
データが変更されると、値の変更に伴い見た目が変更されます。

Filter

filterは、その名の通りフィルタリングしてくれる機能です。



この機能をライブラリなど使わずに書いた場合、テキストの入力にイベントを設定し値を取得、その入力が変更されたら表示しているテキスト情報から条件に当てはまらないものを非表示にしごにょごにょ・・・
この少し面倒な処理もAngularJSを使うと簡単に書くことが可能です。

この例ではAngularJSにあるfilterを使ってますが、自分で拡張してfilterを作ることも可能です。

Directive

AngularJSの肝とも言えるdirectiveのサンプルです。AngularJSの機能として提供されているもの自体もdirectiveを使っています。(ng-repeatやng-if,ng-show...など)



上の例は、helloという要素(Element)をtemplateで置き換えるという処理です。

AngularJSの基本機能自体でもいろいろなことができるように、directiveを応用することでいろいろなことができるようになります。

オトギアでの使用例

オトギアのどの機能でAngularJSの機能が使われているか簡単に説明したいと思います。

オトギアではユーザーが見れるページだけでなく、データを入力するページ(管理画面)や、データを生成するためのツールなどにもAngularJSを使用しています。

フィルタリングとソート

武具のリストに対して2種類のフィルタリングし、更にソートさせる機能の例です。




Filter 1: 武具の種類( type: 武器/防具、category: 剣/銃/楽器/鈍器/槍/杖)

Filter 2: 武具の属性( attribute: 火属性/水属性/風属性/土属性/無属性)

Sort 1: 新着順/古い順/装備コスト高い順/装備コスト低い順/HP高い順/HP低い順/攻撃力高い順/攻撃力低い順/防御力高い順/防御力低い順/素早さ高い順/素早さ低い順/レベル高い順/レベル低い順

この面倒なFilterやSortもAngularJSのFilter機能でかなり楽に作ることが出来てます。


Directive

オトギア内で使用しているdirectiveの一部をご紹介します。
例えば、カードのサムネイルのdirectiveです。

カードゲームなので当たり前ですが、カードのサムネイルは様々なところで登場します。



例えばcardThumbという名前のelement型のdirectiveを定義した場合、上記のようなサムネイルを使用したいときには、cardThumbというtagが存在するかのように、
<card-thumb card="cardのデータ"></card-thumb>

などの形で使えば、表示する際には適切な形に変換して置き換えてくれます。
これをうまく使うことで、html自体が見やすくわかりやすくなるので、かなり便利です。

シネマジェネレーター(シネマ機能を作るツール)

シネマ

シネマ機能とはオトギア内で流れるキャラクターが話したりするのを物語として見える機能です。


ジェネレーター

この機能の再生情報はJSON形式のデータになっています。
そのJSON形式のデータをエンジニアだけではなく、プロデューサーやデザイナーがJSONを意識しなくてもある程度作ることができるものをシネマジェネレーターと呼んでいます。



ジェネレーター内でシーンの追加や、セリフの追加、背景の追加、声などの音声再生のタイミングなどを設定することが可能です。
(デザインをしてないためすごく簡素化してます・・・)

設定された項目から、JSONデータを生成しそのJSONデータを使用してプレビューすることができます。
やってる事自体は簡単ですが、AngularJSのデータバインディングを使用しないで作ると結構めんどくさい部分が多く、AngularJSさまさまな機能でした。

この画面内で再生が可能なしくみになっており、機能をモジュール化したことで、再生機能自体はゲーム内で使っているものをそのまま使えるようになってます。

参考


AngularJSを始める際に参考にしたサイトなどをご紹介します。

ビデオチュートリアル
https://egghead.io/

AngularJSを使ったbootstrapフレームワーク
http://angular-ui.github.io/bootstrap/


AngularJSをベースにしたモバイル用フレームワーク
http://ionicframework.com/

foundationのAngularJS版
http://madmimi.github.io/angular-foundation/


AngularJSを使ったMaterial Design用フレームワーク
https://github.com/angular/material

さいごに

今回はAngularJSの基本的な機能ベースのお話しか出来ませんでしたが、基本的な機能だけでも便利な機能がたくさんあります。
AngularJSがまだモバイルに最適化された状態であるとは言いにくい部分もあり、苦労した部分などもありました・・・。(AngularJS 2.0に期待)

AngularJSを使ってるゲーム、オトギアを触っていただければ光栄です。

フロントエンドエンジニアの水野(@pocotan001)です。


6月21日、フロントエンドエンジニア向けの勉強会Frontrend in Nagoya福岡に引き続き、名古屋にて開催しました。本稿はそのレポートになります。


名古屋のWebコミュニティHTML5NAGOYA協力の下、約100名の方にご参加いただきました。



フロントエンド・エンジニアのスキルマップと育成のはなし(佐藤 歩)


フロントエンドエンジニアとはなにか、と言う問いかけから始まり、フロントエンドエンジニアが考えなければいけない領域について幅広く触れたセッションでした。


特に、自身の体験を踏まえた育成のケーススタディは、話題自体が貴重なこともあり、ひときわ参加者の興味を引いていました。



アメーバにおけるパフォーマンスの考え方およびその運用手法(泉水 翔吾)


フロントエンドのパフォーマンスにおけるトレンドを包括的に抑えつつ、弊社での運用事例を織り交ぜたセッションでした。


チーム開発において、どのようにパフォーマンスを担保するための施策を行ってきたか。実際に弊社で成果を挙げてきた手法なだけに説得力のある内容でした。



ソーシャルゲーム開発における運用とそのツール(杉本 吉章)


とりわけ息の長いソーシャルゲームのプロジェクトを例に、開発と運用手法について取り上げたセッションでした。


メンテナンスの難しさ、技術的負債が浮き彫りになりやすいチーム開発において、どのように解決すべきか、またその考え方について多くの参加者が耳を傾けていました。



CSS設計とWeb Components(谷 拓樹)


堅牢なCSSを書くための設計や考え方を中心に、真新しいCSSの仕様やWeb Componentsにも触れるなど、幅広い内容を取り上げました。


コードベースの内容にもかかわらず、可読性の高いスライドとわかりやすいスピーチで好評のセッションでした。



ライトニングトーク大会


各セッション終了後は、名古屋の勉強会では恒例(?)のライトニングトーク大会が行われました。


node-webkitやaltJSをテーマを取り上げるスピーカー陣の濃さもさることながら、時間終了のドラを鳴らすドラ娘までもが登場し、なかなかに印象的なものになりました。


最後に

お世話になった地元スタッフの方々、および参加者のみなさまに厚く御礼を申し上げます。ありがとうございました!


そして余談になりますが、今回の登壇者4名を含め、Frontrendのメンバー計10名による共著フロントエンドエンジニア養成読本が7月2日に発売されました。



今回のセッションで取り上げられたテーマはもちろんのこと、フロントエンドエンジニアに必要なトピックを幅広く推し並べた、網羅的な内容の一冊です。


興味を持っていただけた方は、お手に取って頂ければ幸いです。


※Frontrendの最新情報についてはFrontrendのサイトまたはTwitterをフォローしてもらえればと思います。

こんにちは。アメーバ事業本部ゲーム部門の須田(@daasuu)です。
フロントエンドディベロッパーとして、ファーミーの開発・運用を担当しております。

今回は、ファーミーでとても愛されている、プラネットデコ機能の実装に関して工夫した点を少しだけ紹介します。

プラネットデコ機能とは

プラネットデコ機能とは、デコを置いたり"ほし(本体)"や"そら(背景)"を入れ替えたりしてそれぞれがお好みのプラネットを作れる機能です。

planet3planet2


ユーザーが思い思いにデコを飾り、とても可愛いプラネットが毎日たくさん生まれています。

デコを編集する

ユーザーが思い思いにデコをかざるには、ストレスなくデコを置ける仕組みが必要になります。
プラネットデコでは場所を変更したいデコをタップし、指でなぞって移動させます。
指の位置に合わせてデコのY座標、X座標、角度が替わり、デコが動きます。

planet5planet6


ぐりんぐりん指に合わせて動きますので、是非ともスマホブラウザで触ってみてください。

指の位置とデコの位置を合わせる工夫

まずはデコの位置を決める座標となる配列を用意します。
ユーザーが細かく配置できるようにするため、角度は5°ずつ替わり、全部で座標は72個と細かく作ります。また、三角関数を用い半径と角度から傾き、X座標、Y座標を計算します。

コードのサンプルは下記になります
//@param_radius デコを置く際の半径
var returnPositionAry = function(param_radius){
  
  var returnAry = [],
      centerY = 280,//中心座標例
      centerX = 240,//中心座標例
      i;

  
  //座標を生成
  for (i = 0; i < 72; i = i ++){
  
    var _angle = 5 * i,
        _dblRadian = (Math.round((_angle * (Math.PI/180)) * 100) * 0.01),
        _y = (param_radius * Math.sin(_dblRadian) * -1) + centerY,
        _x = param_radius * Math.cos(_dblRadian) + centerX,
        _rotate;
        
    _y = Math.round(_y);
    _x = Math.round(_x);
    
    if(_angle < 90){
    
      _rotate = 90 - _angle;
    
    }else if(_angle >= 90 && _angle < 180){
    
      _rotate = 270 + (90 - (_angle - 90));
    
    }else if(_angle >= 180 && _angle < 270){
    
      _rotate = 180 + (90 - (_angle - 180));
    
    }else if(_angle >= 270 && _angle < 360){
    
      _rotate = 90 + (90 - (_angle - 270));
    
    }
    //画像配置のx、y、角度のセット
    returnAry[i] = {x : _x , y : _y , rotate : _rotate};
  
  }
    
  return returnAry;

};

ARY_POSIITON = returnPositionAry(160);

次に、指の位置と上記で作成した座標の位置を合わせる実装をします。
ここでの注意点は、円の位置は座標は5度ずつずれていても、X座標、Y座標はそれぞれ等間隔でずれていかないため、Y座標、X座標それぞれ幅が大きい部分で判定をします。

座標説明


指の位置と座標の位置を合わせる実装コードのサンプルは下記になります。
//@param_stageX 指のX座標の位置
//@param_stageY 指のY座標の位置
var returnDecoPosition = function(param_stageX, param_stageY){

  var _loopStart = null,
      _loopEnd = null,
      _sizeAdjust = 5,
      centerY = 280,//中心座標例
      centerX = 240,//中心座標例
      _halfRadiusLength = 160 * 0.5,//半径が160の際の計算
      returnPositionNum;

  if(param_stageX > centerX && param_stageY <= centerY){

    _loopStart = 0;
    _loopEnd = 19;

  } else if(param_stageX <= centerX && param_stageY < centerY){

    _loopStart = 18;
    _loopEnd = 37;

  } else if(param_stageX <= centerX && param_stageY >= centerY){

    _loopStart = 36;
    _loopEnd = 55;

  } else if(param_stageX > centerX && param_stageY > centerY){

    _loopStart = 54;
    _loopEnd = 72;

  }


  //配列の位置を決定させるfor文
  for(var i = _loopStart; i < _loopEnd; i ++){

    var _moveEnableFlag = false;

    //X軸で判定する領域と、Y軸で判定する領域のチェンジ
    if(param_stageX < centerX + _halfRadiusLength 
      && param_stageX > centerX - _halfRadiusLength ){       //X軸でポジション判定       if((ARY_POSIITON[i].x + _sizeAdjust) >= param_stageX
      && (ARY_POSIITON[i].x - _sizeAdjust) <= param_stageX ){                  _moveEnableFlag = true;       }     } else {       //Y軸でポジション判定       if((ARY_POSIITON[i].y + _sizeAdjust) >= param_stageY
      && (ARY_POSIITON[i].y - _sizeAdjust)<= param_stageY){                  _moveEnableFlag = true;       }     }     //_moveEnableFlagが指の位置のポジション判定      if(_moveEnableFlag){       returnPositionNum = i;       break;            }   }      //指の位置にあう座標番号を返す。   return returnPositionNum;    };

最後に上述のARY_POSIITONに座標番号を返し、そのx座標、y座標、角度にデコを動かします。

終わりに

プラネットデコ機能の一部分を少しだけ紹介させていただきました。

また、キャプチャ画像ではうまく表現できませんが、プラネットデコは1つ1つアニメーションしており、見ていてとても癒されます

是非ファーミーをプレイし、たくさんのプラネットを覗いてみたり、自分だけのプラネットを飾ってみてください。
はじめまして。
アメーバ事業本部 クロスイノベーション室のグンタ(@gunta85)と申します。

今回はフロントエンド開発用の、
ありとあらゆる依存関係を簡単に解決してくれる、
WebPackというスグレモノをご紹介します。

導入経緯

大きなアプリを開発するにあたり、依存関係を解決してくれるものを探していました。

その中で、RequireJSBrowserifyComponentなども候補に挙がりましたが、
諸々の理由でWebPackを選びました。

特徴の違いについては「WebPack vs Browserify」等で検索してみると良いかと思います。

WebPackのメリット

・どのモジュールシステムでも使える

  • AMD
  • CommonJS
  • UMD
  • ES6
  • Component
  • ...

・どのパッケージマネジャーでも使える

  • NPM
  • Bower
  • Component
  • ...

・CSS、画像、フォントなどがrequireできる

・CommonJSシンタックスでモジュールをインポート

var _ = require('lodash');

_.forEach([1, 2, 3], function(num){
});

・Loaders(変換する便利な機能が盛りだくさん)

  • CSSプリプロセッサー
  • 画像をbase64にエンコード
  • ES6→ES5にモジュール変換
  • ...

・Loaderの書き方

var $ = require('jquery');

// 画像をbase64にエンコードし、読み込みます
require('url!./image.jpg');

// CSSをテキストとして読み込み、headに入れる
// 複数のLoaderをチェーンすることは可能
require('style!css!./style.css');

// モジュールシステムを使わないJSファイルも
// requireをし、ローカル変数にアサインされます
require('imports?hoge=lib!lib.js');

・Configファイル

インラインのLoaderを毎回書くのは大変なので、
configファイルに書きます。
{
    module: {
        loaders: [
            { test: /\.png$/, loader: 'url' },
            { test: /\.js$/, loader: 'es6-loader' },
            { test: /\.css$/, loader: 'style!css' }
        ]
    }
}

・モジュールのパス解析

resolve: {
    moduleDirectories: ['node_modules', 'bower_components']
}

・長いパスもスッキリ書ける

下記を書くより...

./../../../../library.js
./../../lodash/dist/lodash.js

エイリアスを書くと...

resolve: {
    alias: {
        library: '絶対パス/../../library',
        lodash: 'lodash/dist/lodash.compat.js'
    }
}

...すっきりインポートが出来ます。

var lib = require('library');
var _ = require('lodash');

・好きなビルドシステムとの連携が簡単

  • Grunt
  • Gulp
  • Make
  • ...

・賢いビルド出力

  • チャンクファイルを等分布することが可能
  • 「重いファイルのみ」などのオンデマンド読み込みが可能
  • ルートによってセグメントに分割が可能
  • 共通モジュールの摘出が可能
  • ...

・速いビルド

  • インクレメンタルビルド
  • 変更されたファイルのみが再ビルドされる

・デバッグが簡単

  • ソースマップなどが出力できます

・懸念点

  • 日本語のドキュメントはまだ無い
  • 基本的には何でもできる
ということで...

WebPackの導入

さっそくインストールしてみましょう。
公式のサイトはこちらです。

インストール


次のコマンドをコマンドラインで叩きます。
$ npm install webpack -g


使用方法

WebPackはとても簡単に使用することが出来ます。
$ webpack <input> <output>
  • <input>はメインのJSファイル名。

  • <output>はビルドされるJSのファイル名。

では実際に実用的なコードを例にして説明していきたいと思います。

まずはサンプルコードを落とします。
$ git clone https://github.com/gunta/webpack-samples-1pixel.git

そして依存ライブラリをインストールします。
$ npm install


【第1部】CommonJSの簡単なサンプル


$ cd 01-commonjs

フォルダの中に下記ファイルがあります。
<math.js>
exports.add = function (x, y) {
  return x + y;
};
<main.js>
var math = require('./math');
alert('1 + 2 = ' + math.add(1, 2));

ビルドをすると、出力先にbundle.jsが生成されます。
$ webpack main.js bundle.js


そしてmain.htmlを開くと、
$ open main.html
きちんとアラートが表示されることが確認できます。


【第2部】Bootstrapを使ったサンプル

$ cd 02-bootstrap

毎度コマンドラインから諸々のフラグを付けるのは大変なので、
Configファイルに書きます。

Configファイル名はwebpack.config.jsにしておくと、
下記コマンドを叩くだけで設定が読み込まれビルドが実行されます。
$ webpack


今回のソースコードは非常にシンプルです。
<main.js>
require('bootstrap/dist/css/bootstrap.css');

こちらのbootstrap.cssのファイルは、
node_modulesの中にnpm installでインストールしたものですが、
bowerでも手動でも、何でもOKです。
<webpack.config.js>
module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders: [
        
      // 拡張子がCSSの場合はCSSのLoaderを採用
      { test: /\.css$/, loader: 'style!css' },
      
      // bootstrap.cssの中に使うWebFontを(デフォルトで)base64エンコードされます
      { test: /\.svg$/, loader: 'url-loader?mimetype=image/svg+xml' },
      { test: /\.woff$/, loader: 'url-loader?mimetype=application/font-woff' },
      { test: /\.eot$/, loader: 'url-loader?mimetype=application/font-woff' },
      { test: /\.ttf$/, loader: 'url-loader?mimetype=application/font-woff' }
    ]
  }
};

下記コマンドで確認できます。
$ open main.html


【第3部】AngularJSのサンプル

こちらは最新の公式AngularJSフォルダ設計 ベスト・プラクティス
ベースにしたサンプルです。

こういう構成にすると、
簡単にコンポーネント化できます。
$ cd 03-angular

<main.js>
var angular = require('angular');
angular.module('app', [
  require('./tabs').name,
  require('./pane').name
]);
<webpack.config.js>
module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      { test: /\.html$/, loader: 'html' }
    ]
  }
};
<tabs/index.js>
module.exports = angular.module('app.tabs', [])
  .directive('tabs', require('./tabs-directive'));
<tabs/tabs-controller.js>
module.exports = function ($scope) {
  var panes = $scope.panes = [];

  $scope.select = function (pane) {
    angular.forEach(panes, function (pane) {
      pane.selected = false;
    });
    pane.selected = true;
  };

  this.addPane = function (pane) {
    if (panes.length == 0) {
      $scope.select(pane);
    }
    panes.push(pane);
  }
};
<tabs/tabs-directive.js>
module.exports = function () {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    controller: require('./tabs-controller'),
    template: require('./tabs-template.html'),
    replace: true
  }
};

このように、.htmlのテンプレートを簡単に埋め込むことができるようになりました。

ビルドをすると、
$ webpack

ブラウザで確認ができます。
$ open main.html


【第4部】CoffeeScriptやLESS、Jadeを使ったサンプル

$ cd 04-coffee-less-jade

<main.coffee>
Colors = require "./colors/colors.coffee"
...
colors = new Colors()
<colors/colors.coffee>
require './colors.less'
template = require './colors.jade'

class @Colors
  getTemplate: -> template

module.exports = @Colors
<colors/colors.less>
@import "base";
LESSファイルのインポートまで解析してくれます。

ビルドをします。
$ webpack

ブラウザで確認できます。
$ open main.html


【第5部】コードスプリット

$ cd 05-code-splitting
こちらのサンプルでは、出力先が2つに分割されます。

1つ目のバンドルは、初期に読み込まれ、
2つ目のバンドルは、require.ensure()を通じて
オンデマンドで必要になった時に読み込まれます。

<main.js>
var a = require('a');
var b = require('b');

require.ensure(['c'], function (require) {
  require('b');
  var d = require('d');
});


ビルドします。
$ webpack

そして開くと、
$ open main.html

`a  b  d`が表示されます。

なぜ、cのモジュールが呼ばれてないのでしょうか?

理由は、require.ensureでは、ファイルの読み込み完了は保証されるのですが、
中身のコードが評価されないからです。

これはCommonJSの仕様で、読み込みと評価のタイミングは自由に選べます。

また、WebPackは、AMDのシンタックスにも対応しています。
require(["a"], function(a) {
    // こちらはAMD仕様なので、aモジュールが読み込みも評価もされます
});

個人的にはCommonJSのシンタックスの方が好きです。


【第6部】production/develが最適化されたサンプル

$ cd 06-production

こちらは一番リアルに近いサンプルなので、
じっくり中身を確認してみてください。

色んな機能がフィッチャーされます。
  • Gruntによるビルド
  • Gulpによるビルド
  • Grunt/Gulp無しによるビルド
  • 複数ページの複数ファイル出力
  • ウォッチもリロードもしてくれるdevサーバー
  • Minifyもモジュールの重複排除もしてくれる設定
  • jQuery/Bootstrapの読み込み
  • グローバル変数にjQuery変数を導入
  • 出力チャンクのネーミング

ビルドの仕方は簡単です。

Grunt

Gruntでdevel版をビルドしたい場合
$ grunt 
全部のモジュールがビルドされ、develサーバーが立ち上がります。

ファイルを変更すると、自動的にページがリロードされます。

ちなみに、物理的にファイルが出力されず
オンメモリでビルドされるので、速いです。

production版をビルドします。
$ grunt build
dist/フォルダにminifyされたファイルが出力されます。

Gulp

こちらはgruntと同様です。

devel版をビルドします。
$ gulp

production版をビルドします。
$ gulp build


【第7部】EcmaScript 6のサンプル

こちらは未来からきたES6の書き方、
ES6モジュールの書き方ができるサンプルです。

ビルドすると現在のES5に変換されますので、
未来の書き方を今すぐ使えます。

これはAngular 2.0でも採用されている方式です。

$ cd 07-es6

まずはBowerのモジュールをインストールします。
$ bower install

そしてビルドします。
$ webpack

中身も未来的です。
<main.js>
// Style modules
require('todomvc-common/base.css')

// ES5 modules
var $ = require('jquery')
var Backbone = require('backbone')

// ES6 modules
import {AppView, Filters} from './todo-app';

// Document ready
$(() => {
  new AppView()
  new Filters()
  Backbone.history.start()
})
<todo-app.js>
// ES5 modules
var $ = require('jquery')
var _ = require('lodash')
var Backbone = require('backbone')
require('backbone.localStorage')

const { Model, View, Collection, Router, LocalStorage } = Backbone
const ENTER_KEY = 13
let TodoFilter = ''

// Todo Model class
class Todo extends Model {

  defaults() {
    return {
      title: '',
      completed: false
    }
  }

  toggle() {
    this.save({
      completed: !this.get('completed')
    })
  }
}

...
export { AppView, Filters }


終わりに

もっとサンプルがほしい!という方は、こちらにたくさんあります。

検索可能な限りでは、今回は日本語初のWebPackの記事になりますが、
今担当しているプロジェクトで6ヶ月前から導入していますし、
Instagram.comでの導入事例もあります。

以上、WebPackのお話をさせて頂きました。
最後までお付き合い頂き、ありがとうございました!
こんにちは。広報でコーポレートサイトを担当しています渡辺です。

今回は写真補正に便利なLightroomの紹介をさせていただきます。
みなさんは写真補正にどのようなツールを使われていますか。
Photoshopで色調補正でレベル補正を調整して、さらにトーンカーブをいじって、今度はフィルターでノイズを軽減して修復ブラシでゴミを消して…等々
1作業1作業工程を踏みながら補正している方もまだまだ多いのかなと思いますが、Lightroomを使うと一つのパネルで全ての工程を行うことができるので非常に便利です。

単体だと16,000円ほどするソフトですが、AdobeのCreative Cloudを利用している方ならサービスに含まれていますので、ダウンロードして使ってみてください。

もちろんPhotoshopのプラグインであるCamera Rowを使ってもほぼ同様のことはできますので、そちらを使っても結構ですが、大量の写真から採用する写真を選んだり、比較しながら検討したりするのはLightroomの方が得意ですので、今回はLightroomをベースに話をしていきたいと思います。

Lightroomを始める


まずLightroomではカタログを作って写真を管理をするので、最初にカタログを作成します。

[ファイル] - [新規作成]から適当なファイル名を付けて[保存]します。




カタログができたら今度はカタログ内に写真を取り込みます。

[ファイル] - [写真とビデオを読み込み]を選択すると以下のような画面が開きます。



左側のソース欄から写真が保存されているフォルダを選択すると、中央にサムネイルがずらーっと表示されるようになります。


読み込む写真をチェックで選択したら(デフォルト全部チェックされています)、右下の[読み込み]ボタンを押しましょう。


これで準備は完了です。


写真を補正する


Lightroomの写真補正は全て[現像]画面で行いますので、右上の方に表示されている現像をクリックします。すると下のような画面が表示されます。


右側のパネル(便宜上全て閉じています)を使って補正を行っていきましょう。


(1)基本補正

暗所での撮影や部屋の照明によってこのような暗くて色被りした写真になることが多いですよね。
まずは基本補正のパネルで全体的に修正してみましょう。



写真は全体的に白熱灯照明で暖色系の色が濃くでているので、右パネル[基本補正] - [色温度][色かぶり補正]のスライダーを調整して自然に見える色に調整します。



このままだと少しくらい印象になってしまうので[露光量]を上げていきます。



全体の明るさを丁度いいレベルにした場合、明るい部分(ここでは照明周り)が飛んでしまっているように見えるので、白とびしてしまった場合は[ハイライト]を調整して明るい部分だけ少し下げてみましょう。そうすると照明の形がくっきり見えるようになりました。逆に黒つぶれしてしまっている場合は[シャドウ]を明るくすることで調整ができます。



補正が終わったら[ファイル] - [書き出し]から[書き出し場所]の選択と[ファイル設定]で画像形式を選択して[書き出し]するだけです。




(2)スポット修正

写真に写ってしまったゴミや余計なものを消すことも多いと思います。
Photoshopで言う[修復ブラシツール]と似た機能ですが、Lightroomでも同様のことができます。
今回はデスクの上にあるコンセント用の穴を消してみましょう。


右パネル[ヒストグラム]下にあるアイコン左から2番目の[スポット修正]を選択します。

さらにその下にブラシ用のパネルが開きます。
ブラシの[サイズ]を消したいもののサイズに調整して一気になぞってみましょう。


自動的にコピー元がどこから持ってくるのか表示してくれますので、自然に見えるコピー元を探し、最後に[閉じる]をクリックします。



するとコンセント穴がきれいに消えてくれました。




(3)ディテール

暗所での撮影で特に起こりやすいノイズ問題。
明るく補正すればするほどノイズ部分が目立ってきます(画面がわかりづらくてすいません。砂の質感のようにざらざらした部分のことです)。
その場合は右パネル[ディテール]を使って補正してきましょう。



中央の画像をクリックすると拡大した画像が表示されます。
今回は[ディテール]内の[ノイズ軽減]から[輝度]を調整します。



するとこのようにノイズが消えてくれます。
全体の写真とアップの写真を見比べながらもっさり感が出ないように調整しましょう。


(4)レンズ補正

カメラのレンズによって、かなり歪曲した画像に写ることがありますが、特にこの写真のように直線の多い写真は違和感を感じることがあります。
こういった場合には[レンズ補正]を使って補正していきましょう。



Lightroomには予めレンズの種類がたくさん登録されていますので、[基本]から[プロファイル補正を使用]にチェックを入れるだけでかなりこの違和感をなくしてくれます。

レンズのプロファイルは[プロファイル]から同じく[プロファイル補正を使用]にチェックを入れ、登録されているメーカーやモデルを選択してください。

また使っているレンズの登録がない場合や、既に加工されたJPEGファイルなどの画像の場合は手動で直すことができます。
[手動]をクリックしてみてください。
[ゆがみ]を調節すると、レンズ特性で歪んだ部分を直してくれます。



これだけだと画像が傾いたように見えるので[垂直方向]と[回転]も調整して真っ直ぐに見えるようにしてみました。



画像を変形させることによって写真外の部分が白く表示されることがあると思います(青枠で囲んだ部分)。
その場合は、[切り抜きを制限]にチェックを入れると自動的にズームしてくれて白い部分がなくなります。



いかかでしたでしょうか。

今回紹介したのはよく使う基本的な機能のみでしたが、まだまだLightroomには沢山便利な機能がありますので、いろいろ試してみてください。
はじめまして。
アメーバ事業本部プロモーション室の大塚康善です。

プロモーション室では広報や宣伝、企画のほかにゲームのユーザー獲得を目的としたバナー広告の制作や運用も行っております。

本日はTwitterや2chまとめで話題になったボーイフレンド(仮)のバナー広告を例に挙げ、拡散されるための考え方をご紹介いたします。

ボーイフレンド(仮)とは


ボーイフレンド(仮)とはユーザーが主人公となり、個性豊かなイケメン達と出会って行く、恋愛カードゲームです。

きっかけはネタ系

最初は全て真面目な内容のバナー広告でしたが、試しにクスっと笑えそうなネタ系の内容を入れてみたのが始まりでした。
やがて2chまとめで話題となり、twitterなどでユーザー間に拡散されていきました。

さて、そんな拡散のきっかけを作った「ネタ系」のバナー広告。
何を考えて作っていたのでしょうか。
そこには意外な真実が…!?

既視感と謎解き

ネタ系のバナー広告では「なんか見たことある」などの既視感を大切にしています。
「見たことある」という親しみを与え、「なんか」というぼかした表現にすることでユーザーの関心を引く、そんな狙いがあります。

ユーザーとの親和性を考えて漫画の表現やネタを幾重にも織り込むことが多く、ちょっとした謎解き気分を味わってもらいたいと思いました。


 そして、元ネタがわかったユーザーが「誰かに言いたくなる」という拡散への起爆剤がそこにあったのです。

シリーズ化してみる

ユーザーの反応を見て、好評なものはシリーズ化することもあります。
ちょっとしたストーリー仕立てにしたり、3段オチにしたりと表現の幅を広げ、ユーザーを楽しませる工夫をしていました。

これはユーザーの期待感の持続を目的とし、少しでもワクワクした状態で新しいバナー広告を待ってくれている状態を作りたかったためです。


ただ、回を重ねるごとにハードルは上がるのでやり過ぎにはご注意を。

ツッコミどころを作る

いわゆる「ユーザーのリアクションとセットに考える」ということです。
ユーザーにどんなツッコミ(リアクション)をしてほしいかをイメージし、構成に落とし込んでいきます。


夜中のテンションで作ってしまうのが一番捗るのですが、朝に見返して顔を覆うこともしばしば…

ネタ系に限らず、狙いのないバナー広告はスルーされますし、スルーされるバナー広告はどんなに美しいデザインでも、ただのゴミです。

最後に

バナー広告を作っていく上で感じたことは、バナー広告を単なる広告としてではなく、コンテンツの一つとして昇華させることで、ユーザーとのコミュニケーションは可能になるということです。

もちろん、それはとても難しいことですし、サービスによってもその必要性が違ってくると思います。しかし、ユーザーに長く愛されるサービスを作るための一つの手段として考えてみてはいかがでしょうか。

長文にお付き合いいただきありがとうございました。今後ともボーイフレンド(仮)をご愛顧いただきます様、よろしくお願いします。

こんにちは。サイバーエージェント 井上と申します。 現在、人事本部にてテクノロジー・デザインコース採用担当をしています。

今年もサイバーエージェントでは、クリエイター向けインターンシップを実施いたします。

夏のインターンシップを通して、更なる成長をしたいと考えている学生の皆さん、学校で学んでいることや普段ご自身でつくっているものがどの様に仕事で活かせるのかを体感していただきながら、この夏成長できるインターンを用意していますので、ぜひご応募ください!



サイバーエージェント Internship 2016

テクノロジー・デザインコースのインターンシップは2種類となります。

1つは、5~9日間で1サービスの企画からデザイン開発までを行い、実際の新規事業の立ち上げを疑似体験する「フロントエンドCAMP」と「DesignCAMP」。

もう1つは、実際に開発現場で働く社員とともに、最先端のサービス開発を経験する「就業型インターンシップ」です。

それぞれ経験できる技術やテーマ別にコースが分かれており、全て併願可能です。
(※コースや日程などは、面接の過程で相談の上、決定いたします。)

「DesignCAMP」概要


「DesignCAMP」の詳細はこちらから

DesignCAMPでは9日間で新規事業や新しいプロダクトの企画からデザインまでを行います。

Webデザインの基礎を学び、企画、デザイン、UI設計を自分たちで考え、質の高いアウトプットを目指して当社社員とともに挑戦します。
自分のデザイン力を磨きたい、Webサイト構築の知識をつけたい、企画から世界観を考え形にしたいという方がチャレンジできる環境をご用意しています。

学校で学んでいることや普段つくっているものがどの様に仕事で活かせるのかを体感していただきます。

■日程
【第一日程】8月5日(火)~8月15日(金)
【第二日程】8月19日(火)~8月29日(金)

■募集人数
各日程10名ずつ

■報酬
【参加者全員特典】
報酬5万円、交通費全額支給、宿泊所提供(※遠方の方のみ)
社員との懇親会、その他各種イベント、勉強会参加優先権、本選考特別枠等

【優勝者】
 iMacもしくはMacBook Proなど ご希望の最新デバイスの贈呈を予定しています。

■場所
【東京】サイバーエージェント渋谷オフィス

「フロントエンドCAMP」概要


「フロントエンドCAMP」の詳細はこちらから

フロントエンドCAMPは5日間で、JavaScriptを使ったWebアプリケーションを制作する開発合宿です。

JavaScript、HTML5、CSS3を中心に、様々な最先端ライブラリを駆使し、ユーザーを魅了するアプリを開発します。

決められた期間内に、いかにユーザー目線のアプリ開発ができるか、企画から開発まで体験できる内容となっています。

■日程
東京【第一日程】8月13日(水)~8月19日(火)
  【第二日程】9月3日(水)~9月9日(火)
京都 8月25日(月)~8月29日(金)

■募集人数
各日程20名ずつ

■報酬
【参加者全員特典】
報酬5万円、交通費全額支給、宿泊所提供(※遠方の方のみ)
社員との懇親会、その他各種イベント、勉強会参加優先権、本選考特別枠等

【優勝者】
 iMacもしくはMacBook Proなど ご希望の最新デバイスの贈呈を予定しています。

■場所
【東京】サイバーエージェント渋谷オフィス
【京都】京都市内会場

「就業型インターンシップ:デザインコース」概要


「就業型インターンシップ:デザインコース」の詳細はこちらから

スマートフォン向け恋愛カードゲーム「ガールフレンド(仮)」や日本最大級コミュニティサービス「アメーバピグ」を始め、クオリティの高いクリエイティブがきっかけとなり、人気が加速したサービスが数多く存在します。

このコースは、そんな「Ameba」の制作現場で実際のサービス作りに携わっていただくインターンシップです。

世界観・コンセプトから設計し、実際にリリースが可能なレベルでのデザイン・UI/UX・マークアップを行っていただきます。

自身の制作経験をフルに生かし、何千万人という多くのユーザーの心を動かすサービスを創りましょう。

■日程
8月11日(月)~9月12日(金)

■募集人数
2名程度

■報酬
【参加者全員特典】
 日給1万円程度の報酬、交通費全額支給、宿泊所提供(※遠方の方のみ)
 社員との懇親会、その他各種イベント、勉強会参加優先権、本選考特別枠等

■場所
【東京】サイバーエージェント渋谷オフィス



エントリー締め切りは、全コースともに併願可能となっており、
・1次締め切り:6月16日(月)12:00
・2次締め切り:6月30日(月)12:00
を予定しています。

エントリーしていただいた方から順次選考にご案内いたしますのでお早目にご応募ください。

皆様からのチャレンジお待ちしております!

はじめまして。2013年新卒入社のTomと申します。
私は現在ガールフレンド(仮)(以下GF)で約1年程フロントエンドの運用を行っています。

今回はGFで使用しているスプライト画像生成ツールGlueに関して導入の経緯などを交えてお話したいと思います。

Glueのメリット

・柔軟
 オプション数が豊富でテンプレートも設定でき、細かくカスタマイズ出来るのでプロジェクトの途中からでも導入しやすい。

・簡単
 コマンドライン上でファイルの入出力先を指定するのみで非常にシンプルに使える。

・高速
 基本的にスプライト画像、cssの生成のみ行うので高速。

導入経緯

スプライト画像生成ツールとして有名なのは、compassを利用した生成手法などがあると思います。
GFでもcompassを使用しており、検討しましたが、以下の理由で断念しました。

  • scssファイルのimport構成に依存すること(構成によってはコンパイルに時間がかかってしまう。)
  • 運用期間からの導入コスト(既存の構成を極力維持したまま使いたい。)
  • GFでは共通のスタイルが纏められたscssファイルのみで完結してしまうページが多い
    (極力リクエスト数を削減したい。スプライトのためにscssファイルを作りたくない。)

compassは多機能で上手く扱えばとても強力なのですが、フルに活用するにはそれらの機能を意識した設計を行っていないと運用は難しいです。
GFに適したスプライト画像生成ツールは以下のようなものでした。
  • scssのコンパイルに依存しない
  • けど極力compassみたいに自動化したい
  • html内にスプライトの定義を記述したい
これらの要望を満たしていたのがGlueでした。

Glueの導入

ではさっそくインストールしてみましょう。Mac OSXを例に説明していきたいと思います。公式のインストールガイドはこちらです。
今回はhomebrewを使ってインストールしていきます。
$ brew install jpeg
$ brew install python
$ pip install glue
インストールが完了したら
$ glue -v
でバージョンを確認してみましょう。最新版(2014/5/28時点)である0.9.4がインストールされていると思います。

使用方法

Glueはとてもシンプルに使用することが出来ます。基本的な使い方は下記の様になります。
$ glue source output
sourceはスプライトにしたい画像が格納されているディレクトリ、outputはスプライト画像の出力先を指定します。

では実際にGFで使用した橋本環奈ちゃんキャンペーンページを例にして説明していきたいと思います。
   

このページでは2枚のスプライト画像を使用しているのですが、その内の1枚が下記を纏めたものになります。

cpディレクトリに移動し下記のコマンドを実行してみると
$ glue sprite1 ./
cpディレクトリ直下にスプライト画像とcssファイルが生成されました。

生成されたcssは下記になります。
/* glue: 0.9.4 hash: 7c38b5a04c */
        .sprite-sprite1-ribbon,
.sprite-sprite1-kanna_text_3,
.sprite-sprite1-kanna_text_1,
.sprite-sprite1-kanna_text_2,
.sprite-sprite1-gf_text_3,
.sprite-sprite1-gf_text_1,
.sprite-sprite1-gf_text_2,
.sprite-sprite1-coin {
            background-image: url('sprite1.png');
            background-repeat: no-repeat;
        }
        
        .sprite-sprite1-ribbon {
            background-position: 0 0;
            width: 624px;
            height: 134px;
        }
        
        .sprite-sprite1-kanna_text_3 {
            background-position: 0 -134px;
            width: 582px;
            height: 116px;
        }
        
        .sprite-sprite1-kanna_text_1 {
            background-position: 0 -250px;
            width: 576px;
            height: 54px;
        }
        
        .sprite-sprite1-kanna_text_2 {
            background-position: 0 -304px;
            width: 572px;
            height: 112px;
        }
…省略…
class名に関しては下記の形式で割り振られています。
sprite-ディレクトリ名-画像名

オプション

オプションの書き方は下記になります。半角スペース区切りで複数指定が可能です。
$ glue source output option
ver0.9以降に追加されたオプションをいくつか紹介したいと思います。

$ glue source output --cocos2d
cocos2dと互換性のあるXMLメタデータファイルを生成します。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>frames</key>
    <dict>
        <key>coin.png</key>
        <dict>
            <key>frame</key>
            <string>{{624, 0}, {160, 110}}</string>
            <key>offset</key>
            <string>{0,0}</string>
            <key>rotated</key>
            <false/>
            <key>sourceColorRect</key>
            <string>{{624, 0}, {160, 110}}</string>
            <key>sourceSize</key>
            <string>{160, 110}</string>
        </dict>
        <key>gf_text_1.png</key>
        <dict>
            <key>frame</key>
            <string>{{0, 466}, {466, 48}}</string>
            <key>offset</key>
            <string>{0,0}</string>
            <key>rotated</key>
            <false/>
            <key>sourceColorRect</key>
            <string>{{0, 466}, {466, 48}}</string>
            <key>sourceSize</key>
            <string>{466, 48}</string>
        </dict>
        …省略…

$ glue source output --margin=20
指定した値を画像の上下左右に余白を取ります。既にpaddingオプションがあるのですが、違いはmarginオプションの場合、余白部分の長さをwidth, heightに含みません。

$ glue source output --cachebuster-filename-only-sprites
生成するスプライト画像にのみキャッシュバスターを付与します。
sprite1_8635fbf5f2.png

少しニッチなオプションだったかもしれないですが、class名を任意の形式に変更したりする等のポピュラーなオプションもありますので是非公式のドキュメントを見てみて下さい。

最後に

基本的な部分しか紹介出来ませんでしたが、Glueいかがでしたでしょうか?
シンプルながらカスタマイズ性もあるので是非今後のスプライト生成ツールの選択肢の1つになればと思います。
他にもテンプレート機能などがあるので是非試してみてくださいね。
最後までお付き合い頂きありがとうございました。