Pages

    2010年9月24日金曜日

    iPadでお絵かき

    JSPaintがiPad対応してないので、
    どこまで出来るかちょっと調べてみました。

    ググると結構やられてるのでネタとしてはいまいちですが
    とりあえずコードをはっときます。

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="user-scalable=no, width=device-width">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <title>タッチテスト</title>

    <style>
    body{ margin:0;padding:0;}
    #canvas{ border:1px solid #009; margin:30px 30px 0;}
    #log{ width:650px; height:220px; overflow:scroll;}
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    </head>

    <body>
    <canvas width="450" height="250" id="canvas"></canvas>
    <div id="log"></div>
    <script>
    //参考:ASCII.jp:HTML5のCanvasで作る、Flash不要のお絵かきツール |古籏一浩のJavaScriptラボ http://ascii.jp/elem/000/000/513/513377/
    var off;
    var gapX;
    var gapY;
    var padd=30;
    var canvX;
    var canvY;
    var canvW;
    var canvH;
    var drawFlag = false;
    var oldX = 0;
    var oldY = 0;
    var $canvas;

    $(document).ready(function () {
            document.body.ontouchmove = function (e) { e.preventDefault(); };
            $canvas=$("#canvas");
            off=$canvas.offset();
            gapX=off.left;
            gapY=off.top;
            canvH=$canvas.attr('clientHeight');
            canvW=$canvas.attr('clientWidth');
            $canvas.bind("touchstart", touchStartHandler, false);
            $canvas.bind("touchmove", touchMoveHandler, false);
            $canvas.bind("touchend", touchEndHandler, false);
        });
        //タッチ開始
        function touchStartHandler(e){
            $("#log").text("touchstart");
             drawFlag = true;
                 // タッチ位置を取得
                    var fn=function(i){
                        oldX=e.originalEvent.touches[i].pageX-gapX;
                        oldY=e.originalEvent.touches[i].pageY-gapY;
                    }
        loop(e,fn);
            }
            //タッチして移動
        function touchMoveHandler(e){
            $("#log").text("touchmove");
        var fn=function(i){
                        canvX=e.originalEvent.touches[i].pageX-gapX;
                        canvY=e.originalEvent.touches[i].pageY-gapY;
                        //判定エリア内なら
                        if(canvX<=canvW+padd && canvY<=canvH+padd && canvX>=0-padd && canvY>=0-padd){

                        $("#log").text("X:"+ canvX+"Y:"+canvY);
                        //draw
                         if (!drawFlag) return;
                            var canv=document.getElementById("canvas");
                            var context =canv.getContext("2d");
                            context.strokeStyle = "rgba(220,220,220,0.7)";
                            context.lineWidth = 3;
                            context.beginPath();
                            context.moveTo(oldX, oldY);
                            context.lineTo(canvX, canvY);
                            context.stroke();
                            context.closePath();
                            oldX = canvX;
                            oldY = canvY;
                        }
        }
        loop(e,fn);
            }
            //タッチ終了
        function touchEndHandler(e){
            $("#log").text("touchend");
             drawFlag = false;
            }
        /*function touchCancelHandler(e){
            $("#log").text("touchcancel");
            }*/
            //ループ
        function loop(e,fn){
            for (var i = 5; i--;) {
                    if (e.originalEvent.touches[i]) {
                        fn(i)
                    }
                }
            }

    </script>
    </body>
    </html>

    参考:


    2010年8月24日火曜日

    ViewFlipperでテキストアニメーション


    API DEMOSのViews/Animation/Pushにテキストがニュースヘッダーのようにアニメするサンプルがあります。それをいじってボタンを押したら(もしくは何らかのイベントで)アニメが動くようにしてみました。アニメの部分をクラスにしてまとめたので、いじりやすくなったんじゃないかと思ってます。(あくまで自己満足)

    ソースはアニメのクラスとそれを呼び出す部分の2つです。(レイアウト、アニメなどXMLは除く)

    注)以下のコードはLogCatにずっと実行されてるみたいな挙動だったので使わないでね。直したものを最後に張っておきます。

    以下だめだめ
    呼び出し側
    package com.yoropan.TextAnimation;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.ViewFlipper;
    
    public class TextAnimation extends Activity {
    
     private ViewFlipper mFlipper;
    
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      final TextView stats = (TextView) findViewById(R.id.stats);
      final TextView stats2 = (TextView) findViewById(R.id.stats2);
      stats.setText("aaaaaaa");
      stats2.setText("bbbbbbbbbb");
    
      Button btn = (Button) findViewById(R.id.change);
      Button btn2 = (Button) findViewById(R.id.change2);
      
      mFlipper = (ViewFlipper) findViewById(R.id.flipper);
      
      btn.setOnClickListener(new View.OnClickListener() {
    
        DoFlipper d=new DoFlipper(TextAnimation.this);
       public void onClick(View v) {
       d.pushup(mFlipper);//上に動け
       }
    
      });
      btn2.setOnClickListener(new View.OnClickListener() {
       public void onClick(View v) {
         DoFlipper d=new DoFlipper(TextAnimation.this);
        d.pushdown(mFlipper);//下に動け
        
       }
      });
     }
     
     
     
    }
    

    アニメの方のクラス
    package com.yoropan.TextAnimation;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    
    import android.app.Activity;
    import android.view.animation.AnimationUtils;
    import android.widget.ViewFlipper;
    
    public class DoFlipper {
     
     Timer timer = null;
     // ハンドラ
     android.os.Handler handler = new android.os.Handler();
     
     private Activity activity;
     public DoFlipper(Activity activity) {
      this.activity=activity;
      }
     void pushup(ViewFlipper mFlipper) {
      mFlipper.startFlipping();
      mFlipper.setInAnimation(AnimationUtils.loadAnimation(activity, R.anim.push_up_in));
      mFlipper.setOutAnimation(AnimationUtils.loadAnimation(activity, R.anim.push_up_out));
      mFlipper.showNext();
      timestop(mFlipper);//stop
      // mFlipper.setAnimation(AnimationUtils.loadAnimation(TextAnimation.this, R.anim.push_up));
      
     }
      void pushdown(ViewFlipper mFlipper) {
      mFlipper.startFlipping();
      mFlipper.setInAnimation(AnimationUtils.loadAnimation(activity, R.anim.push_down_in));
      mFlipper.setOutAnimation(AnimationUtils.loadAnimation(activity, R.anim.push_down_out));
      mFlipper.showNext();
      timestop(mFlipper);//stop
     }
     private void timestop(final ViewFlipper mFlipper) {
      // タイマの設定
      timer = new Timer(true);
      timer.schedule( new TimerTask() {
    
       public void run() {
    
        // 表示の更新
        handler.post( new Runnable() {
         public void run() {
          mFlipper.stopFlipping();
          //pushdown();
         }
        });
    
       }
    
      }, 1000, 1000 );
     }
    }
    
    

    以下LogCatで確認したOKなやつ
    呼び出し側
    package com.yoropan.TextAnimation;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.ViewFlipper;
    
    public class TextAnimation extends Activity {
    
     public static ViewFlipper mFlipper;
    
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      final TextView stats = (TextView) findViewById(R.id.stats);
      final TextView stats2 = (TextView) findViewById(R.id.stats2);
      stats.setText("aaaaaaa");
      stats2.setText("bbbbbbbbbb");
    
      Button btn = (Button) findViewById(R.id.change);
      Button btn2 = (Button) findViewById(R.id.change2);
      
      mFlipper = (ViewFlipper) findViewById(R.id.flipper);
      
      btn.setOnClickListener(new View.OnClickListener() {
    
        DoFlipper d=new DoFlipper(TextAnimation.this);
       public void onClick(View v) {
       d.pushup();//上に動け
       }
    
      });
      btn2.setOnClickListener(new View.OnClickListener() {
       public void onClick(View v) {
         DoFlipper d=new DoFlipper(TextAnimation.this);
        d.pushdown();//下に動け
        
       }
      });
     }
     
     
     
    }
    

    アニメの方のクラス
    package com.yoropan.TextAnimation;
    
    import android.app.Activity;
    import android.view.animation.AnimationUtils;
    import android.widget.ViewFlipper;
    
    public class DoFlipper {
     ViewFlipper mFlipper=TextAnimation.mFlipper;
     
     private Activity activity;
     public DoFlipper(Activity activity) {
      this.activity=activity;
      }
     void pushup() {
      mFlipper.startFlipping();
      mFlipper.setInAnimation(AnimationUtils.loadAnimation(activity, R.anim.push_up_in));
      mFlipper.setOutAnimation(AnimationUtils.loadAnimation(activity, R.anim.push_up_out));
      mFlipper.showNext();
      mFlipper.stopFlipping();
      
     }
      void pushdown() {
      mFlipper.startFlipping();
      mFlipper.setInAnimation(AnimationUtils.loadAnimation(activity, R.anim.push_down_in));
      mFlipper.setOutAnimation(AnimationUtils.loadAnimation(activity, R.anim.push_down_out));
      mFlipper.showNext();
      mFlipper.stopFlipping();
     }
    
    }
    

    タイマーをかませると見た目はとまってるんだけどログには出続けるのでなんか気持ち悪かった(たぶん電池とか消費するんだろうな)ので直しました。

    2010年6月9日水曜日

    Android Bazaar and Conference 2010 Spring

    行きます。



    イベント/Android Bazaar and Conference 2010 Spring - 日本Androidの会(日本アンドロイドの会)


    日時
    2010年6月26日(土)

    10:00~18:00 (受付開始 9:30)

    会場
    東京大学駒場キャンパス13号館1階(総合受付)

    〒153-8902 東京都目黒区駒場3-8-1(京王井の頭線 駒場東大前駅)

    http://www.u-tokyo.ac.jp/campusmap/cam02_01_12_j.html

    2010年3月10日水曜日

    ROKONのパーティクルサンプル

    Example16にBasic Particle Systemというデモがあったので中身を見てみた。

    以下ソースの抜粋
        public Emitter carEmitter;
        public void onCreate() {
            createEngine(480, 320, true);
        }

        @Override
        public void onLoad() {
            atlas = new TextureAtlas(512, 512);
            atlas.insert(backgroundTexture = new Texture("graphics/backgrounds/beach.png"));
            atlas.insert(carTexture = new Texture("graphics/sprites/car.png"));
            TextureManager.load(atlas);
            background = new FixedBackground(backgroundTexture);
            carEmitter = new Emitter(-10, 10, -10, 10, 4, 8, carTexture);
    //秒間最大8生成している(第6引数)
            carEmitter.addParticleModifier(new ParticleDimensions(50, 90, 50, 90));
            carEmitter.addParticleModifier(new ExpireParticle(2700, 3500));
            carEmitter.addParticleModifier(new AccelerateParticle(100, 200, 50, 100));
        }

        @Override
        public void onLoadComplete() {
            rokon.setBackground(background);
            rokon.addEmitter(carEmitter);
            carEmitter.startSpawning();
        }

    Spawningってなんやろーと翻訳すると「産卵」ですって。なるほど。
    N1で動かしてみたけどキャプチャが変になりました。動作自体はいけてる感じです。HT-03Aだと…がんばってますって感じですね。

    2010年3月8日月曜日

    aLDClipの明示的インテント

    以下のようにして使えます。

    package com.yoropan.IntenTest;

    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;

    public class IntenTest extends Activity {
        Button send;
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
         send=(Button)findViewById(R.id.send);
         send.setOnClickListener(clk);
        }
       private View.OnClickListener clk=new View.OnClickListener(){
               //明示的intent
               Intent intent=new Intent(Intent.ACTION_SEND);
               intent.setClassName("com.yoropan.aLDClip","com.yoropan.aLDClip.LDClip");
               intent.putExtra(Intent.EXTRA_SUBJECT,"タイトルだよー");
               intent.putExtra(Intent.EXTRA_TEXT,"http://www.google.com");
               intent.setType("text/plain");
               startActivity(intent);
           }
        };
    }

    結果)

    以上です。よろしくお願いします。

    2010年2月23日火曜日

    androidのレイアウト

    苦戦中。

    LinearLayoutだろうがRelativeLayoutだろうが画面外に出てしまう。
    動的に要素を増やしたときはどうすればいいのだろう。tableレイアウトになるのかなー?。HTMLのインライン要素みたいにはじっこでいい感じに折り返してくれないのかしら。。。

    あとflashだと変数に連番とか振るのだけど、以下のようにしたらウィジェットを動的に複数個作成できた[謎]。普通なんだろうかこれ?

    String[] arr={"aaa","bbb","ccc","ddd","eee"};
            for (int i = 0; i < arr.length; i++) {
                CheckBox checkBox = new CheckBox(this);
                checkBox.setText(arr[i]);
                layout.addView(checkBox);
            }

    2010年2月17日水曜日

    RatingBarのバグ

    SDKのバージョン3でRatingBar(☆☆☆☆☆)を使うとNexusOneやDroidで表示が欠けてしまう

    簡単な解決方法はSDKのバージョンを4(OSでは1.6)にすることみたい。

    RatingBar size issues on high-density screens (Droid, Nexus One) - Android Developers | Google グループ http://groups.google.co.jp/group/android-developers/browse_thread/thread/e91df884f7c056ea?pli=1