2011/03/08

AdobeがFlashをHTML5に書き出すツール Wallaby を公開したようです。

Flash® Professional って記載されてるけど、Flex じゃダメなのかな? 今度の例会で質問してみよう。

アプリのUI

UIは凄い質素です。 wallaby

設定もログモードとブラウザ起動設定くらい。 wallaby

コンバート

手っ取り早く、Flash CS5のサンプルでConvertしてみる。 サポートされてないモジュールがあるとWarningがでる。 wallaby

Filter、Advanced Color等、機能によってはコンバートできない。 wallaby

HTMLファイル構成

wallaby ・jquery: 1.4.2  でもアニメーション処理は、してない模様。

・css: CSS3で webkitのみ対応 CSSアニメーションを使ってるので、重たいと思われる。

・svg: 画像はSVGフォーマットを利用

動きによって CSS3、JavaScriptを使い分けている模様。

実行結果

Flash

HTML5

アニメーションの基本仕様は、Safari Reference Library -Animations を参照

JavaScript側で webkitAnimationIteration、webkitAnimationStart、webkitAnimationEnd でイベントリスナーを登録し、CSS側で @-webkit-keyframes from ... to を作成。

■JavaScript

candle.js

・「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]

  2011/03/08

Eclipse で vi 使う時は今まで viplugin を使ってたけど、vrapper ってのもあるらしい。

インストール

「Install New Software...」で、以下のアドレスでインストールします。

http://vrapper.sourceforge.net/update-site/stable

Eclipse 再起動後、ツールバーに vimアイコンが現れます。 eclipse vim

参考サイト

vimrcまわりの設定が別々に指定できるのがメリットらしい。 Eclipseのキーバインドをvim風にできるVrapperが "マジで" 素晴らしすぎる件について

補完は Vrapper の方がいいらしいが、どうなんだろう?

ビジュアルモードでGUIでコピペもできる(Macだけ?)から、すげぇ快適。

  2011/03/07

さぁ、ちょっと勉強しなきゃいけない分野に・・・。

Android の Sqlite は、ざっと見た感じ、iOSの CoreData に比べると管理が難しそう?と言う印象。 まず Android で Sqliteを扱うには、2通りの方法がある。

(1) Android SDK 提供のクラスを利用 (2) adb shell から Sqliteデータベースツールを利用

SQLiteOpenHelper インターフェイス

SqliteのDB作成やスキーマバージョン管理は、SQLiteOpenHelper インターフェイスを利用する。

SQLiteDatabase クラス

Sqlite のクエリーは SQLiteDatabase クラスを利用する。

DAO クラスの定義

データベースのスキーマをモデル化する。

  2011/03/07

設定を保存するには、 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) を利用するようです。

  2011/03/05

次々に新しい環境がでてきて、もう何がなんだか。。。

Titaniumも良いと思ったが、もしかしたら「jQuery Mobile」がスタンダードになるかも知れない。

「jQuery Mobile」の登場で、モバイルアプリケーション開発は大きく変わる

クックパッドのスマフォ開発は「jQuery Mobile」も使ったらしい。 クックパッドでのスマートフォン開発

いやぁ、選択に迷います。

  2011/03/04

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 の状態

「タブ切り替え」というより、Intent の Flags の仕様ですが、 setFlagsで、FLAG_ACTIVITY_CLEAR_TOP を指定するとタブを切り替える度に、onCreate が呼ばれる。 FLAG_ACTIVITY_SINGLE_TOP は一度作成したアクティビティが保持されます。

詳しくは、 Intent のCategoryとExtraとFlagの一覧表を作ってみたよ

  2011/03/04

Androidのコンポーネントでアイコン作成をする場合、 てっとりばやくAndroid Asset Studio を使うのもありかも。

iPhoneに比べると見栄えがイマイチAndroidですから、デザインの苦手な開発者(自分含む)も スタイルやアイコン変える努力をしないとですね。

