In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

七夕:短冊 Twitter tanzaku Viewer

七夕:短冊 Twitter tanzaku Viewer
* @author Masayuki Komatsu
* http://sekiryou.com/
* http://twitter.com/sekiryou_com
/**
 * Copyright sekiryou ( http://wonderfl.net/user/sekiryou )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/3KVk
 */

/**
* 七夕:短冊 Twitter tanzaku Viewer
* @author Masayuki Komatsu
* http://sekiryou.com/
* http://twitter.com/sekiryou_com
*/
package {
    import caurina.transitions.Tweener;
    import com.bit101.components.PushButton;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.GradientType;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.geom.Matrix3D;
    import flash.geom.PerspectiveProjection;
    import flash.geom.Utils3D;
    import flash.geom.Vector3D;
    import flash.net.navigateToURL;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.utils.escapeMultiByte;
    
    [SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#DDDDDD")]
    
    public class Tanabata extends Sprite {
        private var world:Sprite = new Sprite();
        private var space:Sprite = new Sprite();
        private var i_f:Sprite = new Sprite();
        private var twitButton:Sprite = new Sprite();
        private var projection:PerspectiveProjection;
        private var projectionMatrix3D:Matrix3D;
        private var mtx3D:Matrix3D = new Matrix3D();
        private var tanzakus:Array = [];
        public function Tanabata() {
            Wonderfl.capture_delay(1);
            
            var capture:Bitmap = new Bitmap(new BitmapData(465, 465, false, 0xDDDDDD));
            addChild(capture);
            
            projection = new PerspectiveProjection();
            projection.fieldOfView = 60;
            projectionMatrix3D = projection.toMatrix3D();
            
            addChild(space);
            space.addChild(world);
            
            var test:Bamboo = new Bamboo();
            
            var i:int;
            var len:int = test.trunk.length;
            for (i = 1; i < len; i++) {
                trunkVerts.push(test.trunk[i]._bv3.x, test.trunk[i]._bv3.y, test.trunk[i]._bv3.z);
                trunkVerts.push(test.trunk[i]._ev3.x, test.trunk[i]._ev3.y, test.trunk[i]._ev3.z);
            }
            len = test.branch1.length;
            for (i = 0; i < len; i++) {
                branch1Verts.push(test.branch1[i]._bv3.x, test.branch1[i]._bv3.y, test.branch1[i]._bv3.z);
                branch1Verts.push(test.branch1[i]._ev3.x, test.branch1[i]._ev3.y, test.branch1[i]._ev3.z);
            }
            len = test.branch2.length;
            for (i = 0; i < len; i++) {
                branch2Verts.push(test.branch2[i]._bv3.x, test.branch2[i]._bv3.y, test.branch2[i]._bv3.z);
                branch2Verts.push(test.branch2[i]._ev3.x, test.branch2[i]._ev3.y, test.branch2[i]._ev3.z);
            }
            len = test.twig.length;
            for (i = 0; i < len; i++) {
                twigVerts.push(test.twig[i]._bv3.x, test.twig[i]._bv3.y, test.twig[i]._bv3.z);
                twigVerts.push(test.twig[i]._ev3.x, test.twig[i]._ev3.y, test.twig[i]._ev3.z);
            }
            len = test.leaf.length;
            for (i = 0; i < len; i++) {
                leafVerts.push(test.leaf[i]._bv3.x, test.leaf[i]._bv3.y, test.leaf[i]._bv3.z);
                leafVerts.push(test.leaf[i]._ev3.x, test.leaf[i]._ev3.y, test.leaf[i]._ev3.z);
            }
            
            search("#tanzaku");
            addEventListener("tanzaku_complete", bambooMaker);
            
           var tweetButton:PushButton = new PushButton(this);
            tweetButton.label = "Tweet Tanzaku";
            tweetButton.x = (465 - tweetButton.width) * 0.5;
            tweetButton.y = (465 - tweetButton.height) - 5;
            tweetButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
                navigateToURL(new URLRequest("http://twitter.com/home/?status="
                    + escapeMultiByte("http://wonderfl.net/c/3KVk #tanzaku")
                ));
            });
        }
        private var flag:Boolean = true;
        private function bambooMaker(e:Event):void {
            if (flag) {
                flag = false;
                trunkImage();
                branchImage();
                leafImage();
                bambooRender();
            }
            tanzakuRender()
        }
        
        private var posX:Number = 0;
        private var posY:Number = 0;
        private var posZ:Number = 640;
        private var rotX:Number = 0;
        private var rotY:Number = 0;
        private var rotZ:Number = 0;
        private var prjctOffsetX:Number = 233;
        private var prjctOffsetY:Number = 520;
        private var trunkPrjctVerts:Vector.<Number> = new Vector.<Number>();
        private var trunkVerts:Vector.<Number> = new Vector.<Number>();
        private var branch1PrjctVerts:Vector.<Number> = new Vector.<Number>();
        private var branch1Verts:Vector.<Number> = new Vector.<Number>();
        private var branch2PrjctVerts:Vector.<Number> = new Vector.<Number>();
        private var branch2Verts:Vector.<Number> = new Vector.<Number>();
        private var twigPrjctVerts:Vector.<Number> = new Vector.<Number>();
        private var twigVerts:Vector.<Number> = new Vector.<Number>();
        private var leafPrjctVerts:Vector.<Number> = new Vector.<Number>();
        private var leafVerts:Vector.<Number> = new Vector.<Number>();
        private var uvts:Vector.<Number> = new Vector.<Number>();

        private function bambooRender():void {
            mtx3D.identity();
            mtx3D.appendRotation(rotX, Vector3D.X_AXIS);
            mtx3D.appendRotation(rotY, Vector3D.Y_AXIS);
            mtx3D.appendRotation(rotZ, Vector3D.Z_AXIS);
            mtx3D.appendTranslation(posX, posY, posZ);
            mtx3D.append(projectionMatrix3D);
            bugfix(mtx3D);
            
            Utils3D.projectVectors(mtx3D, trunkVerts, trunkPrjctVerts, uvts);
            Utils3D.projectVectors(mtx3D, branch1Verts, branch1PrjctVerts, uvts);
            Utils3D.projectVectors(mtx3D, branch2Verts, branch2PrjctVerts, uvts);
            Utils3D.projectVectors(mtx3D, twigVerts, twigPrjctVerts, uvts);
            Utils3D.projectVectors(mtx3D, leafVerts, leafPrjctVerts, uvts);
            
            var i:int;
            var len:int = trunkPrjctVerts.length;
            for (i = 0; i < len; i += 4) {
                mtrx.identity();
                var tmpShape:Sprite = new Sprite();
                tmpShape.graphics.copyFrom(trunkShape.graphics);
                world.addChild(tmpShape);
                
                var tmpX:Number = trunkPrjctVerts[i + 2 >> 0] - trunkPrjctVerts[i];
                var tmpY:Number = trunkPrjctVerts[i + 3 >> 0] - trunkPrjctVerts[i + 1 >> 0];
                tmpShape.scaleX = Math.sqrt(tmpX * tmpX + tmpY * tmpY) * 0.005;
                tmpShape.scaleY = tmpShape.scaleX * 0.8;
                tmpShape.rotation = Math.atan2(tmpY, tmpX) * (180 / Math.PI);
                tmpShape.x = trunkPrjctVerts[i] + prjctOffsetX;
                tmpShape.y = trunkPrjctVerts[i + 1 >> 0] + prjctOffsetY;
            }
            
            len = branch1PrjctVerts.length;
            for (i = 0; i < len; i += 4) {
                mtrx.identity();
                tmpShape = new Sprite();
                tmpShape.graphics.copyFrom(trunkShape.graphics);
                world.addChild(tmpShape);
                
                tmpX = branch1PrjctVerts[i + 2 >> 0] - branch1PrjctVerts[i];
                tmpY = branch1PrjctVerts[i + 3 >> 0] - branch1PrjctVerts[i + 1 >> 0];
                tmpShape.scaleX = Math.sqrt(tmpX * tmpX + tmpY * tmpY) * 0.005;
                tmpShape.scaleY = tmpShape.scaleX * 0.3;
                tmpShape.rotation = Math.atan2(tmpY, tmpX) * (180 / Math.PI);
                tmpShape.x = branch1PrjctVerts[i] + prjctOffsetX;
                tmpShape.y = branch1PrjctVerts[i + 1 >> 0] + prjctOffsetY;
            }
            
            len = branch2PrjctVerts.length;
            for (i = 0; i < len; i += 4) {
                mtrx.identity();
                tmpShape = new Sprite();
                tmpShape.graphics.copyFrom(trunkShape.graphics);
                world.addChild(tmpShape);
                
                tmpX = branch2PrjctVerts[i + 2 >> 0] - branch2PrjctVerts[i];
                tmpY = branch2PrjctVerts[i + 3 >> 0] - branch2PrjctVerts[i + 1 >> 0];
                tmpShape.scaleX = Math.sqrt(tmpX * tmpX + tmpY * tmpY) * 0.005;
                tmpShape.scaleY = tmpShape.scaleX * 0.3;
                tmpShape.rotation = Math.atan2(tmpY, tmpX) * (180 / Math.PI);
                tmpShape.x = branch2PrjctVerts[i] + prjctOffsetX;
                tmpShape.y = branch2PrjctVerts[i + 1 >> 0] + prjctOffsetY;
            }
            
            len = twigPrjctVerts.length;
            for (i = 0; i < len; i += 4) {
                mtrx.identity();
                tmpShape = new Sprite();
                tmpShape.graphics.copyFrom(branchShape.graphics);
                world.addChild(tmpShape);
                
                tmpX = twigPrjctVerts[i + 2 >> 0] - twigPrjctVerts[i];
                tmpY = twigPrjctVerts[i + 3 >> 0] - twigPrjctVerts[i + 1 >> 0];
                tmpShape.scaleX = Math.sqrt(tmpX * tmpX + tmpY * tmpY) * 0.005;
                tmpShape.scaleY = tmpShape.scaleX * 0.4;
                tmpShape.rotation = Math.atan2(tmpY, tmpX) * (180 / Math.PI);
                tmpShape.x = twigPrjctVerts[i] + prjctOffsetX;
                tmpShape.y = twigPrjctVerts[i + 1 >> 0] + prjctOffsetY;
            }
            
            len = leafPrjctVerts.length;
            for (i = 0; i < len; i += 4) {
                mtrx.identity();
                tmpShape = new Sprite();
                tmpShape.graphics.copyFrom(leafShape.graphics);
                world.addChild(tmpShape);
                
                tmpX = leafPrjctVerts[i + 2 >> 0] - leafPrjctVerts[i];
                tmpY = leafPrjctVerts[i + 3 >> 0] - leafPrjctVerts[i + 1 >> 0];
                tmpShape.scaleX = Math.sqrt(tmpX * tmpX + tmpY * tmpY) * 0.005;
                tmpShape.scaleY = tmpShape.scaleX * 0.4;
                tmpShape.rotation = Math.atan2(tmpY, tmpX) * 57.29578049;
                tmpShape.x = leafPrjctVerts[i] + prjctOffsetX;
                tmpShape.y = leafPrjctVerts[i + 1 >> 0] + prjctOffsetY;
            }
        }
        private function tanzakuRender():void {
            var len:int = tanzakus.length;
            for (var i:int = 0; i < len; i++) {
                var rnd:Number = Math.random() * 40 + 60;
                if (i < 10) {
                    var tmpX:Number = (branch2PrjctVerts[(i + 2) * 4 + 2 >> 0] - branch2PrjctVerts[(i + 2) * 4 + 0 >> 0]) * 0.01;
                    var tmpY:Number = (branch2PrjctVerts[(i + 2) * 4 + 3 >> 0] - branch2PrjctVerts[(i + 2) * 4 + 1 >> 0]) * 0.01;
                    tanzakus[i].x = branch2PrjctVerts[(i + 2)  * 4 + 0 >> 0] + prjctOffsetX + tmpX * rnd;
                    tanzakus[i].y = branch2PrjctVerts[(i + 2)  * 4 + 1 >> 0] + prjctOffsetY + tmpY * rnd;
                } else {
                    tmpX = (branch1PrjctVerts[(i - 8) * 4 + 2 >> 0] - branch1PrjctVerts[(i - 8) * 4 + 0 >> 0]) * 0.01;
                    tmpY = (branch1PrjctVerts[(i - 8) * 4 + 3 >> 0] - branch1PrjctVerts[(i - 8) * 4 + 1 >> 0]) * 0.01;
                    tanzakus[i].x = branch1PrjctVerts[(i - 8)  * 4 + 0 >> 0] + prjctOffsetX + tmpX * rnd;
                    tanzakus[i].y = branch1PrjctVerts[(i - 8)  * 4 + 1 >> 0] + prjctOffsetY + tmpY * rnd;
                }
                tanzakus[i].scaleX = 0.15;
                tanzakus[i].scaleY = 0.15;
                world.addChild(tanzakus[i]);
            }
            setTween();
        }
        private function setTween():void {
            Tweener.removeAllTweens();
            var turnTime:Number = 8;
            var fillInTime:Number = 3;
            var fillOutTime:Number = 2;
            for (var j:int = 0; j < 20; j++) {
                Tweener.addTween(space, { scaleX:6.0, scaleY:6.0, x:233, y:233, time:fillInTime, transition:"easeInOutCubic", delay:j * turnTime } );
                Tweener.addTween(world, { x: -tanzakus[j].x, y: -tanzakus[j].y - tanzakus[j].height * 0.5 - 10.0, time:fillInTime, transition:"easeInOutCubic", delay:j * turnTime } );
                
                Tweener.addTween(space, { scaleX:1.0, scaleY:1.0, x:tanzakus[j].x, y:tanzakus[j].y, time:fillOutTime, transition:"easeInOutCubic", delay:(j * turnTime) + (turnTime - fillOutTime) } );
            }
            //AUTO RELOAD
            Tweener.addTween(space, {onComplete:function():void {search("#tanzaku");}, time:0, delay:j * turnTime});
        }
        private var trunkShape:Shape;
        private var branchShape:Shape;
        private var leafShape:Shape;
        private var mtrx:Matrix = new Matrix();
        private function trunkImage():void {
            trunkShape = new Shape();
            var g:Graphics = trunkShape.graphics;
            
            g.beginFill(0x000000);
            g.moveTo(185, -10);
            g.curveTo(196, -16, 198, -16);
            g.curveTo(194, 0, 198, 16);
            g.curveTo(196, 12, 185, 10);
            //
            g.moveTo(15, -10);
            g.curveTo(8, -12, 2, -12);
            g.curveTo(-4, 6, 0, 6);
            g.curveTo(2, 10, 15, 10);
            g.endFill();
            
            var mtrx:Matrix = new Matrix();
            mtrx.createGradientBox(20, 20, 0, 5, -10);
            g.beginGradientFill(GradientType.RADIAL, [0x999999, 0x000000], [1.0, 1.0], [0x00, 0xFF], mtrx);
            g.drawCircle(15, 0, 10);
            
            mtrx.identity();
            mtrx.createGradientBox(20, 20, 0, 175, -10);
            g.beginGradientFill(GradientType.RADIAL, [0x9999996, 0x000000], [1.0, 1.0], [0x00, 0xFF], mtrx);
            g.drawCircle(185, 0, 10);
            
            mtrx.identity();
            mtrx.createGradientBox(200, 20, Math.PI * 0.5, 0, -10);
            g.beginGradientFill(GradientType.LINEAR, [0x000000, 0x999999, 0x000000], [1.0, 1.0, 1.0], [0x00, 0x80, 0xFF], mtrx);
            g.moveTo(15, -10);
            g.curveTo(90, -14, 185, -10);
            g.lineTo(185, 10);
            g.curveTo(90, 6, 15, 10);
            g.lineTo(15, -10);
            g.endFill();
        }
        private function branchImage():void {
            branchShape = new Shape();
            var g:Graphics = branchShape.graphics;
            
            var mtrx:Matrix = new Matrix();
            mtrx.createGradientBox(100, 10, 0, 0, -10);
            g.beginGradientFill(GradientType.LINEAR, [0x000000, 0x000000], [0.8, 0.4], [0x00, 0xFF], mtrx);
            g.moveTo(10, -8);
            g.curveTo(55, -8, 200, 0);
            g.curveTo(55, 8, 10, 8);
            g.curveTo(0, 8, 0, 0);
            g.curveTo(0, -8, 10, -8);
        }
        private function leafImage():void {
            leafShape = new Shape();
            var g:Graphics = leafShape.graphics;
            
            var mtrx:Matrix = new Matrix();
            mtrx.createGradientBox(100, 10, 0, 0, -10);
            g.beginGradientFill(GradientType.LINEAR, [0x000000, 0x000000], [0.6, 0.6], [0x00, 0xFF], mtrx);
            var width:Number = 24;
            g.moveTo(40, -width);
            g.curveTo(55, -width, 200, 0);
            g.curveTo(55, width, 40, width);
            g.curveTo(20, width, 0, 0);
            g.curveTo(20, -width, 40, -width);
        }
        //
        private function bugfix(matrix:Matrix3D):void {
            var m1:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]));
            var m2:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
            m1.append( m2 );
            if (m1.rawData[15] == 20) {
                var rawData:Vector.<Number> = matrix.rawData;
                rawData[15] /= 20;
                matrix.rawData = rawData;
            }
        }
        
        public function search(serchWord:String):void {
            var myURLLoader:URLLoader = new URLLoader();
            myURLLoader.addEventListener(Event.COMPLETE, onCompleteXML);
            myURLLoader.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
            var xmlURL:String = "http://search.twitter.com/search.atom?q=";
            xmlURL += encodeURIComponent(serchWord);
            xmlURL += "&rpp=100&test=" + Math.random;
            myURLLoader.load(new URLRequest(xmlURL));
        }
        public function onIoError(e:IOErrorEvent):void {
            trace(e.type);
        }
        private function onCompleteXML(e:Event):void {
            var len:int = tanzakus.length;
            for (i = 0; i < len; i++) {
                world.removeChild(tanzakus[i]);
            }
            tanzakus = [];
            e.currentTarget.removeEventListener(Event.COMPLETE, onCompleteXML);
            
            var myXML:XML = new XML(e.currentTarget.data);
            default xml namespace = new Namespace("http://www.w3.org/2005/Atom");
            
            var itemLength:int = myXML.entry.length();
            
            var tagNums:Array = [];
            for (var i:int = 0; i < itemLength; i++) {
                tagNums.push(i);
            }
            tagNums.sort(function():int { return Math.random() > 0.5 ? 1 : -1; } );
            
            if (itemLength > 20) {
                var tzId:int = 20;
            } else {
                tzId = itemLength;
            }
            
            for (i = 0; i < tzId; i++) {
                var authorName:String = myXML.entry[tagNums[i]].author.name;
                var title:String = myXML.entry[tagNums[i]].title;
                
                var tmp:Tanzaku = new Tanzaku(title, authorName);
                tanzakus.push(tmp);
            }
            if (tzId < 20) {
                var authors:Array = ["template00(test)","template01(test)","template02(test)","template03(test)","template04(test)","template05(test)","template06(test)","template07(test)","template08(test)","template09(test)","template10(test)","template11(test)","template12(test)","template13(test)","template14(test)","template15(test)","template16(test)","template17(test)","template18(test)","template19(test)"];
                var titles:Array = ["おとうさんのしごとがみつかりますように", "|´・ω・`| みんな~", "みんなが幸せでありますように", "七夕まつり","ミ☆ 天の川 ミ☆","たなばた","彦星 織姫", "ありがとう",  "ヒタ",  "和んだふる", "おとうさんのしごとがみつかりますように", "みんなが幸せでありますように", "|´・ω・`| みんな~", "七夕まつり","ミ☆ 天の川 ミ☆","たなばた","彦星 織姫", "ありがとう",  "ヒタ",  "和んだふる"];
                titles.sort(function():int { return Math.random() > 0.5 ? 1 : -1; } );
                for (i = 0; i < 20 - itemLength; i++) {
                    tmp = new Tanzaku(titles[i], authors[i]);
                    tanzakus.push(tmp);
                }
            }
            dispatchEvent(new Event("tanzaku_complete"));
        }
    }
}

