flash on 2010-8-6

by amashio
drawTriangles()を使ってビットマップを矩形に描画。
矩形のポイントを移動させるとビットマップを歪めることができる
♥0 | Line 108 | Modified 2010-08-06 15:40:17 | MIT License
play

ActionScript3 source code

/**
 * Copyright amashio ( http://wonderfl.net/user/amashio )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/jf9L
 */

package {

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.system.Security;

    [SWF(width=550, height=400, backgroundColor=0xFFFFFF)]

    /**
    * drawTriangles()を使ってビットマップを矩形に描画。
    * 矩形のポイントを移動させるとビットマップを歪めることができる
    */
    public class RenderingTriangles extends Sprite {

        private var _anchors:Vector.<Sprite>;
        private var _anchor:Sprite;
        private var _anchorIndex:uint;
        private var _vertices:Vector.<Number>;
        private var _indices:Vector.<int>;
        private var _uvtData:Vector.<Number>;
        private var _image:BitmapData;

        /**
        * コンストラクタ
        */
        public function RenderingTriangles() {
            loadImage();
        }

        /**
        * 歪曲させるイメージのロード
        */
        private function loadImage():void {
            Security.loadPolicyFile("http://5ivestar.org/proxy/crossdomain.xml");
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
            loader.load(new URLRequest("http://5ivestar.org/proxy/http://amashio.com/wonderfl/15_RenderingTriangles/footprints.jpg"));
        }

        /**
        * 4つの三角形用のvertices、indicies、uvtDataを定義。
        * verticesには、頂点がドラッグできるように視覚的なアンカーポイントを追加
        */
        private function defineTriangles():void {
            // イメージとステージの端との余白
            var border:Number = 50;
            var width:Number = stage.stageWidth;
            var height:Number = stage.stageHeight;

            //5つのアンカーポイントを保持
            _anchors = new Vector.<Sprite>();
            addAnchor(border, border);
            addAnchor(width-border, border);
            addAnchor(width/2, height/2);
            addAnchor(border, height-border);
            addAnchor(width-border, height-border);

            _vertices = new Vector.<Number>();
            for each (var anchor:Sprite in _anchors) {
                _vertices.push(anchor.x, anchor.y);
                trace(anchor.x, anchor.y);
                trace(TextField(anchor.getChildAt(0)).text);
            }

            _indices = new Vector.<int>();
            _indices.push(1, 0, 2);
            _indices.push(0, 2, 3);
            _indices.push(1, 2, 4);
            _indices.push(2, 3, 4);

            _uvtData = new Vector.<Number>();
            _uvtData.push(0, 0);
            _uvtData.push(1, 0);
            _uvtData.push(.5, .5);
            _uvtData.push(0, 1);
            _uvtData.push(1, 1);
        }

        /**
        * 視覚的なアンカーポイントを指定されたx/y位置に追加する
        *
        * @param x アンカーのx位置
        * @param y アンカーのy位置
        */
        private function addAnchor(x:Number, y:Number):void {
            var anchor:Sprite = new Sprite();
            // 太い線スタイルと1ピクセルの線の描画で即席の円を作成
            anchor.graphics.lineStyle(20);
            anchor.graphics.lineTo(1, 0);
            anchor.addEventListener(MouseEvent.MOUSE_DOWN, onAnchorDown);
            anchor.addEventListener(MouseEvent.MOUSE_UP, onAnchorUp);
            anchor.x = x;
            anchor.y = y;
            // アンカーには、_anchorsベクターでのインデックスを示すラベルを置く
            var label:TextField = new TextField();
            label.x = -4;
            label.y = -9;
            label.mouseEnabled = false;
            label.textColor = 0xFFFFFF;
            label.text = String(_anchors.length);
            anchor.addChild(label);
            addChild(anchor);
            _anchors.push(anchor);
        }

        /**
        * 現在の頂点の位置にもとづいてビットマップを再描画
        */
        private function draw():void {
            graphics.clear();
            graphics.beginBitmapFill(_image);
            graphics.drawTriangles(_vertices, _indices, _uvtData);
            graphics.endFill();
        }

        /**
        * アンカーがクリックされたときのハンドラ。アンカーのドラッグを開始する
        *
        * @param event anchorスプライトが送出するイベント
        */
        private function onAnchorDown(event:MouseEvent):void {
            _anchor = event.target as Sprite;
            _anchor.startDrag();
            _anchorIndex = _anchors.indexOf(_anchor);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onAnchorMove);
        }

        /**
        * アンカーがドラッグされるときのハンドラ。関係する頂点の位置を更新し、ビットマップを再描画する
        *
        * @param event anchorスプライトが送出するイベント
        */
        private function onAnchorMove(event:MouseEvent):void {
            _vertices[_anchorIndex*2] = _anchor.x;
            _vertices[_anchorIndex*2+1] = _anchor.y;
            draw();
            event.updateAfterEvent();
        }

        /**
        * ドラッグ後アンカーがリリースされたときのハンドラ。ドラッグを停止する
        *
        * @param event anchorスプライトが送出するイベント
        */
        private function onAnchorUp(event:MouseEvent):void {
            if (_anchor) {
                _anchor.stopDrag();
                stage.removeEventListener(MouseEvent.MOUSE_MOVE, onAnchorMove);
            }
        }

        /**
        * イメージのロードが完了したときのハンドラ。メモリ内にイメージを保存しビットマップを三角形内に描画する
        *
        * @param event LoaderInfoが送出するイベント
        */
        private function onImageLoaded(event:Event):void {
            var loaderInfo:LoaderInfo = event.target as LoaderInfo;
            var bitmap:Bitmap = loaderInfo.content as Bitmap;
            _image = bitmap.bitmapData;
            defineTriangles();
            draw();
        }

    }

}