お久しぶりです。3度目の登場となります。
アメーバ事業本部 経営本部局の渡辺です。

今日は雑誌「Web Designing」との共同企画で開催している「Tap App Awards」について紹介したいと思います。

ご存じない方が多いと思いますので「Tap App Awards」について少し説明させていただきますと…
次世代のWebクリエイター発掘を目的とした「TapApp(タップ*アップ)」プロジェクトの一環として2013年2月に行われるアプリ制作のアワード企画となっています。

TapAppプロジェクトは、雑誌「Web Designing」との共同企画で、2012年10月号から「アプリ制作現場のUIデザインケーススタディ」と題し4回連載でスマートフォンゲームやコミュニティのUIデザインにまつわるTIPSを紹介している記事から始まります。まだ見ていない方がいらっしゃればバックナンバーを是非ご覧いただきたいと思います。

Tap Appセミナー

今月17日には雑誌連動企画「Tap Appセミナー」を開催し、掲載内容を含めたスマートフォンUIの勉強会を行いました。

中村洋基さんの基調講演

セミナー冒頭ではPARTYの中村洋基さんが「インタラクティブ基調講演 ~アプリアイデアとの正しい出会い方~」と題して基調講演を。

1st Sessionでは弊社のコミュニティサービスを開発する、デザイナー・デベロッパー陣から
・「スマートフォンWebアプリ最適化”3つの極意”」~ストレスフリーのスマホコーディング術~
・「スマホコミュニティサービスの創りかた」~ユーザーをハマらせるためのサービスデザイン~
のテーマでスマホ開発の極意を。


Technical SessionではAdobeの轟啓介さんが「アドビがオススメしたいWeb技術のスマホアプリ開発」と題してマルチプラットフォーム開発で便利な、PhoneGapの紹介を。

2nd Sessionでは弊社のソーシャルゲームを開発する、デザイナー・デベロッパー陣から
・動的に項目変更されるソーシャルゲームUIの作り方のコツ
・よりよいUIをつくるためのデバック方法
・表示領域、タッチイベントの取り方等OSの差によるユーザーストレスの軽減法
のテーマでスマホ特有のUIのTIPSを紹介しました。

ありがたいことに、当日は足下が悪かったにもかかわらず沢山の方がご来場いただき、満員御礼となったんですが、応募時に申し込みが殺到したため、参加できなかった方が多くいらっしゃったようなので、当日の内容をUstreamの録画にてご覧いただけるように準備いたしました。

「セミナーの内容を聞いてみたい!」
「参加したけどもう一度見てみたい!」
というかたは是非こちらのページからご視聴いただければと思います。
tapapp2012_01 → tapapp2012_02 の順番にご覧ください。

※2012年内目途での掲載となりますので早めのご確認をお願いします。

資料についても一部Slideshareにて共有しております。

スマートフォンWebアプリ最適化”3つの極意
ADOBE PHONEGAP WEB標準によるモバイルアプリの開発
WebデザインのUIレシピ
Tap App Awards 2013

Tap App Awards

これから「TapApp(タップ*アップ)」プロジェクトは年明けのAwardに向けて盛り上がっていきます。
セミナーの内容をご覧頂き、アプリ開発にチャレンジしたいという方は是非ご参加ください。

賞金・副賞も豪華!
「上海クリエイティブオフィスツアー」(ペア2名)、Adobe CS6 Design & Web Premium、Intuos5 touch medium、賞金等々

部門はフリー部門とテーマ部門の2部門

・フリー部門
「繋がる」をキーワードとしたアプリをあなたのアイデアで創ってください

・テーマ部門
下記のいずれかを選び、それをテーマとしたアプリをあなたのアイデアで創ってください
[Clock(時計)]
[カレンダー/スケジューラー]
[毎日3分遊びたくなるゲーム]
[リズムで遊ぶアプリケーション]
[温かみを感じるアプリケーション]
[Photo Library(写真共有)]

審査員も、Partyの中村洋基さん、Adobeの轟啓介さんはじめ、バスキュールの馬場鑑平さん、FWAのRob Fordさん等豪華なメンバーです。

応募締切は、2013年1月15日(火)となりますのでまだまだ企画を考える時間はたっぷりあります。
技術で腕試ししてみたい方、スマホの開発にチャレンジしてみたい方、UIデザインで勝負したい方、既存のスマートフォンアプリケーションの概念を超越するような作品を審査員、関係者一同、お待ちしています!

詳細の内容は「Tap App Awards」のページをご確認ください。

はじめまして。アメーバ事業本部ピグディビジョン ピグカフェチームでディベロッパーをしています安斎です。
今回は、2012年8月にリリースされたピグカフェについて、リリースまでの開発中の話も含めながら、お話させていただければと思います。

ピグカフェタイトル


ピグカフェの世界観

ピグカフェの舞台は、東京の青山です。
「青山」というと、「おしゃれ」「アーバン(都会的)」「大人の街」と言ったイメージです。
デザインはそれらを意識して制作をしています。

ピグカフェ青山エリア


また、東京のカフェというと、料理は洋食だけにとどまらず和食のあるカフェも多いですし、様々な国の料理があります。

そのため今回作った料理も各国の料理を用意し、幅を持たせることができました。
さらに、東京のカフェを知るために毎週「カフェめぐりランチ」を実施し、青山・渋谷・代官山周辺のカフェをたくさん回りました。
料理やインテリアまたカフェのある街並みは制作にとても役立ちました。

ピグカフェのゲームの仕組み

ピグカフェはアメーバピグで初のカフェ経営ゲームです。
基本的には、料理を作る→接客をする→アイテムをゲット!
というのが大まかなゲームの流れです。

ピグカフェゲームしくみ


さらに料理レベルやお手伝いレベルを上げることで、多くの料理が作れるようになったり、多くのお客様を招いてアイテムをゲットしカフェを発展させていくことができます。

自動的に動くNPCたち

ここからは、ゲームの裏側の仕組みについてお話しします。
ピグカフェでは、スタッフやお客様など自分以外のキャラクターが自動的に動いてゲームが進行していくのが大きな特徴です。
これは、今までのピグゲームにはなかった大きな特徴と言えます。

サーバーサイドではNode.jsで実装をし、WebSocketを使って通信を行なっています。そのためリアルタイムにゲームが進行するものを作ることができました。

「料理をつくる」「運ぶ」「食べる」「食べ終わって帰る」などの一つ一つの行為を常にサーバーと通信をしています。
これらは情報量も多い上、他人から見ても同様に見えるように同期していますので、開発にはかなり苦心した部分です。

自分のピグとNPCたちが繰り広げるピグカフェの世界をぜひお楽しみください。

NPCチェッカー

ピグカフェにはリリース時点で100体を超えるNPC(レアなお客様)を準備しました。制作には多くの時間が必要だと予想されたため、簡単に使えるNPCチェッカーを用意しました。

ピグカフェはFlashで動いていますので、実際に動かすためには、一体一体をswfにする必要があります。(社内ではFlashでswfにすることを「fla化」と呼んでいます)
出来上がったswfを、Flashにさほど触ったこと無い人でも簡単にチャックできるツールを目指しました。

ピグカフェNPCチェッカー


このツールは、画面にドラッグアンドドロップでswfを読み込むことができます。
また、ピグカフェでは料理の食べ方だけでも7種類用意しているので、各アクションや表情を見ることができます。

NPCチェッカーを作ることで、
・開発環境が整ってない状態でも、ローカルで完成させることができる
・イラストレーターさんだけで、イラストからfla化、チェックまでを一環して行うことができる
これらの利点があり、開発効率を大幅に改善することができました。

開発自体の進捗を若干の期間止めたとしても、効果のあるツールは優先して作った方が、開発効率が良くなりチームみんなが幸せになるのでオススメです。

最後に

ピグカフェはリリースして3ヶ月弱経ちました。ユーザーにより楽しんでもらえるゲームにするために、更なる開発・運用を行なっていきたいと思っています。また、毎月2本のイベントクエストも配信していますので、ぜひピグカフェをお楽しみください。