import flash.geom.Vector3D
class Node {
    public var _bv3:Vector3D;
    public var _ev3:Vector3D;
    public function Node(bv3:Vector3D, ev3:Vector3D) {
        _bv3 = bv3;
        _ev3 = ev3;
    }
}

import flash.geom.Matrix3D;
import flash.geom.Vector3D;
class Bamboo {
    private var mtx3D:Matrix3D = new Matrix3D();
    public var ground:Node;
    public var trunk:Vector.<Node> = new Vector.<Node>();
    public var branch1:Vector.<Node> = new Vector.<Node>();
    public var branch2:Vector.<Node> = new Vector.<Node>();
    public var twig:Vector.<Node> = new Vector.<Node>();
    public var leaf:Vector.<Node> = new Vector.<Node>();
    public function Bamboo() {
        var i:int;
        var angleX:Number = 0;
        var angleZ:Number = Math.random() * 8 - 4;
        
        ground = new Node(new Vector3D(0, 0, 0), new Vector3D(0, 0, 0));
        trunk.push(ground);
        for (i = 1; i < 8; i++) {
            var tmpTrunk:Node = new Node(new Vector3D(0, 0, 0), new Vector3D(0, -120, 0));
            trunk.push(tmpTrunk);
            mtx3D.identity();
            mtx3D.appendRotation(angleX, Vector3D.X_AXIS);
            mtx3D.appendRotation(angleZ, Vector3D.Z_AXIS);
            mtx3D.appendTranslation(trunk[i - 1 >> 0]._ev3.x, trunk[i - 1 >> 0]._ev3.y, trunk[i - 1 >> 0]._ev3.z);
            bugfix(mtx3D);
            trunk[i]._bv3 = mtx3D.transformVector(trunk[i]._bv3);
            trunk[i]._ev3 = mtx3D.transformVector(trunk[i]._ev3);
        }
        for (i = 0; i < 8; i++) {
            var tmpAngleZ:Number = 35 + Math.random() * 8 - 4;
            var node:Node = new Node(new Vector3D(0, 0, 0), new Vector3D(0, -100, 0));
            mtx3D.identity();
            mtx3D.appendRotation(tmpAngleZ, Vector3D.Z_AXIS);
            mtx3D.appendTranslation(trunk[i]._ev3.x + 8, trunk[i]._ev3.y, trunk[i]._ev3.z);
            bugfix(mtx3D);
            node._bv3 = mtx3D.transformVector(node._bv3);
            node._ev3 = mtx3D.transformVector(node._ev3);
            branch1.push(node);
            
            tmpAngleZ = -35 + Math.random() * 8 - 4;
            node = new Node(new Vector3D(0, 0, 0), new Vector3D(0, -100, 0));
            mtx3D.identity();
            mtx3D.appendRotation(tmpAngleZ, Vector3D.Z_AXIS);
            mtx3D.appendTranslation(trunk[i]._ev3.x - 8, trunk[i]._ev3.y, trunk[i]._ev3.z);
            bugfix(mtx3D);
            node._bv3 = mtx3D.transformVector(node._bv3);
            node._ev3 = mtx3D.transformVector(node._ev3);
            branch1.push(node);
        }
        for (i = 0; i < 6; i++) {
            tmpAngleZ = 35;// + Math.random() * 8 - 4;
            node = new Node(new Vector3D(0, 0, 0), new Vector3D(0, -100, 0));
            mtx3D.identity();
            mtx3D.appendRotation(tmpAngleZ, Vector3D.Z_AXIS);
            mtx3D.appendTranslation(branch1[i  * 2]._ev3.x, branch1[i  * 2]._ev3.y, branch1[i  * 2]._ev3.z);
            bugfix(mtx3D);
            node._bv3 = mtx3D.transformVector(node._bv3);
            node._ev3 = mtx3D.transformVector(node._ev3);
            branch2.push(node);
            
            tmpAngleZ = -35;// + Math.random() * 8 - 4;
            node = new Node(new Vector3D(0, 0, 0), new Vector3D(0, -100, 0));
            mtx3D.identity();
            mtx3D.appendRotation(tmpAngleZ, Vector3D.Z_AXIS);
            mtx3D.appendTranslation(branch1[i * 2 + 1 >> 0]._ev3.x, branch1[i  * 2 + 1 >> 0]._ev3.y, branch1[i  * 2 + 1 >> 0]._ev3.z);
            bugfix(mtx3D);
            node._bv3 = mtx3D.transformVector(node._bv3);
            node._ev3 = mtx3D.transformVector(node._ev3);
            branch2.push(node);
        }
        for (i = 0; i < 12; i += 2 ) {
            tmpAngleZ = 35 + Math.random() * 8 - 4;
            node = new Node(new Vector3D(0, 0, 0), new Vector3D(0, -80, 0));
            mtx3D.identity();
            mtx3D.appendRotation(tmpAngleZ, Vector3D.Z_AXIS);
            mtx3D.appendTranslation(branch2[i]._ev3.x, branch2[i]._ev3.y, branch2[i]._ev3.z);
            bugfix(mtx3D);
            node._bv3 = mtx3D.transformVector(node._bv3);
            node._ev3 = mtx3D.transformVector(node._ev3);
            twig.push(node);
            
            tmpAngleZ = -35 + Math.random() * 8 - 4;
            node = new Node(new Vector3D(0, 0, 0), new Vector3D(0, -80, 0));
            mtx3D.identity();
            mtx3D.appendRotation(tmpAngleZ, Vector3D.Z_AXIS);
            mtx3D.appendTranslation(branch2[i + 1 >> 0]._ev3.x, branch2[i + 1 >> 0]._ev3.y, branch2[i + 1 >> 0]._ev3.z);
            bugfix(mtx3D);
            node._bv3 = mtx3D.transformVector(node._bv3);
            node._ev3 = mtx3D.transformVector(node._ev3);
            twig.push(node);
        }
        for (i = 0; i < 12; i++) {
            var baseRnd:Number = Math.random() * 32 - 16;
            for (var j:int = 0; j < 6; j++ ) {
                tmpAngleZ = baseRnd + (j - 3) * 20 + Math.random() * 12 - 6;
                node = new Node(new Vector3D(0, 5, 0), new Vector3D(0, 70, 0));
                mtx3D.identity();
                mtx3D.appendRotation(tmpAngleZ, Vector3D.Z_AXIS);
                mtx3D.appendTranslation(branch1[i]._ev3.x, branch1[i]._ev3.y, branch1[i]._ev3.z);
                bugfix(mtx3D);
                node._bv3 = mtx3D.transformVector(node._bv3);
                node._ev3 = mtx3D.transformVector(node._ev3);
                leaf.push(node);
                
                tmpAngleZ = baseRnd + (j - 3) * 20 + Math.random() * 12 - 6;
                node = new Node(new Vector3D(0, 5, 0), new Vector3D(0, 70, 0));
                mtx3D.identity();
                mtx3D.appendRotation(tmpAngleZ, Vector3D.Z_AXIS);
                mtx3D.appendTranslation(branch2[i]._ev3.x, branch2[i]._ev3.y, branch2[i]._ev3.z);
                bugfix(mtx3D);
                node._bv3 = mtx3D.transformVector(node._bv3);
                node._ev3 = mtx3D.transformVector(node._ev3);
                leaf.push(node);
            }
        }
    }
    private function bugfix(matrix:Matrix3D):void {
        var m1:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]));
        var m2:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
        m1.append( m2 );
        if (m1.rawData[15] == 20) {
            var rawData:Vector.<Number> = matrix.rawData;
            rawData[15] /= 20;
            matrix.rawData = rawData;
        }
    }
}