というか、iPhoneでも使えそうじゃないか?

  2011/03/02

日付選択のウィンドウは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 リスナーが呼ばれます。

  2011/02/25

Eclipse 3.6では標準でプラグインがサポートされている模様。

Install New Softwareでインストールするが、パッケージURLは以下の通り。

subversion

  2011/02/25

iPhone版 MikuMikuDanceの開発者が、MMDを扱うサンプルをBSDライセンスデ公開してくれました。

MikuMikuDanceのiPhone版サンプル公開

そろそろ、ちゃんと3Dの勉強もしないといかんなぁ?と情熱を掻き立てられます。

MMDって?

MikuMikuDance(ミクミクダンス)の略称のようです。 MikuMikuDance

クリプトンの初音ミクからこんなに派生しているとは・・・。 ニコニコとかでこんな盛り上がってるのか!って驚きです。

pmd、vmd形式のデータは各ユーザさんが公開しています。 ・VPVP wikiMMDモデル・アクセサリ情報

iPhoneでビルドしてみる

僕の環境では、MikuMikuDanceプロジェクトはそのままビルドできました。 で、モデルファイルを落として、iTunes経由で実機に突っ込みます。 mmd

実機で起動。 mmd mmdとか仕様がよくわかってないので、モデル全部は表示できませんでした。 vmdでモーションは動きました。

CPUに負荷がかかるせいか?ちょっとモデルローディングに時間がかかります。 プログラムコードを参考に見てみようと思います!

pngファイルの軽量化
Google DriveのIconを再起的に削除
php-markdownでバニラPHPなコードブロック処理
laravel-ffmpeg を使う
2021年版 Ubuntu + certbot + Let's Encrypt でサーバ証明書設定
GihHub のデフォルトでない master ブランチを checkout する
マルチログインで未認証のリダイレクト
Homebrew で Redis をインストール
CSS だけでスムーズスクロール
EC-CUBE4 で Gmail の smtp を利用する
Amazon Linux 2 の amazon-linux-extras とは
UNIQUE カラムのバリデーションで自分自身を除外して更新
フォーム有効期限切れで Page Expired をリダイレクト
ログを日付でローテーションやクリアや削除
Homebrew で PHP8.0 から PHP7.4 にダウングレード
Big sur で zsh 移行と Homebrew アップグレード
Mac に minikube をインストール
途中から .gitignore に追加する
Larevel 6.x から Laravel 8.x にバージョンアップ
Composer で Allowed memory size (メモリ不足)エラー
Blade でカスタムクラスを利用する
git push git pull にブランチ指定せずに実行する
git pull や git push できなくなったとき
Docker のコンテナからホストOS に接続
Mac で ローカル IP アドレス(ipv4)のみを表示する
ホストOS から Docker の MySQLコンテナに接続
caching_sha2_password のエラー
node-config で環境設定ファイルを利用する
rootパスワードを初期化(再設定)する
Git から clone したときのエラー対処
Mac に MySQL をインストール
Mac に PostgreSQL をインストール
Laravel 環境構築 - Mac ネイティブ編
Firebase 入門 - Firebase とは
Firebase 入門 - CLI インストールとデータベースの設定
AWS 無料枠(t2.micro)で容量とメモリエラー
Cloud9 を起動する -初心者編-
gcloud で GCEインスタンスを起動してみる
AWS CLI と jq でインスタンス一覧を整形して表示
React と Laravel7 のプロジェクトを作成する
Homebrewインストール-2020年版
3直線で囲まれた範囲塗りつぶし
PuLP で線形最適化問題を解く
カスタムのペジネーションを作る
node-sass を使って sass をコンパイルする
Log ファサードでSQLログを分離して書き出す
いちから始める Docker - 複数のコンテナを使う - (2020年)
いちから始める Docker - docker-compose を使う - (2020年)
AWS ECR を使ってみる
Laravel7 でマルチ認証