ピグカフェはこちら
http://cafe.pigg.ameba.jp/

こんにちは。

スマートフォンで提供しているサービス「きいてよ!ミルチョ」の開発に携わっている若松と申します。クリエイティブアカデミーを経て、今年6月に入社しました。


入社してまだ半年も経っておりませんが、社内で実際にサービスの開発に携わると、そのスピード感、ダイナミズムといったことを実感し、非常に密度の濃い充実した日々を過ごしております。今回は「きいてよ!ミルチョ」というサービスと、その運用・改善の一端をご紹介できればと思います。


「きいてよ!ミルチョ」とは

ミルチョ

「きいてよ!ミルチョ」は簡単に言ってしまうと、ミルチョというヘンな生き物に自分のひとりごとを聞いてもらう、というサービスです。ひとりごとをどんどん聞いてもらい、また他人のひとりごとを聞いてそれに対して感謝されたり、ミルチョの世界で様々なアクションをすることで、ミルチョは色々な形に成長します。
このヘンな生き物のキモかわいさ、即座に得られる他ユーザーからの反応が何やら癖になるということで、実は今じわりと、巷で話題になってきています。


「きいてよ!ミルチョ」プロジェクトの運用について

このプロジェクトは8月にWebブラウザ版をリリースした後アプリ版のリリースも順調に完了し、現在はより使いやすく楽しめるサービスにするべく、猛スピードで改善を行っている最中です。

ここからは、どういう風にして私たちのチームが運用・改善のサイクルを回しているのかを、簡単にご紹介します。


■ 週に一度、サービスを改善してリリース

まず私たちのチームでは、大体1週間に一度、「きいてよ!ミルチョ」の新規バージョンをリリースしています。新規バージョンで留意しているのは、ユーザー視点でこれまでよりもサービスの価値が向上しているものになっている、ということです。具体的には機能の追加や、キャラクターの追加、バグ修正、パフォーマンスの改善といった項目が反映されていきます。
リリースのスパンは柔軟に考えており、改善内容によっては1週間以上をかけることもあります。


■ 取りかかる優先度 = より価値を高められる改善

改善項目には、重要度の高い(= ユーザーにとってより価値のある)順に、優先度を設定していきます。バグは早々に無くすべきだし、使い勝手上で欠陥があれば、そこも早めに改修したい。もちろん、ユーザーがより楽しめるような新しい機能はどんどん追加していきたいです。また、弊社にはダカイゼンという仕組みがあり、そこから上がってくる改善項目も多数あります。
チームでは毎朝、前日のユーザーの利用状況を共有しています。そこで早急に解決しなくてはいけない課題が見つかったら、他の項目を差し置いても、優先度を高く設定したりします。
実施したい項目は常に列をなしていますが、一旦上記のルールに従って整理し、そこから順に手をつけていきます。


■ リストページにおける改善の事例

- 事例1

改修2

- 事例2

改修1

それまでは"きいたよ"のタップ領域と詳細ページへ遷移させる為のタップ領域が近接しており、ミスタップがおきるという声が社内から上がっていました。そこで一方のタップ領域を大幅に変更し、意図しない遷移をなくすように改善しました。また、"きいたよ"ボタンの画像を、それまでは押下前、押下後でしか変化しなかったものを、押下時にも変化させるように変更しました。こうすることで、ユーザーのアクションをよりダイレクトに表す、という効果を高めることができました。こうした見た目上の変化は、もちろんサーバとの通信が走る前につけています。こうした施策によって、ユーザーの回遊性、アクション数が大幅に向上しました。


■ 担当範囲はその都度、柔軟に決めます

チーム内では厳密には作業の担当は決まっていません。デザイナーもコーディングをしますし、アニメーション(ミルチョではSencha Animatorを使用)を担当したりしています。フロントは大部分をJSで制御していますが、それを担当するフロントエンジニア2名(東京と福岡)は、作業範囲を明確化せず流動的にその都度最適と考える割り振りをして、作業を進めています。こういった進め方は、作業のスピード感を保つのに貢献していると考えています。


密接なコミュニケーションの必要性

- 朝会風景

ミーティング風景

私達のチームは、開発メンバーが福岡と東京に分かれています。こうした運用手法に限らず、プロジェクトを成功させる為には密接なコミュニケーションは必須ですが、私たちは毎朝のミーティングやチャットツールでこれを実現しています。朝のミーティングは他のプロジェクトでも普通に行っていることですが、私達のチームにおいては特に重要な意味を持っていると考えています。私たちは毎朝ビデオ通話を通じて以下のような内容について話し合っています。

  • 前日のユーザーの利用状況
  • 昨日のタスクの進捗
  • 本日のタスク
  • 浮上した問題点
  • どのように解決していくか

これとは別に、週に一度定例ミーティングを開きます。そこでは現状の課題や、今後それをいかにして解決していくかなど、もっと中期的な内容について話し合います。プロジェクトは外的な要因に左右されることも多々あります。初めの計画通りにいかなくても、こうしたタイミングでその都度、進路を修正し、新たな課題とどう向き合っていくか、いかにしてそれを乗り越えていくかについて、私たちはしっかりと話し合っています。

また、福岡のメンバーは定期的に上京します。その際に一緒にご飯を食べたり、チームでお酒を飲みにいったりするのですが、実はこういったことが互いを理解する上では一番効果的なのではないかと思います。私たちもこうした過程を経て、ますます連携の効率が上がったように思います。


これからのミルチョに乞うご期待

- チーム内から出る様々なアイデア

ダカイゼン

現在チーム一丸となって、パフォーマンスの改善や機能の追加、ユーザビリティの向上施策などに、猛烈に取り組んでいる最中です。またミルチョの種類も絶えず追加されています。今後どういった方向にこのサービスを導いて行けば良いか、どうすればよりユーザーにとって楽しめるサービスになるのか。私達は今後も徹底的に考え抜き、サービスの価値を向上させて参ります。「きいてよ!ミルチョ」のこれからに是非ご期待ください。



【きいてよ!ミルチョ】 http://mirucho.me/


はじめまして。こんにちは。
Ameba事業本部 デザイナーのサトウ(@sugaar)です。
今回は、9月3日にリリースしたスマホブログ、「Simplog」iOS版のUIデザインについてご紹介させていただきます。

Simplogとは

Simplogは、Twitterのように気軽に投稿し、ブログよりもシンプルに美しく記録するAmeba発のスマホブログです。

Simplog_image

おかげさまで会員数10万人を突破(11月7日現在)し、
ユーザーの皆様に満足いただけるよう、日々改善を重ねています。

シンプルで簡単な投稿

Simplogは「シンプル × ブログ」というコンセプトのもと、「シンプルなUIで、いかにユーザー体験をリッチにするか」を追求しました。
「ブログ投稿」というユーザー体験をリッチなものにするためには、その複雑な機能を、いかに分かりやすく、使いやすいものにするかが重要です。

【見せる機能と見せない機能】


Simplogでは当初、投稿画面に以下の機能を想定していました。
・投稿ボタン
・下書き保存ボタン
・画像選択エリア
・テキスト入力エリア
・カテゴリ機能
・ロケーション情報
・他SNSへの同時投稿(Ameba、Facebook、Twitter)

ここから、「アレもこれも」で膨らんだ機能を、ユーザーアクションを想定して「必要な機能」「あまり必要でない機能」に分けて整理し、複雑な機能をよりシンプルに見せるためにUIをブラッシュアップしていきます。

■下書きボタン

「記事を書く → 投稿」というブログ投稿本来の遷移を優先するために、投稿画面からは無駄なボタンを一切排除しています。スッキリとした簡潔な画面に見せる事で、「ブログを書く」という敷居を下げ、記事を書くユーザーへのプレッシャーを軽減できると考えたからです。
そのため、「下書きボタン」をボタンとして用意せずに、左上の「キャンセルボタン」を押した際のアクションシートを採用しました。
これにより、「キャンセルボタンを押して記事を書くのをやめる」というネガティブな行動に紐付け、より自然なアクションで下書き保存へ促す事ができます。

