2011年2月28日月曜日

グラフィックライブラリを作る的なはなし。

点の集合が線で、線の集合が面なんていうのはさておき、
グラフィック系だと最初に、【線を引く】なんていうことをやる場合が多いのですが、
実は、線を引くのは結構曲者なのですよ。図形を描く方が理解しやすい場合も多いのです。

本来なら、、(0,0)から(100,100)まで線を引くみたいなところから始めるのですが、
何が難しいかっていうと、、、、図形は面積があるので、そのまま描けばいいのですが、線は面積がない。
面積がないけど、ピクセルで描くから面積ができる。そこが難しいんです。

例でいうと、こんな感じ。
左は、(0,0)-(5,1)-(2,4)の3角形。
右は、(0,0)-(5,0)の直線。

三角形の方は、(0,0)という点に面積はなく、数学てやったグラフのような感じですが、
直線の方は、ピクセルに対して、0,1,2,3,,,という座標を与えているので、
点自体が1ピクセル面積をもってしまうのです。

よって、右の直線は、(0,0)-(6,0)-(6,1)-(0,1)の四角形と考えるならわかりやすいのですが、
(0,0)-(5,0)の直線と考えるのは、かなり無理があるのです。
しかし、とにかく線を気軽に引きたい場合などは、この方法もたしかに【あり】ですが、
DTP系のグラフィックスとしては【なし】ですかねー。

しかし、大方のグラフィックでは、線を引く命令は右図のような指定、
多角形を描く命令は左図のような指定をするんですよね。

もちろん、実際には、1ピクセル以下の描画はできませんから、アンチエイリアスをかけて
みたいな感じになりますけどねー。

2011年2月11日金曜日

FLEXでFLASH(AS)っぽく画像を表示

FLEXで画像を読み込んで表示。一番単純にして重要な機能であるが、
FLEXのサンプルとかHowTo本を見ると、
【まずImageコンポーネントを~~】
なんていう、私の趣味とかけ離れた手法がかかれている。
まぁそれはそれとして、どうActionScriptに展開されるかを確認するのも重要だが、
ここでは、FLASH-CS3っぽく表示させてみる。
すると、こんな感じ
var loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e){
 var bmp = new Bitmap;
 bmp.bitmapData = loader.content.bitmapData.clone();
 stage.addChild( bmp );
});  
var urlfile = "http://localhost/ren2.jpg";
var UR=new URLRequest(urlfile);
UR.method = URLRequestMethod.POST;
loader.load(UR);
まぁ、いままでとなんら変わることもなく実行できましたね。
もちろん、これはこれとして、実際はクラスでキッチリ書きますYO。
まぁ実際はコンテナっぽいものを作って、そこに描画させることになるのかな。
だから、FLASH-AS3だと、Spriteかなんかで

var sp = new Sprite;
sp.addChild(bmp);
stage.addChild( sp );
的な。

でも、こんなことするなら、わざわざFLEXじゃなくて、FLASHですればいいじゃんって
ことなんですけど、、、まぁ、気分で使い分けてるだけっす。
mxなら、
var temp : mx.controls.Image = new mx.controls.Image;
temp.x = 30;
temp.y = 85;
temp.width = 205;
temp.height = 216;
temp.source = "http://localhost/ren2.jpg";
addElement(temp);
ですかねー。

2011年2月9日水曜日

マウスイベントを最下層でひろうために。

CS3の時代にFlashで作ったAS3を見返して、FLEX4で実行させてみます。
クラスとしては後述の【keyAndMouse】クラスとしました。
keyAndMouseと言いながらも、keyは、ctrlとshiftをチェックするだけです。
要するにFLASHの、階層全てにイベントが発生するという特徴をいかして、
たとえボタンをクリックしてもkeydownがとれるように使います。
何につかうかといえば、何らかのGUIとしか言いようがないですけど、
今作ってるものには必要なんで^^;^^;
ということで、使い方は、mxmlのなかで、
~~略~~
public function MD(e){
 LL.text = "--M1---" + kam.getCS();
}
public function MU(e){
 LL.text = "--M2---" + kam.getCS();
}
public function MM(e){
 LL.text = "--M3---" + (ct++) + "/ " + kam.getCS();
}
public function MO(e){
 LL.text = "--M4---" + kam.getCS();
}
~~略~~
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
 kam = new keyAndMouse(this); 
 kam.setMD(MD);
 kam.setMU(MU);
 kam.setMM(MM);
 kam.setMO(MO);
~~略~~
って感じです。
要するに、、最下層のマウスイベントを、自分のクラス内にもってきたい時につかうのです。
まぁサンプルはどっちにしても同じ階層ですけど、このkamなるインスタンスを、引数として
別のクラスとかにもってって、そこで使うことをイメージしてます。
CS3のFLASHで作ってたときは、コンストラクタの引数はthisではなくstageでしたが、
引数をthis.stageにすると、
メインスレッド (中断 : TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。)
といって怒られるので、thisに変更したのですが、実は、単に書く場所がマズかっただけで、
applicationCompleteHandlerで設定してやればOKでした。怠慢でした^^;^^;

