Monthly Archive for March, 2007

ColorMatrixFilter TweenEngine

ColorMatrixFilter 클래스를 이용하면  이미지의 각 픽셀의 RGBA 색상 및 알파 값에 4 x 5 행렬 변환을 적용하여 saturation 또는 contrast 또는  brightness 를 적용할수 있다. 물론 각각의 ColorMatrixFilter 에 적용되는 matrix 속성값을 다르게 설정하여야 한다.

이 예제에서 활용한 ColorMatrix 는 Mario Klingemann(http://www.quasimondo.com) 가 제작한 소스를 이용하여 트윈클래스를 제작하였다.
기본적인 클래스 구조는 이전의 트윈클래스와 같다. 객체속성을 이용하여 for~in 구문으로 트윈을 적용하였다. 다른 객체에 비해 적용되는 속성의 갯수(matrix 속성)가 20개로써 많기 때문에 이미지를 크게 하거나 트윈길이를 너무 길게할 경우 느려질 수가 있다. 또한 트윈이후 이전 트윈클래스와 같이 콜백함수를 호출할 수 있다.

download sample

//==================================================================
//@class name  :  ColorMatrixTween.as
//@author          : vkimone. KimKiJeung  (http://kimkijeung.com)
//@last update   : 2007. 03. 19
//@version         : V1.0
//==================================================================
/**
 @description
* 무비클립의  ColorMatrixFilter 트윈 클래스 : 이징함수 설정으로 조절 
 
* @example
*     <code>
*     ColorMatrixTween.tween(targetMc,0,ColorMatrixTween.SATURATION,Regular.easeOut,30,
             {{func: callBackFunction,obj: functionScope, param: [파라미터 배열로 들어감]}}
*     </code>
*/
 
import flash.filters.ColorMatrixFilter;
import com.dstrict.UB.util.filters.ColorMatrix;
class com.dstrict.UB.util.transitions.tween.ColorMatrixTween{
  public static var SATURATION:String="saturation";
  public static var CONTRAST:String="contrast";
  public static var BRIGHTNESS:String="brightness";
 
 /**---------------------------------------------------------------------
  *@description  saturation, contrast, brightness 트랜지션
    @param mc : MovieClip, 적용무비클립
    @param value : Number , 적용 percentage
    @param mode :String , saturation or contrast or brightness mode
    @param func : Function, easing function
   @param durationFrame : Number, 지속프레임
*----------------------------------------------------------------------*/
public static function tween(mc:MovieClip,value:Number,mode:String,func:Function,durationFrame:Number):Void{
var time:Number=1;
var beginning:Array=new Array();
var change:Array=new Array();
 var mat:ColorMatrix = new ColorMatrix();
 switch(mode){
   case SATURATION :
     mat.adjustSaturation(value/100);
     break;
 
   case CONTRAST :
     mat.adjustContrast(value/100);
     break;
 
   case BRIGHTNESS :
     mat.adjustBrightness(255*value/100);
     break;
  }
  var cm:ColorMatrixFilter = new ColorMatrixFilter(mat.matrix);
  var startMatrix:Array=
                       (mc.filters[0].matrix==undefined) ? ColorMatrix.IDENTITY : mc.filters[0].matrix;
  var targetMatrix:Array=mat.matrix;
 
for(var i in targetMatrix){
  beginning.push(startMatrix[i]);
  change.push(targetMatrix[i]-startMatrix[i]);
}
       var type=(typeof(arguments[5])=="object")? true : false;
       if(type){
        var referObj=arguments[5];
       }else{
        var p:Number=arguments[5];
        var referObj=arguments[6];
       }
  mc.onEnterFrame=function(){
  var objIdx:Number=0;
  for(var i in targetMatrix){
   targetMatrix[i]=func(time,beginning[objIdx],change[objIdx],durationFrame,p);
   objIdx++;
   }
   targetColMatrixFilter.matrix=targetMatrix;
   mc.filters=[targetColMatrixFilter];
   time++;
  if(time&gt;durationFrame){
   delete this.onEnterFrame;
   if(referObj!=undefined){
    referObj.func.apply(referObj.obj,referObj.param);
   }
 
  }
};
}
}
 
import  com.dstrict.UB.util.transitions.tween.FilterTween;
import  mx.transitions.easing.*;
import com.dstrict.UB.util.filters.ColorMatrix;
//SATURATION (from 0  to 100)
image.onRollOver=function(){
 ColorMatrixTween.tween(image,0,ColorMatrixTween.SATURATION,Regular.easeOut,10);
}
image.onRollOut=function(){
 ColorMatrixTween.tween(image,100,ColorMatrixTween.SATURATION,Regular.easeOut,10);
}
//CONTRAST (from 0  to 100)
image2.onRollOver=function(){
 ColorMatrixTween.tween(image2,100,ColorMatrixTween.CONTRAST,Regular.easeOut,10);
}
image2.onRollOut=function(){
 ColorMatrixTween.tween(image2,0,ColorMatrixTween.CONTRAST,Regular.easeOut,10);
}
//BRIGHTNESS (from -100  to 100)
image3.onRollOver=function(){
ColorMatrixTween.tween(image3,100,ColorMatrixTween.BRIGHTNESS,Regular.easeOut,10);
}
image3.onRollOut=function(){
ColorMatrixTween.tween(image3,0,ColorMatrixTween.BRIGHTNESS,Regular.easeOut,10);
}

Filter TweenEngine

무비클립 속성에 비해 다루기가 까다로워 필터 트원은 좀처럼 사용하지는 않았다.
특히 프레임으로 모션트윈은 어느정도 사용했지만 스크립트를 이용한 조절은 거의……

전반적으로 필터에 대해 다시 살펴보면서 이번기회에 필터트윈 클래스를 만들어 보았다.
새로 만들긴 했지만 기존에 만들었던 무비클립 Tween 클래스와 기본 구조는 같다.
어짜피 필터 트원이라는것이 필터속성을 시간단위로 변화를 주는 것이기 때문에 무비클립의 그것과 다르지 않았다.

무비클립 트윈클래스와 다른점은 인자값으로 적용할 필터오브젝트를 생성해서 넘겨주는 것이다.
그리고 그 필터속성의 변화값을 무비클립 filters 속성에 적용해 주는 것이다.
그리고 다중필터 지원은 동시에 여러가지 필터를 적용하는 경우가 많지 않을뿐더러 쓸데없이 파라미터가 길어질 염려가 있어 적용하지 않았다.

필터 적용범위는 필터속성의 데이타 타입이 Number 일경우에만 적용해야 한다. 따라서 ColorMatrixFilter와 같이 속성값이 matrix 일 경우 이 클래스로는 트윈이 적용되지 않는다. 그 이외의 모든 필터의 속성에 대해서는 트윈이 가능하다.
또한 필터 속성마다 해당하는 속성 범위가 존재한다. 이점을 유의해서 적용해야한다.

download sample

//==================================================================
//@class name  :  FilterTween.as
//@author          : vkimone. KimKiJeung  (http://kimkijeung.com)
//@last update   : 2007. 03. 07
//@version         : V1.0
//==================================================================
/**
 @description
* 무비클립의 필터 속성  트윈 클래스 : 이징함수 설정으로 조절
* 트원할 필터속성의 갯수에 관계없이 오브젝트로 적용 가능
*
* @caution
*  -반드시 트원할 필터 속성의 데이타 타입이 Number 일경우에만 적용할수 있다.
    String,Boolean,Array 는 적용할 수 없다.
   -다중필터 적용은 지원하지 않는다.
*
* @example
*     <code>
*        Filtertween.tween(targetMc,{blurX:36,blurY:36},Regular.easeOut,30,
       {{func: callBackFunction,obj: functionScope, param: [파라미터 배열로 들어감]}}
*     </code>
*/
import flash.filters.BitmapFilter;
class com.dstrict.UB.util.transitions.tween.FilterTween{
/**------------------------------------------------------------------------
 * @param mc : MovieClip, 적용무비클립
 * @param filter : BitmapFilter , 적용할 필터 객체
 * @param obj : Object, 단일 필터속성 (필터 속성 data type 이 Number 일 경우)
                                                     ex. {blurX:32,blurY:32}
 * @param func : Function, easing function
 * @param durationFrame : Number, 지속프레임
 * @param referObj :[option] reference object(caution--&gt; 파라미터값 반드시 배열요소로 입력)
*----------------------------------------------------------------------*/
public static function tween(mc:MovieClip,filter:BitmapFilter,obj:Object,func:Function,durationFrame:Number):Void{
var time:Number=1;
var beginning:Array=new Array();
var change:Array=new Array();
 
for(var i in obj){
  beginning.push(filter[i]);
  change.push(obj[i]-filter[i]);
}
       var type=(typeof(arguments[5])=="object")? true : false;
       if(type){
        var referObj=arguments[5];
       }else{
        var p:Number=arguments[5];
        var referObj=arguments[6];
       }
  mc.onEnterFrame=function(){
  var objIdx:Number=0;
  for(var i in obj){
   filter[i]=func(time,beginning[objIdx],change[objIdx],durationFrame,p);
   mc.filters=[filter]; //필터 적용부분
   objIdx++;
   }
   time++;
  if(time&gt;durationFrame){
   delete this.onEnterFrame;
   if(referObj!=undefined){
    referObj.func.apply(referObj.obj,referObj.param);
   }
 
  }
};
}
}
 
import  com.dstrict.UB.util.transitions.tween.FilterTween;
import  mx.transitions.easing.*;
import flash.filters.*;
var blurFilter:BlurFilter=new BlurFilter(0,0,1);
var dropShadowFilter:DropShadowFilter=new DropShadowFilter(0,120,0x000000,1);
var glowFilter:GlowFilter=new GlowFilter(0x6E7D74,1,16,16,2,2);
//BlurFilter
image.onRollOver=function(){
 FilterTween.tween(image,blurFilter,{blurX:8,blurY:8},Regular.easeOut,15,
        {func:onFilterTweenFinished,obj:_root,param:["blur"]});
}
image.onRollOut=function(){
 FilterTween.tween(image,blurFilter,{blurX:0,blurY:0},Regular.easeOut,15);
}
//DropShadowFilter
image2.onRollOver=function(){
 FilterTween.tween(image2,dropShadowFilter,{distance:4,blurX:4,blurY:4},Regular.easeOut,15,
        {func:onFilterTweenFinished,obj:_root,param:["dropShadow"]});
}
image2.onRollOut=function(){
 FilterTween.tween(image2,dropShadowFilter,{distance:0,blurX:4,blurY:0},Regular.easeOut,15);
}
//GlowFilter
image3.onRollOver=function(){
 FilterTween.tween(image3,glowFilter,{alpha:1,blurX:36,blurY:36},Regular.easeOut,15,
        {func:onFilterTweenFinished,obj:_root,param:["glow"]});
}
image3.onRollOut=function(){
 FilterTween.tween(image3,glowFilter,{alpha:0,blurX:0,blurY:0},Regular.easeOut,15);
}
function onFilterTweenFinished(evt):Void{
 trace("filterTween finished....."+evt);
}

Converting to a Cartesian coordinates

동적으로 여러개의 MovieClip 을 원형으로 배열할때 직교좌표계 사용하는 것보다 극좌표계를 사용하면 훨씬 다루기가 쉽다. 또한 x,y 와 같은 점을 다룰경우 Point 클래스를 이용하면 각 점간의 수학적인 연산에 있어 기본적으로 Point  클래스의 메서드를 이용하여 쉽게 처리할 수 있다.

극좌표를 직교좌표로 바꿀때도 기본으로 제공해주는 메서드를 사용하면 된다.

polar (Point.polar method)
public static polar(len: Number, angle: Number) : Point

Converts a pair of polar coordinates to a Cartesian point coordinate.

Parameters
len: Number – The length coordinate of the polar pair.
angle: Number – The angle, in radians, of the polar pair.

Returns
Point – The Cartesian point.

1167762589

import flash.geom.Point;
var len:Number = 125;
var angleInRadians:Number ;
var cartesianPoint:Point
var unitAngle:Number=15;
for(var i=1 ; i&lt;=24 ; i++){
var mc:MovieClip=this.attachMovie("M_thumb"+i,"M_thumb"+i,i);
angleInRadians = Math.PI*unitAngle/180*(i-1);
cartesianPoint = Point.polar(len, angleInRadians); // 극 좌표를 직교좌표로 전환
 
var offsetX:Number=Math.round(cartesianPoint.x);
var offsetY:Number=Math.round(cartesianPoint.y);
mc._x=Stage.width/2+offsetX;
mc._y=Stage.height/2+offsetY;
}

굳이 point 클래스를 사용하지 않고서도 극좌표계를 직교좌표계로 간단한 삼각함수를 사용하여 다음과 같이도 쉽게 바꿀수 있다.

x1=x0+(Math.cos(angle)*radius);
y1=y0+(Math.sin(angle)*radius);

하지만 Point 클래스를 사용하여 좌표를 구성한다면 코드의 일관성에 있어서나 간결성에 있어 상당한 도움이 될것이다.

Book-Actionscript 3 with Design Patterns

오래전에 사놓고 프로젝트 때문에 읽어보지 못한 책들을 이제서야 한두권씩 찾아서 읽기 시작했다.
1년 전까지만해도 왜 플래시로는 design pattern 책이 나오질 않을까?….우리나라는 그렇다 치더라도 외국에는 충분히 나왔어야할 내용의 책인데…하고 생각했던 적이 있다. 물론 이전에도 패턴에 대해 언급했던 책은 있었지만 전문적으로 플래시를 이용하여 적용한 패턴 책은 찾아 볼 수 없었다.

이제 AS3.0 나 발표된지도 어느정도 지나서인지 관련책들이 많이 보이는것 같다. 안타깝게도 해외에서만 말이다. 처음 이책을 발견하고 그자리에서 구매해버렸다. 자그마치 $50 달러….

1036283543아직 자세히 살펴보지는 못했지만 내가 기대하고 있던 내용의 책이였다. AS3.0 으로 바뀌면서 문법자체가 자바랑 상당부분 비슷하게 바뀌었기 때문에 문법적으로 자바 디자인 패턴책과 엄청난 차이가 있는것은 아니다. 하지만 플래시만의 고유의 영역에 있어서 자바나 다른 언어와는 다른 구조적인 이유로 인해 발생하는 패턴 적용의 이슈들을 어느정도 다뤄줬기 때문에 상당히 유용할것 같다.

많은 플래시 개발자들이 아직까지 플래시로 무슨 디자인패턴까지 쓰냐고 …. 아직까지 인터페이스의 개념조차도 상당수의 플래시 개발자들에게 생소한 마당에 디자인 패턴이라니…. 하면서 효용성에 있어 의문을 제기한다.

물론 나도 이점에 있어서 어느정도 동의한다. 아직까지 플래시 개발에 있어서 기존 응용프로그램 개발만큼의 큰 규모의 프로젝트가 적었기도 했고 대부분 소규모 웹사이트 개발이 전부였을 것이다.
그래서 그런지 플래시 개발을 여러사람이 공동으로 진행했다라는 소리는 좀처럼 들어보지 못한것 같다. 또한 플래시 툴의 특성상 디자인 베이스의 사용자들이 개발자로 전향했던 경우가 많아서 정통 개발자들의 관심인 여러가지 문제에 있어 플래시 개발자들에겐 논외의 대상일 수도 있다.

그렇지만 앞으로의 actionscript 는 그런 문제에 있어 먼저 개발자들이 인지하고 좀더 구조적인 프로그래밍 스킬을 쌓아가지 않으면 안되는 모양새인것 같다.
해외에서는 이미 상당수의 개발자들이 플래시 오픈소스 프로젝트를 진행하고 있다.
혼자서 하는것이 아닌 여러사람이 공동으로 개발에 참여하고 결과물을 내놓는 것이다. 이들이 이렇게 까지 할수 있는 이유 중에 하나는 바로 의사소통을 할수 있는 도구…..그들 나름대로의 프레임워크가  존재하기 때문이다. 이런 프레임워크 정의는 어느정도 구조적인 개발의 전제하에 진행되어야할 것이다.

플래시….참 어떻게 보면 쉬운 툴이고 어떻게 보면 너무 어려운 툴이다.
요즘들어 적어도 Interaction Designer 에게는 플래시 그 이외의 배워야 할것이 너무 많다는걸 느낀다. 뭔가 새로운걸 만들어야한다는 생각과….계속 발전하는 기술…..새로운 기술을 익혀 적용하기에도 바쁜데 남들과 다른 그 어떤 새로운 것을 만들어야 한다는 생각이 들때면 가끔 슬퍼질때가 있다….

예술은 아는 만큼 보이고 아는만큼 느낄수 있다고 한다.
플래시도 알면 알수록 내가 가야할 길이 너무 멀다라는걸 새삼 느낀다.

Table of Contents:

Part I – Successful Projects
1. How to Design Applications
2. Programming to Interfaces

Part II – Patterns
3. MVC
4. Singleton
5. Factory (Abstract Factory and Factory Method)
6. Proxy
7. Iterator
8. Composite
9. Decorator
10. Command
11. Memento
12. State

Part III – Advanced ActionScript Topics
13. Working with Events
14. Sending and Loading Data
15. E4X (XML)
16. Regular Expressions

책정보보기