■ロケーション選択

「どこで」を記録するロケーション選択機能は、テキスト入力エディタの一部に含め、サブ機能として位置づけました。
思い出をより詳細に記録するために便利な機能ですが、「ブログ」というコンセプトで考えた場合、ロケーション情報のみの投稿がレアケースであると判断したためです。
そのため、「テキスト入力のサブ機能」という位置づけで、エディタ機能の一部として取り入れました。

美しいレイアウトでリッチに閲覧

投稿画面をシンプルなものにし、気軽に書いた記事をリッチに見せる方法として、Simplogでは以下にこだわりました。

■写真をキレイに見せる

Simplogでは、写真を最大3枚まで同時に投稿する事ができます。
投稿する写真に対して、複数枚をレイアウトして組み写真を作成できる他、よりリッチに見せるためのフィルター加工が可能です。
また、フィード面での見栄えを考慮し、1枚投稿の場合はあえてトリミング処理を行わずに、そのままの状態で投稿しています。
これにより、縦長の写真をよりダイナミックに見せる事ができ、意図せず写真が見切れてしまうというユーザーストレスを軽減します。

■思い出として残す

日々の思い出を振り返るための機能として、投稿した日が一目で分かるカレンダーと、どんな1日だったかをまとめるページを設けました。
何気なく投稿したものを、1ヶ月や1日として自動的にまとめる事で、ブログに「残す」という行為をリッチに演出する事ができます。
気軽に振り返れるよう、マイページから横フリックでシームレスにカレンダーへ遷移させています。

■他SNSへの投稿を最適な形に

SimplogではAmebaブログはもちろん、Facebook、Twitterなど他SNSへの同時投稿が可能です。
その際、Amebaブログのタイトル指定や、Facebookアルバムへの格納方法など、投稿先に応じて最適な形で見えるよう工夫しています。

■外部投稿時の記事ページをリッチな見た目に

Amebaブログ、Facebook、Twitterなど他SNSへの同時投稿時に、Simplogの記事ページへの導線を紐付けています。
スマートフォン向けの記事ページでは、直接コメントなどのリアクションができる他、気になるユーザーのフォローが可能です。
PC向けの記事ページでは、写真がメインの記事と、テキストがメインの記事でレイアウトを変え、それぞれ最適な形で見えるよう工夫しています。

ユーザーコミュニケーション

ブログを書くモチベーションの1つとして、投稿した記事に対する他人のリアクションも重要な要素です。
Simplogでは、ユーザー間で自然にリアクションできるよう、ナイス・コメントの「気軽さ」と「レスポンスの速さ」について工夫しています。

■ナイスをポップに演出

「ナイス」ボタンを押した際に、「ニコちゃんマーク」をアニメーションで表示させ、ついつい押したくなるような演出を入れています。
また、ダブルタップでナイスがつく裏機能を設け、より気軽なリアクションを促しています。

■「レスポンスが速い」と思わせる施策

ナイスをつけた際に、押した瞬間にフロント側で色付きの画像に切り替え、実際のデータを裏でサーバに送るようにしています。
これにより、パッとリアクション済みのボタンに切り替わったように見えるため、通信待ちのユーザーストレスを軽減することができます。

最後に

最後まで読んでいただきありがとうございます。
まだまだ発展途上のSimplogですが、今後更なる改善を予定しております。
「シンプルさ」にこだわり、よりリッチなサービスを目指して日々進化していきますので、引き続きどうぞよろしくお願い致します。

【Simplog】http://simplog.jp/

はじめまして。2011年入社の根岸と申します。

9月まで「あそんで♪HuggPet」というゲームのディベロッパーをしており、10月から新規ゲームのプロジェクト責任者(PS)をしております。


今回の記事では、「あそんで♪HuggPet」で使用している「ボタン」の実装方法について、少しだけお話させていただきたいと思います。


ボタンは押したらハイライトしてほしい

先日、居酒屋で「すみませ~ん!」と大声で店員を呼んだのですが、反応がありませんでした。

その後、すぐに店員が来たので問題無いと言えば無いのですが、私は店員に声が届いているのか不安で、危うくもう一度大声を出して呼ぶところでした。

もし、店員の「はい!ただいまお伺いしま~す!」の一言があれば、私は不安にならずに済みました。

店員には、呼ばれたらまず返事をしてほしいです。


これは、ボタンでも一緒だと思います。

日頃、スマートフォンのブラウザサービスを見ていると、ボタンを押しても視覚的な変化(Active効果)のないもの(特にゲーム)を時々見かけます。

押しても変化がないと、ユーザーはちゃんと押せたのか、押し間違えていないか、不安になってしまうのではないでしょうか?

ボタンを押した後、遷移に時間がかかるのはある程度仕方ないですが、ボタンが押されたらまずは視覚的に変化させて「ちゃんとココが押せているよ」ということを教えてあげるべきだと思います。


店員は、呼ばれたらまず返事をしてほしい。

ボタンは、押したらまずハイライトしてほしい。


リンクボタンを実装する上での問題点

「あそんで♪HuggPet」の初期の開発において、リンクボタンを、aタグを用いて次のように実装していました。

(良くない例です)

/* CSS */
<style type="text/css">
    .btnRoundedRect{
        font-size:20px;
        line-height: 40px;
        width:200px;
        height:40px;
        border-radius: 15px;
        border:5px solid #FF85A3;
        background-color:#FF3366;
        text-align: center;
    }
    .btnRoundedRect a {
        text-decoration: none;
display:block;
color:#FFFFFF;
    }
</style>

/* HTML */
<div class="btnRoundedRect">
<a href="http://pet.ameba.jp">サンプル1</a>
</div>

しかし、この実装ではいくつかの問題がありました。


1. ブラウザのデフォルトのActive効果がイケてない

iOS端末、Android端末では、例えば次のようになります。

サンプル1

このデフォルトのActive効果はシステマチックで、HuggPetのデザインには合いませんでした。

2. Android端末のブラウザで、aタグのバグがある

HuggPetでは、ページ遷移を減らすために、擬似的なポップアップを使用しています。

HuggPet3


これは、ベース要素の上に、ポップアップの要素をz-indexを用いて重ねているのですが、ポップアップ要素内をクリックすると、ベースの要素にあるaタグが反応してしまうバグがありました。


<再現方法>

1. 子に<a>を入れた要素A、Bを用意する

2. Bを「position:absolute」「z-index」を使ってAに重ねる

3. Aにある<a>をタップすると、Bを貫通してAの<a>が反応する


リンクボタンの実装方法

そこで私たちがとった実装方法は、

 1. buttonタグ(divタグ)を使用

 2. そのbutton要素に、タップ時のHover効果を、JavaScriptで追加

 3. そのbutton要素に、タップ時の処理(ページ遷移)をJavaScriptで追加

というものでした。


しかし、全てのbuttonに対して、1つ1つjavascriptで処理をバインドするのは大変だし、ミスも生じやすいです。

また、JavaScriptの知識のないHTMLディベロッパーも開発に携わるため、プロジェクト進行上問題がありました。リンクを1つ追加するのに、Javascriptのできるディベロッパーに依頼しなくてはいけなくなってしまうのは、開発効率が悪いです。

そこで、

 1. Active効果を追加するCSSクラス「enableActive」を作成し、そのクラスのある要素にJavaScriptでActive処理をバインド

 2. ページ遷移処理を追加するCSSクラス「enableLink」を作成し、そのクラスのある要素にJavaScriptでページ遷移処理をバインド

という手段をとりました。

/* CSS */
<style type="text/css">

        button{
            background-color:transparent;
            border: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
        }
        .btnRoundedRect div{
            width:200px;
            height:40px;
font-size:20px;
            line-height: 40px;
            border-radius: 15px;
            text-align: center;
color:#FFF;
border:5px solid #FF85A3;
background-color:#FF3366;
        }
        .btnRoundedRect .active{
            border-color:#DF2956;
            background-color:#CA224B;
        }
</style>


