AdobeがFlashをHTML5に書き出すツール Wallaby を公開したようです。
Flash® Professional って記載されてるけど、Flex じゃダメなのかな? 今度の例会で質問してみよう。
UIは凄い質素です。
設定もログモードとブラウザ起動設定くらい。
手っ取り早く、Flash CS5のサンプルでConvertしてみる。 サポートされてないモジュールがあるとWarningがでる。
Filter、Advanced Color等、機能によってはコンバートできない。
・jquery: 1.4.2 でもアニメーション処理は、してない模様。
・css: CSS3で webkitのみ対応 CSSアニメーションを使ってるので、重たいと思われる。
・svg: 画像はSVGフォーマットを利用
動きによって CSS3、JavaScriptを使い分けている模様。
アニメーションの基本仕様は、Safari Reference Library -Animations を参照
JavaScript側で webkitAnimationIteration、webkitAnimationStart、webkitAnimationEnd でイベントリスナーを登録し、CSS側で @-webkit-keyframes from ... to を作成。
■JavaScript
・「xxxx_sprite」「xxxx_fs」htmlクラスのエレメントを探す ・左右の揺れは、CSS クラスから -webkit-animation-duration を取得しアニメーション終了時間を計算 ・次のエレメントの取得は nextElementSibling を利用 ・display: none, block でパラパラ描画
function wlby_calc_timeout(c) {
var timeout = (new Date).getTime();
while (c) {
timeout += parseFloat(getComputedStyle(c)['-webkit-animation-duration']) * 1000;
c.timeout = Math.round(timeout);
c = c.nextElementSibling;
}
}
var wlby_hide_children = function(self) {
var c = self.firstElementChild;
while (c) {
c.style.display = 'none';
c = c.nextElementSibling;
}
}
var wlby_activate_sibling = function(evt, self) {
if (evt.srcElement != self)
return;
if (self.style.display == 'none')
return;
if (!self.timeout)
wlby_calc_timeout(self);
self.style.display = 'none';
var sibling = self.nextElementSibling;
if (!sibling)
return;
while ((sibling.timeout < evt.timeStamp)&&sibling.nextElementSibling)
sibling = sibling.nextElementSibling;
// $('.wlby_fs', sibling).css('display', 'none');
// var n = new Number((sibling.timeout - (new Date).getTime()) / 1000);
// sibling.style.webkitAnimationDuration = n.toString() + 's';
sibling.style.display = 'block';
};
var wlby_activate_children = function(evt, self) {
if (evt.srcElement != self)
return;
wlby_hide_children(self);
var c = self.firstElementChild;
if(!c)
return;
// $('.wlby_fs', c).css('display', 'none');
wlby_calc_timeout(c);
c.style.display = 'block';
c.style.webkitAnimationDelay = '';
}
var wlby_loop_children = function(evt, self) {
if (evt.srcElement != self)
return;
wlby_activate_children(evt, self);
var c = self.firstElementChild;
if (!c)
return;
c.style.webkitAnimationDelay = '0s';
}
$(document).ready(function() {
$('.wlby_sprite').each(function()
{ this.addEventListener('webkitAnimationIteration', function(evt) { wlby_loop_children(evt, this); return false; }, false, false) });
$('.wlby_sprite, .wlby_graphic').each(function()
{ this.addEventListener('webkitAnimationStart', function(evt) { wlby_activate_children(evt, this); return false; }, false, false) });
$('.wlby_fs').each(function()
{ this.addEventListener('webkitAnimationEnd', function(evt) { wlby_activate_sibling(evt, this); return false; }, false, false) });
});
■CSSの一部抜粋 ・@-webkit-keyframe の opacity でフェイドイン・フェイドアウトを実現している [css] @-webkit-keyframes wlby_frameset-animation { from { } to { } }
.wlby_fs, .wlby_graphic { -webkit-animation-name: wlby_frameset-animation; }
.wlby_graphic { -webkit-animation-duration: 1s; }
.wlby_masked { height: inherit; position: inherit; width: inherit; }
.wlby_sprite { -webkit-animation-name: wlby_frameset-animation; -webkit-animation-iteration-count: infinite; }
@-webkit-keyframes wlby_KF_3 { from, 4.49% { -webkit-transform: matrix(1, 0, 0, 1, -0.452, -5.589) skew(-69.891deg,27.062deg) scale(1.0112, 0.2792); opacity: 0.200259; } 5.61%, 8.98% { -webkit-transform: matrix(1, 0, 0, 1, -0.452, -5.589) skew(-69.891deg,27.062deg) scale(1.0112, 0.2792); opacity: 0.168419; } 10.11%, 14.6% { -webkit-transform: matrix(1, 0, 0, 1, -0.452, -5.589) skew(-69.891deg,27.062deg) scale(1.0112, 0.2792); opacity: 0.200259; }
....
.wlby_4 { -webkit-animation-duration: 2.90323s; -webkit-transform: matrix(1, 0, 0, 1, -25.05, -29); -webkit-transform-origin: 20px 106.95px; }
.wlby_47 { -webkit-animation-duration: 0.0322581s; display: none; position: absolute; -webkit-transform: matrix(1, 0, 0, 1, -13.95, -28.55); }
.wlby_48 { -webkit-animation-duration: 0.0322581s; display: none; position: absolute; -webkit-transform: matrix(1, 0, 0, 1, -13.65, -28.25); } [/css]
Eclipse で vi 使う時は今まで viplugin を使ってたけど、vrapper ってのもあるらしい。
「Install New Software...」で、以下のアドレスでインストールします。
http://vrapper.sourceforge.net/update-site/stable
Eclipse 再起動後、ツールバーに vimアイコンが現れます。
vimrcまわりの設定が別々に指定できるのがメリットらしい。 Eclipseのキーバインドをvim風にできるVrapperが "マジで" 素晴らしすぎる件について
補完は Vrapper の方がいいらしいが、どうなんだろう?
ビジュアルモードでGUIでコピペもできる(Macだけ?)から、すげぇ快適。
さぁ、ちょっと勉強しなきゃいけない分野に・・・。
Android の Sqlite は、ざっと見た感じ、iOSの CoreData に比べると管理が難しそう?と言う印象。 まず Android で Sqliteを扱うには、2通りの方法がある。
(1) Android SDK 提供のクラスを利用 (2) adb shell から Sqliteデータベースツールを利用
SqliteのDB作成やスキーマバージョン管理は、SQLiteOpenHelper インターフェイスを利用する。
Sqlite のクエリーは SQLiteDatabase クラスを利用する。
データベースのスキーマをモデル化する。
設定を保存するには、 SharedPreferences を利用するとお手軽。
デフォルト設定としてデータを保存してみる。 Staticメソッド getDefaultSharedPreferences(Context context) でSharedPreferencesインスタンスを取得。 設定を保存するには、Editor クラスを edit() で生成する。
[java] public class UserLoginActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user_login); }
public void login(View v) {
TextView userIdTextView = (TextView) findViewById(R.id.userIdTextView);
TextView passwordTextView = (TextView) findViewById(R.id.passwordTextView);
String userId = userIdTextView.getText().toString();
String password = passwordTextView.getText().toString();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
Editor editor = sharedPreferences.edit();
editor.putString("userId", userId);
editor.putString("password", password);
editor.commit();
//ログイン処理...
}
} [/java]
[java] public void loadPreferences() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); String userId = sharedPreferences.getString("userId", null); String password = sharedPreferences.getString("password", null); } [/java]
デフォルト設定ではなく、ファイル名を指定して保存する場合は、 SharedPreferences getSharedPreferences(String name, int mode) を利用するようです。
次々に新しい環境がでてきて、もう何がなんだか。。。
Titaniumも良いと思ったが、もしかしたら「jQuery Mobile」がスタンダードになるかも知れない。
「jQuery Mobile」の登場で、モバイルアプリケーション開発は大きく変わる
クックパッドのスマフォ開発は「jQuery Mobile」も使ったらしい。 クックパッドでのスマートフォン開発
いやぁ、選択に迷います。
Androidでタブ画面を切り替えるには、TabActivityを利用します。
・Android Tab Layout ・タブメニューを利用する
TabActivity を利用数にはレイアウトを以下のように作成する (1) TabHost(id=tabhost) を追加する (2) TabWidget(id=tabs) と FrameLayout(id= tabcontent) を TabHost に追加する (3) TabHost addTab() で順番にコンテンツを追加
[java] public class Sample extends TabActivity implements TabHost.TabContentFactory {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TabHost tabhost = getTabHost();
tabhost.addTab(tabhost.newTabSpec("tab1")
.setIndicator("追加", getResources().getDrawable(android.R.drawable.ic_menu_add))
.setContent(new Intent(Sample.this, RaceResultList.class)
.setFlags(Intent. FLAG_ACTIVITY_SINGLE_TOP)));
tabhost.addTab(tabhost.newTabSpec("tab2")
.setIndicator("削除", getResources().getDrawable(android.R.drawable.ic_menu_delete))
.setContent(new Intent(Sample.this, RaceForecastList.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
[/java]
(1) TabActivity を継承する (2) getTabHost() で TabHost を取得する (3) タブに追加する画面(Intent)を作成する (4) TabHost addTab() で順番に画面を追加する
「タブ切り替え」というより、Intent の Flags の仕様ですが、 setFlagsで、FLAG_ACTIVITY_CLEAR_TOP を指定するとタブを切り替える度に、onCreate が呼ばれる。 FLAG_ACTIVITY_SINGLE_TOP は一度作成したアクティビティが保持されます。
Androidのコンポーネントでアイコン作成をする場合、 てっとりばやくAndroid Asset Studio を使うのもありかも。
iPhoneに比べると見栄えがイマイチAndroidですから、デザインの苦手な開発者(自分含む)も スタイルやアイコン変える努力をしないとですね。
というか、iPhoneでも使えそうじゃないか?
日付選択のウィンドウはAlertDialogを継承しています。 DatePickerDialog
よって、Intentのような画面遷移なしで表示が可能です。 コンストラクタは2種類。
DatePickerDialog(Context context, DatePickerDialog.OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)
引数int themeに関してはスタイルに関わる事なので勉強する必要がありますが、 ここでレイアウトをカスタマイズする事は頭に入れておく必要がありますね。
[java] DatePickerDialog.OnDateSetListener DateSetListener = new DatePickerDialog.OnDateSetListener(){ public void onDateSet(android.widget.DatePicker datePicker, int year, int monthOfYear, int dayOfMonth) { datetime = String.valueOf(year) + String.format("%02d", monthOfYear + 1) + String.format("%02d", dayOfMonth); Log.d("DatePicker", datetime); } };
Striing datetime = "20110301";
int year = Integer.parseInt(datetime.substring(0, 4));
int monthOfYear = Integer.parseInt(datetime.substring(4, 6)) - 1;
int dayOfMonth = Integer.parseInt(datetime.substring(6, 8));
final DatePickerDialog dialog = new DatePickerDialog(this, R.style.Theme_Dialog, DateSetListener, year, monthOfYear, dayOfMonth);
dialog.show();
[/java]
日付が設定された場合は、onDateSet リスナーが呼ばれます。
Eclipse 3.6では標準でプラグインがサポートされている模様。
Install New Softwareでインストールするが、パッケージURLは以下の通り。
http://download.eclipse.org/releases/helios
iPhone版 MikuMikuDanceの開発者が、MMDを扱うサンプルをBSDライセンスデ公開してくれました。
そろそろ、ちゃんと3Dの勉強もしないといかんなぁ?と情熱を掻き立てられます。
MikuMikuDance(ミクミクダンス)の略称のようです。 MikuMikuDance
クリプトンの初音ミクからこんなに派生しているとは・・・。 ニコニコとかでこんな盛り上がってるのか!って驚きです。
pmd、vmd形式のデータは各ユーザさんが公開しています。 ・VPVP wiki ・MMDモデル・アクセサリ情報
僕の環境では、MikuMikuDanceプロジェクトはそのままビルドできました。 で、モデルファイルを落として、iTunes経由で実機に突っ込みます。
実機で起動。 mmdとか仕様がよくわかってないので、モデル全部は表示できませんでした。 vmdでモーションは動きました。
CPUに負荷がかかるせいか?ちょっとモデルローディングに時間がかかります。 プログラムコードを参考に見てみようと思います!