ってことで、クラスは以下。たいしたことないっすけどね。
あぁ、あんまり型を書かない人なんで、すんません。。
package{
 //----------------------------------
 import flash.display.MovieClip;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.KeyboardEvent;
 import flash.events.MouseEvent;
 import flash.ui.*;
 //----------------------------------
 public class keyAndMouse extends Sprite{
  var father  = null;
  var bControl = false;
  var bShift  = false;
  var funcMD  = null; // mouseDown event handler
  var funcMU  = null; // mouseUp   event handler
  var funcMM  = null; // mouseMove event handler
  var funcMO  = null; // mouseOver event handler
  var bKeep  = false;
  //--------------------
  var bMouseDown = false;
  //--------------------
  public function setMD(f){ funcMD = f;  }
  public function setMU(f){ funcMU = f;  }
  public function setMM(f){ funcMM = f;  }
  public function setMO(f){ funcMO = f;  }
  //--------------------
  public function getCS(){
   if(bControl && bShift) return 3;
   else if(bShift)   return 2;
   else if(bControl)  return 1;
   return 0;
  }
  //--------------------
  public function md(e){ if(funcMD) funcMD(e); }
  public function mu(e){ if(funcMU) funcMU(e); }
  public function mm(e){ if(funcMM) funcMM(e); }
  public function mo(e){ if(funcMO) funcMO(e); }
  //--------------------
  function keyAndMouse(f,bb:Boolean=true){
   bKeep = bb;
   father = f;
   this.addEventListener(Event.REMOVED_FROM_STAGE, removed);
   //-------------------
   // keyDown
   //-------------------
   father.addEventListener(KeyboardEvent.KEY_DOWN,
    function (e){
     if(e.keyCode == Keyboard.CONTROL) bControl = true;
     if(e.keyCode == Keyboard.SHIFT)  bShift = true;
    }
   );
   //-------------------
   // keyUp
   //-------------------
   father.addEventListener(KeyboardEvent.KEY_UP,
    function (e){
     if(e.keyCode == Keyboard.CONTROL) bControl = false;
     if(e.keyCode == Keyboard.SHIFT)  bShift  = false;
    }
   );
   //-------------------
   // mouseDown
   //-------------------
   father.addEventListener(MouseEvent.MOUSE_DOWN,
    function (e){
     if(bMouseDown){
      if(funcMU) funcMU(e);
      bMouseDown=false;  // 微妙な仕様
      return;     // 
     }
     bMouseDown = true;
     if(funcMD) funcMD(e);
    }
   );
   //-------------------
   // mouseUp
   //-------------------
   father.addEventListener(MouseEvent.MOUSE_UP,
    function (e){
     bMouseDown = false;
     if(funcMU){
      funcMU(e);
      if(!bKeep){
       funcMD = null;
       funcMU = null;
       funcMM = null;
      }
     }
    }
   );
   //-------------------
   // mouseMove
   //-------------------
   father.addEventListener(MouseEvent.MOUSE_MOVE,
    function (e){
     if(funcMM) funcMM(e);
    }
   );
   //-------------------
   // mouseOver
   //-------------------
   father.addEventListener(MouseEvent.MOUSE_OVER,
    function (e){
     if(funcMO) funcMO(e);
    }
   );
   //-------------------
  }
  //--------------------
  // like a destructer
  //--------------------
  private function removed(e:Event):void{
   removeEventListener(Event.REMOVED_FROM_STAGE, removed);
  }
  //--------------------
 }
 //----------------------------------
}

2011年2月5日土曜日

グラフィックライブラリを作るのだよ。。

まぁ、いまどき、グラフィックライブラリを1から作る人はいないでしょう。きっと。
でも、必要性にせまられることもあるのです。
参考にしたのは、この本。残念ながら廃刊のようです。いい本なのにね。



自分で作る必要性は、私の場合は2つ。
1.既存ライブラリだと性能が低い場合
2.既存ライブラリだと高機能すぎて重すぎる場合
まぁ、1はほとんどなく、2が主要な理由です。
ってことで、いままで作ったものを整理する意味で、いろいろ書いてみます。
ちなみに、上記の本のみでグラフィックライブラリを作ってしまいました。
Amazonの中古で出てたら、買いましょう!

あぁそうそう、

もいいですね。あんまり読んでないので、読んだらまた書きます。
この本はよくない。

2011年2月2日水曜日

PHPでsmartyするとき。

PHPでsmartyするときなんですけどー、、
せっかく、テンプレート化するんだから、うまく分離してつくりたいものです。
ここでいううまく分離というのは、
テンプレートだけをブラウザで表示させても、それらしく見えるように作れれば、
それが一番いいのでは?
という考えです。
まぁちょっと考えればわかることなんですが、とりあえず、あんまり見たことはない。
たぶん、大方の人は、可変部分をテンプレートにいれないからです。
うぅーん、正確な言い方じゃなかった。
テンプレートをhtmlで表示させるときは有効だけど、smartyで使うときは無効になるような
デリミタ設定をしてやればいいのです。
それがこれ。
$sm = new Smarty;
$sm->left_delimiter = "<!--{";
$sm->right_delimiter = "}-->";
そうすると、
<!--{$maintable}-->
<!--{* -->
<table>
<tr><td>1</td><td>2</td></tr>
<tr><td>A</td><td>B</td></tr>
</table>
<!-- *}-->
みたいに書けば、html表示したときはtableが表示され、smarty経由だと、tableが表示されなくなる。
よって、$maintableをおきかえれば、それでOKってことになりますね。
まぁ逆に、htmlができあがった時点で、可変部分については、デリミタで囲んで、置き換える変数を加えてやれば、それでOK。
昔は、DreamWeaverが8の時代には、拡張子がtplなやつを使えるように、
いろいろ設定したりアイコン作ったりしたけど、、最近はテンプレートの拡張子をhtmlしちゃうとといういい加減さです。^^;^^;