import flash.display.Graphics;
import flash.display.Sprite;
import flash.text.engine.FontDescription;
import flash.text.engine.TextBlock;
import flash.text.engine.TextElement;
import flash.text.engine.TextLine;
import flash.text.engine.TextRotation;
import flash.text.engine.ElementFormat;
import flash.text.engine.EastAsianJustifier;
import flash.text.TextField;

class Tanzaku extends Sprite {
    private var titleTF:TextField = new TextField();
    private var _title:String = new String();
    private var _author:String = new String();
    private var tanzakuMC:Sprite = new Sprite();
    private var titleMC:Sprite = new Sprite();
    private var authorMC:Sprite = new Sprite();
    public function Tanzaku(title:String, author:String):void {
        _title = title;
        _author = author;
        
        var tanzakuWidth:Number = 160;
        var tanzakuCenter:Number = tanzakuWidth * 0.5;
        var titleWidth:Number = 120;
        var authorWidth:Number = 30;
        var authorHeight:Number = 180;
        var stringLength:Number = 80;
        var holeY:Number = 20;
        addChild(tanzakuMC);
        tanzakuMC.x = -tanzakuCenter;
        tanzakuMC.y = 80 + 20;
        var g:Graphics = tanzakuMC.graphics;
        
        g.lineStyle(1);
        g.moveTo(tanzakuCenter, holeY);
        g.curveTo(tanzakuCenter + 10, -20, tanzakuCenter, -100);
        
        g.lineStyle(1, 0xBBBBBB);
        g.beginFill(0xEEEEEE);
        g.drawCircle(tanzakuCenter, holeY, 6);
        g.drawRect(0, 0, tanzakuWidth, 440);
        g.endFill();
        
        g.lineStyle(1);
        g.moveTo(tanzakuCenter, holeY);
        g.curveTo(tanzakuCenter - 10, -20, tanzakuCenter, -100);
        
        tategaki(_title, titleMC, 0, 0);
        tanzakuMC.addChild(titleMC);
        var tmp:Number = titleWidth / titleMC.width;
        titleMC.width *= tmp;
        titleMC.height *= tmp;
        if (titleMC.height > 360) {
            tmp = 360 / titleMC.height;
            titleMC.width *= tmp;
            titleMC.height *= tmp;
        }
        
        if (titleMC.width < titleWidth) {
            if (titleMC.width * 0.5 < tanzakuCenter - authorWidth) {
                titleMC.x = tanzakuCenter + titleMC.width * 0.5;
            } else {
                titleMC.x = tanzakuCenter + titleMC.width * 0.5 + (titleMC.width * 0.5 - tanzakuCenter - authorWidth);
            }
        } else {
            titleMC.x = tanzakuWidth - 10;
        }
        titleMC.y = 40;
        
        tategaki(_author, authorMC, 0, 0);
        tanzakuMC.addChild(authorMC);
        
        tmp = authorWidth / authorMC.width;
        authorMC.width *= tmp;
        authorMC.height *= tmp;
        if (authorMC.height > authorHeight) {
            tmp = authorHeight / authorMC.height;
            authorMC.width *= tmp;
            authorMC.height *= tmp;
        }
        
        authorMC.x = authorWidth * 0.5 + 15;
        authorMC.y = 240;
    }
    private function tategaki(tag:String, mc:Sprite, posX:Number = 0, posY:Number = 0):void {
        var fontDescription:FontDescription = new FontDescription("MS Mincho");
        var format:ElementFormat = new ElementFormat();
        format.fontSize = 12;
        format.fontDescription = fontDescription;
        
        var txt_array:Array = tag.split("\r");
        var linePosition:Number = posX - format.fontSize;
        
        for (var i:int = 0; i < txt_array.length; i++) {
            setTB(txt_array[i]);
        }
        function setTB(txt:String):void{
            var textElement:TextElement = new TextElement(txt, format);
            var textBlock:TextBlock = new TextBlock();
            textBlock.content = textElement;
            textBlock.lineRotation = TextRotation.ROTATE_90;
            textBlock.textJustifier = new EastAsianJustifier("ja", "unjustified", "pushInKinsoku");

            var previousLine:TextLine = null;
        
            while (true) {
                var textLine:TextLine = textBlock.createTextLine(
                    previousLine,
                    240);
                if (textLine == null)
                    break;
                textLine.y = posY;
                textLine.x = linePosition;
                linePosition -= 24;
                mc.addChild(textLine);
                previousLine = textLine;
            }
        }
    }
}