/* Javascript (jQueryが必要)*/
<script language="JavaScript">
        <!--
        $(function(){
            //アクティブ効果を有効にする
            $(".enableActive").on("touchstart mousedown",function(){
                $(this).find("div").addClass("active");
            });
            $(".enableActive").on("touchend mouseup mouseout",function(){
                $(this).find("div").removeClass("active");
            });
            //リンクを有効にする
            $(".enableLink").on("touchend mouseup",function(){
                alert($(this).data("link")+"に移動します。");
                location.href=$(this).data("link");
            });
        });
        //-->
</script>


/* HTML */
<button class="btnRoundedRect enableActive enableLink"
    data-link="http://pet.ameba.jp">
    <div>サンプル2</div>
</button>


実行結果は、以下のようになります。

サンプル2

このようにすれば、押したらハイライトするリンクボタンを、HTMLの知識のみで量産することができます。

最後に

ボタンをハイライトさせる実装の例として、「あそんで♪HuggPet」での実装方法をご紹介しました。

「あそんで♪HuggPet」は、ボタンのハイライトや、擬似的なポップアップ等、ユーザーの皆様に快適に遊んでいただけるように工夫しています。
今後も、スマートフォンブラウザで、より快適に遊べるゲームをつくっていきます。

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


こんにちは、ピグディビジョンでフロントエンドの開発を担当しているHAKASHUN(@HAKASHUN)です。

今回は、Fireworksにおけるスクリプト実行についてお話したいと思います。



Fireworksにおけるスクリプト実行とは?



Fireworksでは、[コマンド] > [スクリプトを実行]で、.jsfという拡張子のファイルを実行することができます。

.jsfという拡張子はFireworksオリジナルのファイル形式ですが、中身はJavaScriptであるため、Fireworksの様々な機能を、JavaScript言語で制御することができます。

多数のレイヤに対して反復して同じ作業を行いたいときや、ピクセル単位の計算を正確に作業に反映させたいときなどに、時間のコストや作業ミスのリスクを軽減してくれます。



簡単なスクリプトを作って実行してみる

事始めとして、下記の画像のような簡単な図形を描画しておき、スクリプトを使って100個のレイヤを複製してみます。

square

.jsfファイルを作成して、その中に実行したいスクリプトを記述していくのですが、初めは、実際に何をどのように書けばいいのかわからないと思います。Adobeが公式に出しているリファレンスもあるのですが、現在英語のものしか存在していません。



ヒストリーパネルを使って、jsfファイルに何を書けばよいのかのヒントを掴む。

右も左もわからない状況から脱するために、ヒストリーパネルを活用することにします。ヒストリーパネルには、Fireworksの一つ一つの処理で行われているスクリプトをクリップボードにコピーしてくれる機能があり、スクリプトを書く上での大きな助けとなります。



square



今回は、図形を[コピー]し、[ペースト]する作業を複数回実行するスクリプトをつくるため、まずは普段Fireworksでしているのと同じように、1回だけ図形をコピー&ペーストし、その処理スクリプトをクリップボードにコピーすることにします。



historyPanel



上記画像の枠線内のボタンをクリックすると、コピーとペースト処理がクリップボードにコピーされます。



.jsfファイルを作成する。

コピーが完了したら、任意の名前(ここではcopyAndPaste.jsf)で.jsfファイルを作成し、エディタを開いて編集していきます。

先ほどコピーしたスクリプトをエディタ上でペーストすると、以下の記述が貼付けられます。



fw.getDocumentDOM().clipCopy();
fw.getDocumentDOM().clipPaste("ask user", "vector");


1行目で、選択状態のオブジェクトをコピーし、2行目でコピーしたオブジェクトをペーストしています。

これを100回実行すれば、100個のレイヤが複製されるため、さらにjavaScriptのfor文を使って、内容を以下のように編集します。



for(var i = 0; i < 100; i++){
    fw.getDocumentDOM().clipCopy();
    fw.getDocumentDOM().clipPaste("ask user", "vector");
}


これで、1つのオブジェクトから、100個のレイヤを複製するスクリプトが完成しました。



作成したスクリプトを実際に使ってみる

それでは、実際に作成したスクリプトを使って、オブジェクトのレイヤを100個複製してみます。







[コマンド] > [スクリプトを実行]を選択し、作成したjsfファイルを選択すればスクリプトが実行されます。







無事に想定した処理を実行することができました。





jsfスクリプト作成の手順や考え方[初級編]

上記簡易サンプルでは、主に2つの手順にわけてスクリプトを組み立てていきました。



approach



  1. 実行させたい処理を分割して考え、それぞれがどのように行われているのかをヒストリーパネルでクリップボードにコピーする。
  2. 上記でコピーした一つ一つの処理とJavascriptを組み合わせて、思い通りの処理を実行するスクリプトを組み立てる。


実にシンプルな例でしたが、このようにまずは簡単な図形などで試していくと、Fireworksの様々な処理がどのようなスクリプトで実行されるのかの理解を効率よく深めていけると思います。



少し複雑なスクリプトを作って実行してみる

次にもう少し複雑なスクリプトに挑戦してみたいと思います。

ちょうど先日、
  • 一つのレイヤ群から大量のカラーバリエーションを作成し、
  • なおかつレイヤー名も決められた規則でつけていく
というスクリプトを作成する機会があったので、それをモデルにして、複雑なスクリプトを作成する際に、有用な情報をお伝えできればと思います。



DOM Inspectorをインストールする

DOM Inspector(http://fireworks.abeall.com/extensions/panels/#DOM-Inspector)

複雑な処理を実行するには、Fireworksの内部構造をできるだけ理解する必要があります。DOM Inspectorは、FireworksにおけるGUIでの操作で、内部状態がどのようになっているのかを表示してくれるツールです。スクリプトを組み立てていくのに大変役に立ちます。

上記リンクから、swfをダウンロードし、Fireworksアプリケーションフォルダ内のCommand Panelsフォルダの中に入れることで、インストールすることができます。





Fireworksを再起動すれば、上部メニューの[ウィンドウ]リストに[DOM Inspector]欄が追加されています。 DOM Inspectorを表示した状態で、オブジェクトを選択などすると、Fireworksがどのように情報を持っているのか確認することができます。







例えば、jsfファイルの中で、opacityの値を変更する処理を書けば、スクリプトを用いて不透明度を変化させることができるし、カンバス上での位置やオブジェクトの大きさ、色なども、スクリプト上でどの値を操作すれば変更できるのか確認することができます。例として簡単なスクリプトを以下に掲載しました。

var select = fw.selection[0]; //選択している要素を取得
select.opacity = 10;
select.top = 0;
select.left = 0;




Javascriptに精通している人であれば、DOM Inspectorの内容を見て、かなり高度な処理スクリプトを記述できると感じるはずです。初めは.jsfファイルに何を書けばいいか全くわからなかったと思いますが、ここまででグッとFireworksスクリプトへの苦手意識が小さくなったはずです。

一つのオブジェクトから、大量のカラーバリエーションを作成するスクリプト

DOM Inspectorという強力な味方を手にした所で、本題のスクリプトを書いていきます。 このスクリプトは、あらかじめ下記のようなレイヤ構成のカラーセット(color_0)があったとして、色の異なるバリエーションcolor_1、color_2をスクリプトによって作成するものを目指します。







以下、ポイントだけを絞ってスクリプトの説明をさせていただきます。

レイヤをコピーし、命名規則に従って名前を変更するスクリプト

はじめに、色の変更処理は後回しにして、カラーセットごとにレイヤをコピーし、命名規則に従って名前をつけるスクリプトを作成します。

var dom = fw.getDocumentDOM(); //color_0レイヤーを取得
var colorNum = 3; //カラーバリエーションの数

for(var i = 1; i < colorNum; i++){
    dom.duplicateLayer(-1, 1, "after current"); //レイヤーを複製
    var layer = dom.layers[dom.currentLayerNum];
    layer.name = 'color_' + i; //複製したフォルダ名を変更
    var selects = fw.selection; //複製したフォルダ内のオブジェクトを選択
    for(var j = 0; j < selects.length; j++){
        selects[j].name = 'color_'+ i +'_' + j;//オブジェクト個々の名前を変更
    }
}


dom.duplicateLayer(-1, 1, "after current")で、color_レイヤーを複製し、layer.name = 'color_' + i;で、color_1、color_2という名前を最上位レイヤにつけています。 var selects = fw.selection;で、カラーセット内のオブジェクトを全て取得し、その次のfor文の中で、オブジェクトの名前を命名規則に従ってつけています。

このスクリプトを実行すると、以下のようになるはずです。







色を置き換える処理を付け加える

レイヤを複製し、それぞれのレイヤ、オブジェクトの名前を変更できた所で、色を置き換える処理を付け加えます。 color_0は、4種類の赤色を使っているので、color_1、color_2のカラーセット用にもそれぞれ4つの色を定義します。

var colorSet = [
    ['#FFBFBF', '#FF7373', '#FF2626', '#D90000'],
    ['#BFCFFF', '#7297FF', '#1D5DFF', '#0036E1'],//color_1の色セット
    ['#C4FFB8', '#82FF5A', '#52FF00', '#3DD900']  //color_2の色セット
];
次に、この配列定義を用いて、for文でオブジェクトの名前を変更する際に色の変更も行うようにします。 DOM Inspectorで確認すると、オブジェクトの色は、fw.selection.pathAttributes.fillColorで定義されていたので、その値を変更するようにします。





for(var i = 1; i < colorSet.length; i++){
    dom.duplicateLayer(-1, 1, "after current");
    var layer = dom.layers[dom.currentLayerNum];
    layer.name = 'color_' + i; //コピーしたフォルダ名を変更
    var selects = fw.selection; //コピーしたフォルダ内のレイヤーを選択

    for(var j = 0; j < selects.length; j++){
        selects[j].name = 'color_'+ i +'_' + j;//レイヤー個々の名前を変更
        //▼オブジェクト個々の色を配列定義に基づいて変更

        selects[j].pathAttributes.fillColor = colorSet[i][j];

    }
}
これで、本題のスクリプトが完成しました。最終的に完成スクリプトは以下のようになります。
var colorSet = [

    ['#FFBFBF', '#FF7373', '#FF2626', '#D90000'],
    ['#BFCFFF', '#7297FF', '#1D5DFF', '#0036E1'],//color_1の色セット
    ['#C4FFB8', '#82FF5A', '#52FF00', '#3DD900']  //color_2の色セット
];

for(var i = 1; i < colorSet.length; i++){
    dom.duplicateLayer(-1, 1, "after current");
    var layer = dom.layers[dom.currentLayerNum];
    layer.name = 'color_' + i; //コピーしたフォルダ名を変更
    var selects = fw.selection; //コピーしたフォルダ内のレイヤーを選択

    for(var j = 0; j < selects.length; j++){
        selects[j].name = 'color_'+ i +'_' + j;//レイヤー個々の名前を変更
        selects[j].pathAttributes.fillColor = colorSet[i][j]; //オブジェクト個々の色を変更
    }
}
簡単なJavascriptとDOM Inspectorが表示してくれるFireworks内部の構造を使って、複雑な処理を一瞬で仕上げてくれるスクリプトができました。 実際に実行しても、ちゃんと期待する結果が反映されます。







jsfスクリプト作成の手順や考え方[上級編]

初級編ではjsfスクリプト作成のポイントとして、以下の2つをあげました。

  • 実行させたい処理を分割して考え、それぞれがどのように行われているのかをヒストリーパネルでクリップボードにコピーする。
  • 上記でコピーした一つ一つの処理とJavascriptを組み合わせて、思い通りの処理を実行するスクリプトを組み立てる。
より高度なjsfスクリプトを作成する場合は、さらに、
  • DOM Inspectorを用いてFireworks内部の構造やデータの持ち方を理解する
ことが不可欠になります。少し難しいですが、コツをつかむことができれば、サンプルスクリプトのようにシンプルな記述で大幅に時間とミスを縮小してくれるスクリプトを作ることができると思います。

jsfスクリプト特有のメソッドやプロパティに慣れ親しめば、英語で書かれた公式Fireworksドキュメントも少しずつ理解できるようになるはずです。



最後に

Fireworksを長年使っている人でも、あまりチャレンジしたことがないスクリプト実行についてお話しました。

普段カーソルを動かして実行している様々な処理を、スクリプトを使って実行するのは、特に単調な反復処理を一気に終わらせる際に大変便利です。 私自身も以前、単純作業でも、絶対にミスのできない処理を大量にしなければならない際に、先輩にスクリプトを作成してもらい、大変感激したことがありました。

中々文献の少ないjsfスクリプトですが、少し頑張って探せば、公開されている便利なスクリプトを見つけることができます。ダウンロードしてスクリプトの中身を読んだり、自分なりにカスタマイズするのも大変勉強になると思います。

ぜひjsfスクリプトでもっともっとFireworksを使いこなしてみましょう^^

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



------------------------------------------

written by HAKASHUN

twitter:@HAKASHUN

Blog: http://hakashun.net/



こんにちわニコニコ
第2ソーシャルゲームDivの渡辺(@propeland)です
新しい技術と風邪の流行にはいち早く乗ってしまうFlashメインのDeveloperです

iOSではFlashが使えないためスマートフォンではちょっと影の薄くなった汗Flashですが
実はまだまだ使えるんです!!

今回はUnityとFlashで簡単にアニメーションを作成するアセットと使い方をご紹介しますチョキ
(Unityについてはある程度触ったことがあるという前提で進めます)

従来だと、デザインを反映させたりアニメーションを付けるのは
Textureを作って、ゲームオブジェクトを配置して・・・・と
Unityの操作に慣れていないと大変でしたが
uniSWFというAssetを使うとデザイナーさんやFLASHerさんの慣れ親しんだ
Flashで簡単にUIやアニメーションが作ってそのまま使うことができます
余計な手間はかかりません

uniSWFは2012年の6月に出たばかりの新しいAssetなのでまだまだ資料があまりありませんが
人気のNGUIよりも使いやすいのでは…と思っています

・:,。゚・:,。★゚・:,。゚・:,。☆


それでは実際にuniSWFを使ってFlashのデータをUnity上で使ってみましょう音譜

まず新しいプロジェクトを作成します
そしてAssetStoreからuniSWFをダウンロード&importします

サンプルは特に必要なければimportから外してかまいません

importが終わるとProjectウィンドウにuniSWFのインストーラーが登場します

ダブルクリックでインストールするとuniSWF converterというAIRアプリが立ち上がります
(AIRのバージョンが古いとAIRのインストールが促されます)

uniSWFのインストールはこれで完了です!
ComponentメニューにuniSWFが追加されます


次にカメラの準備をします
Hierarchyウィンドウにデフォルトで配置されているMain Camera

このMain Cameraを選んだ状態で
Component->uniSWF->MovieClipOverlayCameraBehaviour
を選択してコンポーネントを追加します



コンポーネントを追加したCameraのProjectionの設定をorthographicに変更します

これでUnity側の設定は終了です


再生するFlashの準備をします
簡単なアニメーションをつけたMovieClipを用意します


このMovieClipにリンケージを設定します

uniSWFではリンケージ名を使って読み込みを行うため、
使いたいMovieClipの最上層に必ずリンケージを設定します
ここでは「mc_root」という名前をつけています
(ネストしたMovieClipは自動的に読み込まれます)

プロジェクトのAssetフォルダの中にswfというフォルダ(名前は任意です)を作って
そこにFlashを保存してパブリッシュします
Flashの名前はAnimation.swfにしました

Flashの準備はこれで終わりです


ではUnityに戻りましょう
新しいswfが作成されるとuniSWF converterがExportするか聞いてきます
Exportボタンを押すと自動的にResourceフォルダの中にswf情報が作成されます

Flashを再生するために簡単なスクリプトファイルを作成します



スクリプトファイルを開いて次のようなスクリプトを書きます

using UnityEngine;
using pumpkin.display;

public class ClassName:MonoBehaviour
{
    void Start ()
    {
        Stage stage = MovieClipOverlayCameraBehaviour.instance.stage;
        MovieClip rootMc = new MovieClip("swf/Animation.swf:mc_root");
        stage.addChild(rootMc);
    }
}

このスクリプトを保存してMain Cameraにドラッグして関連付けます

さっそくUnityの再生ボタンを押します
プレビュー画面にFlashで作成したアニメーションが再現されます
ものすごーく簡単です!


ではスクリプトを1行ずつ説明していきます

using pumpkin.display;
これはMovieClipを表示/操作するためのパッケージです
MovieClipクラスが含まれています
MovieClipの操作にはFlashと同じように
gotoAndStop("label")play("label")といったタイムライン関数が使えます

Stage stage = MovieClipOverlayCameraBehaviour.instance.stage;
Stageはシングルトンのためnewで作成せずこのように参照します
このStageはFlashのStageと同じ意味です

MovieClip rootMc = new MovieClip("swf/Animation.swf:mc_root");
ここでMovieClipを参照しています
引数にはAsset以下のswfのパス:リンケージ名を指定します
この記述でメモリ上にMovieClipがロードされます
まだ画面上には表示されません

stage.addChild(rootMc);
DisplayContainerへの登録です
ここではステージに追加していますが
すでにステージに登録されているMovieClipに対しても登録ができます

今回のサンプルではMovieClipの再生だけを紹介しましたが
それ以外にもイベントリスナの登録、フレームスクリプトの追加、
入力フォームの作成、などたくさんの機能があります
…が1記事ではおさまりませんでした
詳しい使い方などTwitter等で気軽に聞いてください


最後にuniSWFを使うことのメリットについてですが

・スクリプトが簡単!特にFlashを使ってきた人には分かりやすい!
・デザイナーの作ったUIをそのまま反映させることができる
・Textureの作成などを意識しなくてすむ
・アニメーションをFlashで作るので楽&作り方が簡単
・UIの変更があってもswfを更新するだけでOK
・使いまわしたMovieClipはDraw回数が増えないのでメモリにも優しい
・いままでのFlashの素材を使いまわせる
・出たばかりで絶賛アップデート中なので意見をどんどん聞いてくれる!
・1個のFlashデータでAndroidもiOSも作れる♪
というあたりかと思います

スマートフォンアプリを作っている方は一度お試しください

反響があればまた応用編も書きたいので気になった方はお問い合わせお願いします(笑)


はじめまして!2012年入社の新卒デザイナー松本です。
現在、女子中高生向けのスマートフォンサービスのウェブデザインやイラストを制作しています。

今回は私が制作した、Candyというサービスのオフィシャルキャラクターの事例を元に、
女子中高生にとっての「かわいい」とは何か、そして「かわいい」キャラクターの制作方法をご紹介したいと思います。


※Candyについては、こちらの記事をお読みください。
「女性向けソーシャルコミュニティサービス "Candy"」

女子中高生の実態

Candyは女子中高生向けのサービスなので、女子中高生に刺さる「かわいい」と思ってもらえるキャラクターを作る必要がありました。
しかし私は女子中高生ではないため、彼女達が何をかわいいと思うのかがわかりません。

そこで、まずは今の女子中高生の文化や生活を知ることからはじめました。
女子中高生向けの雑誌を読んだり、渋谷109の雑貨ショップに行って今人気のキャラクターを調査したりしました。

その結果、今の女子中高生にはキモカワ系のキャラクターが人気だということがわかりました。

何パターンものキャラクター制作

調査してわかったことを元に、様々な種類のキャラクターを制作していきます。

キモカワ系のキャラクターを作る際のポイントとして、
・あまり表情のない顔
・単純なシルエット
・ギョロ目
・現実にはいない不思議な生物
・女子中高生が好きなモチーフ(ハートなど)をキャラに取り入れる
等に気を付けて制作しました。

キャラクターはペンタブレットを使ってIllustratorで描いていきます。
ざっくりとラフを描いた後、パスを整えながら表情や髪型等を調整していきます。


まずはとにかく数を増やすことを目標にし、最終的に14体のキャラクターを制作しました。


※Illustratorでのイラストの描き方については、こちらの記事を参考にしてください。
「Illustratorによるイラスト制作の基本操作」

アンケート、投票

キャラクターが描けたら、今度は本当にそのキャラクターが女子中高生に刺さるのか、
どのキャラクターが人気なのかを知る為に、渋谷109前で市場調査をしました。

道ゆく女子中高生たちに声をかけてアンケートに協力して頂き、
・どのキャラクターが一番好きか
・そのキャラクターの好きなところ
・そのキャラクターの改善点
などを聞いていきます。



2日間かけてアンケートを行った結果、一番人気のあるキャラクターはこの子たちに決まりました。


次は、頂いたアンケート結果をもとに、このキャラクターをブラッシュアップしていきます。

キャラクター設定

キャラクターを作りながら、キャラクターの設定も同時に考えていきます。

Candyというサービスのキャラクターなので、「飴の妖精」というコンセプトで制作しました。
サービスのロゴの色を各キャラクターに使用し、どんなタイプの女の子にも親しみを持ってもらえるように、それぞれ性格の異なる5人組のキャラクターにしました。


ピンクがゆるふわ、オレンジがギャル、緑がオタク、水色がまじめ、紫がセクシー、というキャラ設定になっています。
キャラクターの趣味や性格、言葉遣いなどを詳細に決めることで、キャラクターのポーズやキャラクター同士の絡みなどを考えやすくなります。

名前は最後まで悩んだのですが、キャラクター制作が得意な社員にヒアリングを行い、
各キャラクターの色の味+女子中高生がよくあだ名などに使う言葉+キャンディの「ぺろ」で「○○っぺ」でいくことにしました。
5人あわせて「ぺろちゃんず」というキャラクターです。


実はぺろちゃんずには、隠れキャラのコラっぺもいます。

コラっぺには、普段は表に出ずに、エラーページやメンテナンスページなどで活躍してもらっています。
簡素でシステマチックになりがちなエラー・メンテページでも、キャラクターを配置することで世界観を出すことが出来ます。

キャラクターの活用例

キャラクターが完成し世の中にデビューしたあと、実際にサービスでどのように活用されているかをご紹介します。

・ユーザーの反応
初めてユーザーの皆さんにお披露目したときの反応はとても良く、
「かわいい」や「キーホルダーにして売ってほしい」などのコメントが沢山寄せられました。



・チュートリアル
サービスを始めると最初に出てくるチュートリアルにぺろちゃんずを出すことで、
チュートリアルを楽しそうに見せてサービスを進めたくなるような工夫をしました。



・キャラクターブログスキン
チュートリアルを最後まで終わらせるともらえるご褒美として作ったブログスキンです。
スタッフブログのスキンとしても使われています。



・デコメコラボ
「デコリ屋さん」というAndroidアプリとコラボして、ぺろちゃんずのデコメを作って頂きました。


このように、サービスを盛り上げるために様々なところでキャラクターを使用しています。
ゲームではなくコミュニティサービスなので、キャラクターを全面に出すことはあまりありませんが、
公式キャラクターを設定することで、ユーザーに親しみやすさを与えたり、他のサービスとのコラボが実現しやすくなります。
サービス内だけでなく、チームでもPCのデスクトップの壁紙をぺろちゃんずにしたりして、みんなで可愛がっています。

おわりに

最後までお読みいただきありがとうございました!
Candyのリンクを貼っておきますので、まだCandyを使ったことのない方は、ぜひぜひ使ってみてくださいね。
【Candy】http://candy.am

これからハロウィンに向けて、ハロウィン仕様のぺろちゃんずが登場するので、チェックしてみてください。
これからもCandyをよろしくお願いします!

はじめまして、ブロググループでフロントエンドの開発を担当している泉と申します。
クリエイティブアカデミー※1を経て、2012年5月に中途入社いたしました。

今回は、スマートフォン版アメーバブログの画像コンテンツで使ったタッチイベントの技術について少しお話させていただきます。
スマートフォンフォン版のページ制作ということで、HTML5/CSS3/JavaScriptを組み合わせて制作していきます。
※1 弊社が実施したクリエイター・エンジニア向けの無料セミナーで、私は「HTML5/CSS3/JavaScript」コースでスマートフォンWebアプリケーションの制作を学びました。アカデミーの模様は、弊社渡辺が書いた記事をご参照下さい。
クリエイティブアカデミー レポート


仕様について

1、フリックを使った画像の切り替え


1 pixel|サイバーエージェント公式クリエイターズブログ-flick_image

今までは、現在見ている画像から次(前)の画像を見るためには、リンクをタップしてもらって該当の画像ページに遷移させる必要がありました。
しかし今回はユーザにストレスを与えないために、ページ遷移しなくても画像が切り替わるように実装します。

2、表示されている画像のピンチイン/アウト(拡大/縮小)


1 pixel|サイバーエージェント公式クリエイターズブログ-pinch_image


タップされた時のイベントハンドリング

スマートフォンでタップされた時のイベントのハンドリングの方法は様々あると思いますが、今回はTouchイベントとGestureイベントを使用します。

Touchイベント

Touchイベントは指が1本以上タップされた時に発生します。
・touchstart・・・スクリーンに指が触れた
・touchmove・・・スクリーンに指が動いた
・touchend・・・スクリーンから指が離れた
・touchcancel・・・システム側でキャンセルされた(着信など)

Gestureイベント

2本以上の指でタップされた段階でTouchイベントに加えてGestureイベントが発生します
・gesturestart・・・2本目(2本以上)の指がスクリーンに触れた
・gesturechange・・・2本以上の指が動いた
・gestureend・・・触れているどれかの指が離れた

これらのイベントをハンドリングしながら、実際に制作していきます。

フリックを使った画像の切り替え

ここからはサンプルコードを使ってご説明します。

HTML 例
<div id="imgList" style="-webkit-transform:translate3d(0%, 0%, 0px);">

<div style="-webkit-transform:translate3d(-100%, 0%, 0px);"><img src="sample01.jpg" id="img01"></div>・・・画像a

<div style="-webkit-transform:translate3d(0%, 0%, 0px);"><img src="sample02.jpg" id="img02"></div>・・・画像b

<div style="-webkit-transform:translate3d(100%, 0%, 0px);"><img src="sample03.jpg" id="img03"><div>・・・画像c

</div>

<div id="animationLayer"></div>

JavaScript 例
var startX;
var moveX;
var eventKind = '';
var elm = document.getElementById('animationLayer'); //タップを取得するエレメントを定義
var slide = document.getElementById('imgList'); //スライドさせるエレメントを定義
var slidePosition = 0;
var imgPosition = 0; //初回アクセス時の画像を0番目として、見ている画像の番号を格納する

elm.addEventListener('touchstart', touchStart, false);//タップされた瞬間
elm.addEventListener('touchstart', touchMove, false);//指を動かしている
elm.addEventListener('touchstart', touchEnd, false);//指が画面から離れた

//タップされた瞬間に実行されるメソッド
function touchStart(e) {
switch (e.touches.length) {
case 1:
eventKind = 'flick';
flickStart(e);
break;
default:
break;
}
}

//指が動いている時に実行されるメソッド
function touchMove(e) {
e.preventDefault();
switch (e.touches.length) {
case 1:
flickMove(e);
break;
default:
break;
}
}

//指が離れた時に実行されるメソッド
function touchEnd(e) {
switch (eventKind) {
case 'flick':
flickEnd(e);
break;
default:
break;
}
}


function flickStart(e){

//スタート時のX座標を保持
startX = e.touches[0].pageX;

//タップした瞬間の id="imgList" のX方向のポジションを取得
slidePosition = window.innerWidth * imgPosition;

}

function flickMove(e){

//指が動いた距離を計算
moveX = startX - e.touches[0].pageX;

//指が動いた分 id="imgList" を移動させる
slide.style.webkitTransform =
'translate3d(' + ((slidePosition - moveX) * -1) + 'px, 0px, 0px)';
}

function flickEnd(e){

//指が動いた距離を計算
moveX = startX - e.touches[0].pageX;

//指を離した場所と最初にタップ場所が100px以上離れていたら自動的に次の画像を表示する
//スライドさせる方向を判定
//右の画像を表示させる時は+、逆はー
if(moveX > 100){
imgPosition += 1;
}
else if(moveX < -100){
imgPosition -= 1;
}

//(表示させている画像のポジション × -100)% 分移動させる
slide.style.webkitTransform =
'translate3d(' + (imgPosition * -100) + '%, 0px, 0px)';
}



今回はサンプルとしてスライドさせる部分のHTMLと、実際にスライドさせるJavascriptのソースを用意しました。

タップを検知するエレメントに<div id="animationLayer"></div>を用意しました。
<div id="animationLayer"></div>はスクリーンいっぱいのサイズで、レイヤー最前面に
用意します。

<div id="imgList"></div>が画像を囲っているエレメントで、その下に表示する画像が
横並びになるようにマークアップします。
<div id="imgList"></div>をスライドさせることで前後の画像を表示させたいと思います。

大まかな処理の流れは以下のようになります。
1:タップされた指の数を判定
2:id="imgList" のX方向のポジションを取得
3:指を動かした距離分 id="imgList" をスライドさせる
4:ある程度(今回は100pxに指定)スライドさせて指を離したら、自動的に次(前)の
  画像をスライドさせる

大事なポイントを簡単にご説明します。

まず、タップしている指の数を取得するときはe.touches.lengthを使います。
touchXXXX系のイベントはtouchesという名前でタップした指の分だけ指の情報の
オブジェクトを配列で持ちます。
例:1本目の指・・・e.touches[0]、2本目の指・・・e.touches[1]
1本だけしかタップされていない場合は配列に1つしかオブジェクトが存在しないことに
なるので、指の数を取得するときはlengthプロパティで取得することができます。

そしてtouchesの中のpagexXプロパティでタップした指のX座標を取得することができます。
例:e.touches[0].pageX。

JavaScriptでインラインstyleを指定していますが、今回のようにベンダープレフィックス付きの
プロパティを指定したい時は"webkitXxxxx"という風に記述します。
例:translate3dを使いたい時
  ・・・element.style.webkitTransform = 'translate3d(Xpx, Ypx, Zpx)';

【注意点】
touchendの時はe.touchesが空になってしまうため、指の本数が取れません。
そこでtouchstart時にどのようなアクションが実行されているかあらかじめ保持して、
touchend時はその保持されたアクションの内容を見て実行するメソッドを出し分ける必要が
あります。

また、指を動かしている時にデフォルトの画面の動きを止めないといけないので、
各メソッドを実行する前にe.preventDefaultをコールして何も動作しないように制御する必要が
あります。

表示されている画像のピンチイン/アウト(拡大/縮小)

以下、サンプルコードになります。
HTMLはフリックと同じ物を使用します。(拡大する画像はsample01.jpgとします)

HTML 例
<div id="imgList" style="-webkit-transform:translate3d(0%, 0%, 0px);">

<div style="-webkit-transform:translate3d(-100%, 0%, 0px);"><img src="sample01.jpg" id="img01"></div>・・・画像a

<div style="-webkit-transform:translate3d(0%, 0%, 0px);"><img src="sample02.jpg" id="img02"></div>・・・画像b

<div style="-webkit-transform:translate3d(100%, 0%, 0px);"><img src="sample03.jpg" id="img03"><div>・・・画像c

</div>

<div id="animationLayer"></div>

JavaScript 例
var startDistance;
var moveDistance;
var currentScale = 1;
var saveScale = 1; //拡大率(縮小率)の初期値
var eventKind = '';
var elm = document.getElementById('animationLayer'); //タップを取得するエレメントを定義
var img = document.getElementById('img01'); //拡大させる画像を定義

elm.addEventListener('touchstart', touchStart, false);//タップされた瞬間
elm.addEventListener('touchstart', touchMove, false);//指を動かしている
elm.addEventListener('touchstart', touchEnd, false);//指が画面から離れた

//タップされた瞬間に実行されるメソッド
function touchStart(e) {
switch (e.touches.length) {
case 1:
eventKind = 'flick';
case 2:
eventKind = 'pinch';
pinchStart(e);
break;
default:
break;
}
}

//指が動いている時に実行されるメソッド
function touchMove(e) {
e.preventDefault();
switch (e.touches.length) {
case 2:
pinchMove(e);
break;
default:
break;
}
}

//指が離れた時に実行されるメソッド
function touchEnd(e) {
switch (eventKind) {
case 'pinch':
pinchEnd(e);
break;
default:
break;
}
}


function pinchStart(e){

//スタート時の指の距離を保持
startDistance = getDistance(e);

}

function pinchMove(e){

//2本指の距離を計算
moveDistance = getDistance(e);

//start時の距離を基準に動いた比率を計算
currentScale = moveDistance / startDistance;

//拡大率を算出
saveScale = saveScale * currentScale;

img.style.webkitTransform =
'scale3d(' + saveScale + ',' + saveScale + ', 1)';
}

function pinchEnd(e){
if(saveScale < 1){
saveScale = 1;
img.style.webkitTransform =
'scale3d(' + saveScale + ',' + saveScale + ', 1)';
}
}

//指の距離を測るメソッド.
function getMeasure(e) {
return Math.sqrt(
Math.pow(
Number(e.touches[0].pageX) - Number(e.touches[1].pageX), 2) +
Math.pow(
Number(e.touches[0].pageY) - Number(e.touches[1].pageY), 2));
}
ピンチの大まかな処理の流れは以下のようになります。
1:タップされた指の数を判定
2:2本指でタップ瞬間に、指の間の距離を測定
3:動かす度に指の間の距離を測定し、拡大率を保持させつつ画像を拡大
4:どちらかの指が離れた瞬間に拡大率が1以下だったら、拡大率を1にして
  画像を元のサイズに戻す
5:2回目以降のピンチは保持された拡大率と動かしている比率を乗算して拡大率を算出する

2本の指でタップされたのでgestureイベントが使えるようになります。
gestureイベントにはピンチ時の拡大率を返してくれるevent.scaleという素晴らしいプロパティがあります。
よし、これを使おう!っと思ったのですが、Androidで非対応だったので今回は自力で計算することにします。

2本の指の距離は以下の公式で出すことができます。
√((X2 - X1)2 + (Y2 - Y1)2)
数学の授業でやった記憶がある方もいるかと思います。
この公式を頑張って処理してくれているのがgetMeasureメソッドです。

そして動かしている時の距離をピンチスタート時の距離で除算ことで拡大率を算出することが
できます。
currentScale = moveDistance / startDistance;

次に保持してある拡大率に、動かしている時の拡大率を乗算することで最終的な拡大率を
算出します。
(初回はsaveScaleに拡大率1を保持しておく)
saveScale = saveScale * currentScale

あとはフリックの時と同じようにtransformの値をエレメントに適用するだけで
ピンチイン/アウトされるようになります。
今回は拡大縮小させるのでscaleプロパティを使います。
img.style.webkitTransform = 'scale3d(' + saveScale + ',' + saveScale + ', 1)';

最後に

今回ご紹介した内容はタッチ系イベントの基礎的な部分ですが、基礎的な技術でフリックや
ピンチイン/アウトの実装も簡単にできてしまします。
もし機会がありましたら、オリジナルのフォトギャラリー等を作ってみてはいかがでしょうか。

私ももっと深く追求して、Webブラウザで表現出来る可能性を探ってみたいと思っております。

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




こんにちは。アメーバ事業本部ピグディビジョン
ライフチームでデザインを担当しています沖本です。

$1 pixel|サイバーエージェント公式クリエイターズブログ-okimoto


現在ピグライフチームは
プロデューサー、デザイナー、フラッシュディベロッパー
システムエンジニア、イラストレーター、進行管理、など
トータルで約20名ほどのメンバーで構成されており、
月に2本のイベント運用を行っています。
今回はピグライフでのイベントクエストがどのような流れで
つくられているのかについてお話しさせて頂きます。

イベントテーマを決める

イベントクエストは主にプロデューサー、デザイナー、イベントを担当する
イラストレーターを中心に内容を考えます。
ひとつのイベントを通して、ピグライフで遊んでくれた方々が
どういう気持ちになってほしいかという目的をもって全体のテーマを決めます。

ピグライフは農園ゲームであり、その中でもプラントは
ユーザーのお庭を飾る大事な要素であるため、イベントクエストを考える際は
初めにどんなプラントにするのかを考えます。

1 pixel|サイバーエージェント公式クリエイターズブログ-7月中旬のラベンダーイベントの世界感
<7月中旬のラベンダーイベントの世界感>
ラベンダーイベントでは庭一面がラベンダー畑になり
避暑地のような涼しげなイメージなることが狙いでした


プラントとテーマがきまったら、イベントクエスト毎にあるシネマの登場人物も
大まかに考えます。
プラントに合う料理やインセンティブアイテムを考えて
制作するものが決まったら、早速イラストに取りかかります。


リサーチ・制作

ある程度デザインアイデアが固まったら、イメージが
ピグライフの世界感に合っているかイラストの方向性を確認します。

1 pixel|サイバーエージェント公式クリエイターズブログ-8月のオレンジイベントでのセーラー服のデザイン
<8月のオレンジイベントでのセーラー服のデザイン>
(左)リリースされたアイテム (右)デザイン

ピグライフはお庭のゲームなので、海を連想させるものではなく、お庭で着てもおかしくない
ヨーロッパの子供の遊び着のようなセーラー服になるようにデザインを修正


チェックが通ったら仕上げたり反対側を描き、
イラストが完成したらflashデータにする作業に入ります。

シネマの制作

ピグライフにはシネマとよばれる機能があり、
イベントにまつわるストーリーがクエスト毎に見れるようになっています。
シネマ機能は開発当初ピグライフのクエストの内容を補足することが目的で
つくられたものでしたが、今ではピグライフの世界をつくる大事な一部となっています。
最近シネマジェネレーターの機能が充実して、パンや、ズーム、心の声など
より複雑な描写ができるようになりました。
※詳しくはフラッシュディベロッパーの竹ノ谷のブログ記事をご覧下さい。

【パンを使った演出例】
このように横に広い背景を用意しておき、黒枠から赤枠へパンする
$1 pixel|サイバーエージェント公式クリエイターズブログ-酒場0

■黒枠の時
向こう側に何かをみつけるユーザー
1 pixel|サイバーエージェント公式クリエイターズブログ-酒場1

■赤枠へパン後
目の前に豪華な王冠を発見!
1 pixel|サイバーエージェント公式クリエイターズブログ-酒場2

シネマストーリーはチーム内のライティングに長けたメンバー中心に決めていきます。
イベント内容を決めた時のアイデアと、制作物を元に話の大筋を組み立て、
キャラクター毎の性格を大事にして、言い回しを考えていきます。
絵コンテ制作の後、シネマ制作をし、本番と同じ環境で制作物を確認して、
いよいよリリースです!

世界観作りによりひろがったこと

シネマ機能でNPCに個性をだすことができ、
1st Anniversary企画で人気投票イベントをすることができました。
人気投票で一位になったウシは脅威の総票数1,588,766票!
本当にたくさんの方々に投票していただき大盛況でした。
ありがとうございました!

1 pixel|サイバーエージェント公式クリエイターズブログ-村人人気投票結果

1 pixel|サイバーエージェント公式クリエイターズブログ-3

公式グルっぽ でのピグライフの料理をつくってみる掲示板や
イラスト掲示板の投稿も力作だらけで、チームメンバーみんなでいつも喜んで
拝見させていただいております。
皆さんに愛されるピグ村になりますように努力していきたいと思います。
これからもピグライフをよろしくおねがいします!