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

forked from: ニコニコ動画で見たアレの劣化版

ネタ元 http://www.nicovideo.jp/watch/sm9277616

1. 画像の上を適当にドラッグして色を塗る
2. 左上 Blur ボタンをクリックすればなめらか
3. 満足いくまで塗ったら、左下 Make3D ボタンをクリック
4. 画像をドラッグして回転したり、下の Height スライダを動かすなど
5. 好きな画像を読み込んでみると楽しいかも
6. 3Dモードの時に Ctrl キーを押しながらマウスで画像をつかんではなすと・・・!!

JellyPicsのコードをPV3Dで動くようにして強引に組み込ませていただきました。
http://dotfla.net/
/**
 * Copyright Carlos.Guerrero ( http://wonderfl.net/user/Carlos.Guerrero )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/2zJa
 */

// forked from matsumos's ニコニコ動画で見たアレの劣化版
// ネタ元 http://www.nicovideo.jp/watch/sm9277616
// forked from matsumos's エセ3Dモデラー
/* 
 * 1. 画像の上を適当にドラッグして色を塗る
 * 2. 左上 Blur ボタンをクリックすればなめらか
 * 3. 満足いくまで塗ったら、左下 Make3D ボタンをクリック
 * 4. 画像をドラッグして回転したり、下の Height スライダを動かすなど
 * 5. 好きな画像を読み込んでみると楽しいかも
 * 6. 3Dモードの時に Ctrl キーを押しながらマウスで画像をつかんではなすと・・・!!
 *
 * JellyPicsのコードをPV3Dで動くようにして強引に組み込ませていただきました。
 * http://dotfla.net/
 */

package
{
    import com.bit101.components.*;
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.net.*;
    import flash.system.LoaderContext;
    import flash.system.Security;
    import flash.utils.ByteArray;
    import mx.graphics.codec.PNGEncoder;
    import org.papervision3d.cameras.*;
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import org.papervision3d.core.math.*;
    import org.papervision3d.core.utils.Mouse3D;
    import org.papervision3d.materials.*
    import org.papervision3d.objects.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.view.*;
    import net.hires.debug.Stats;

    public class Main extends BasicView
    {
        private var _plane:Plane;
        private var _material:BitmapMaterial;
        private var _paint:Paint;
        private var _canvas:BitmapData;
        private var _imageWidth:int;
        private var _imageHeight:int;
        private var _make3dButton:PushButton;
        private var _draw2dButton:PushButton;
        private var _hitArea:Sprite;
        private var _heightSlider:HUISlider;
        private var _loadMapDataButton:PushButton;
        
        // ドラッグによってかかっている力
        private var _power:Rectangle;
        
        // オリジナルの頂点データ
        private var _baseVertices:Array = [];
        // 力がかかった状態の頂点データ
        private var _poweredVertices:Array = [];
        // 現在の頂点データ
        private var _vertices:Array;
        // 各頂点にかかる力
        private var _energies:Array = [];
        
        private var _forces:Array = [];
        
        public function Main():void
        {
            stage.quality = StageQuality.MEDIUM;
            
            _imageWidth = _imageHeight = 465;
            
            /*
            var stats:Stats = new Stats();
            stats.x = -80;
            addChild(stats);
            */
            
            super( _imageWidth,_imageHeight, false, true, CameraType.TARGET );
            Mouse3D.enabled = true;
            
            init();
            
            loader(setCanvas).load(new URLRequest("http://assets.wonderfl.net/images/related_images/0/0f/0f55/0f55917fef21710db05932fa8a2e0c2d6a85fecf"), new LoaderContext(true));
        }
        
        private function init():void
        {
            _canvas = new BitmapData( _imageWidth, _imageHeight, true, 0x00000000 );
            
            _paint = new Paint( _canvas, _imageWidth, _imageHeight );            
            addChild(_paint);
            _paint.init();
            
            _plane = new Plane( new WireframeMaterial(0x00FF00,1), _imageWidth, _imageHeight, Math.floor( _imageWidth / 20 ), Math.floor( _imageHeight / 20 ) );
            
            _vertices = _plane.geometry.vertices;
            for (var i:int = 0; i < _vertices.length; i++) 
            {
                _baseVertices.push(new Vertex3D(_plane.geometry.vertices[i].x,_plane.geometry.vertices[i].y,_plane.geometry.vertices[i].z));
                _poweredVertices.push(new Vertex3D(_plane.geometry.vertices[i].x,_plane.geometry.vertices[i].y,_plane.geometry.vertices[i].z));
                _energies.push(new Vertex3D(0, 0, 0));
                _forces.push(0);
            }
            
            scene.addChild( _plane );
            
            var loadButton:PushButton = new PushButton(this, stage.stageWidth - 100, 0, "Load Image", function():void {
                fileRefelence( loader(setCanvas).loadBytes ).browse();
            });
            
            var saveMapDataButton:PushButton = new PushButton(this, stage.stageWidth - 100, 20, "Save Map Data", function():void {
                var encoder:PNGEncoder = new PNGEncoder();
                var bytes:ByteArray = encoder.encode(_canvas);
                var fileReference:FileReference = new FileReference();
                fileReference.save(bytes, "map" + new Date().valueOf() +".png");
            });
            
            _loadMapDataButton = new PushButton(this, stage.stageWidth - 100, 40, "Load Map Data", function():void {
                fileRefelence( loader(setMapData).loadBytes ).browse();
            });
            
            var targetPos:DisplayObject3D = new DisplayObject3D();
            targetPos.copyTransform( _plane );
            targetPos.moveBackward( camera.focus * camera.zoom * this.scaleX );

            camera.x = targetPos.x;
            camera.y = targetPos.y;
            camera.z = targetPos.z;

            _draw2dButton = new PushButton( this, 0, stage.stageHeight - 20, "Draw2D", draw2d );
            _make3dButton = new PushButton( this, 0, stage.stageHeight - 20, "Make3D", make3d );
            
            _heightSlider = new HUISlider( this, stage.stageHeight / 2, stage.stageHeight - 20, "Height", heightSlideHandler );
            _heightSlider.value = 20;
            pheight = .2;
            
            _hitArea = new Sprite();
            _hitArea.graphics.beginFill( 0x0, 0 );
            _hitArea.graphics.drawRect( 0, 0, stage.stageWidth,stage.stageHeight );
            _hitArea.graphics.endFill();
            addChildAt(_hitArea, getChildIndex(viewport) + 1);
            
            startRendering();
            startRenderingVercities();
            
            draw2d();
            
        }
        
        private function fileRefelence( func:Function ):FileReference {
            var f:FileReference = new FileReference();
            f.addEventListener(Event.SELECT, function(e:Event):void {
                f.addEventListener(Event.COMPLETE, function(e:Event):void {
                    func(f.data);
                });
                f.load();
            });
            return f;
        }
        
        private function startRenderingVercities():void
        {
            // 各マウスイベント
            _hitArea.addEventListener(MouseEvent.MOUSE_DOWN, amouseDownHandler);
            _hitArea.addEventListener(MouseEvent.MOUSE_MOVE, amouseMoveHandler);
            _hitArea.addEventListener(MouseEvent.MOUSE_UP, amouseUpHandler);
            stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
            
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, kayUpHandler);
        }
        
        private var _ctrlKey:Boolean;
        
        private function keyDownHandler(e:KeyboardEvent):void
        {
            if ( e.keyCode == 17 ) _ctrlKey = true;
        }
        
        private function kayUpHandler(e:KeyboardEvent):void
        {
            if ( e.keyCode == 17 ) _ctrlKey = false;
        }
        
        /**
         * 頂点に力をかける (詳しくは本を見てください)
         *
         * @param power かける力
         * @param vertices 力をかける頂点
         */
        private function addPower(power:Rectangle, vertices:Array, _forces:Array):void
        {
            // 力の開始点
            var px:Number = power.x;
            var py:Number = power.y;
            // 力のベクトル (矢印)
            var vx:Number = power.width;
            var vy:Number = power.height;
            
            // 力のベクトルの長さ
            var vl:Number = Math.sqrt(vx * vx + vy * vy);
            // 正規化された力のベクトル
            var nvx:Number = vl != 0 ? vx / vl : 0;
            var nvy:Number = vl != 0 ? vy / vl : 0;
            
            // 各頂点について
            for (var i:uint = 0; i < _vertices.length; ++i) {
                // 頂点を取り出す
                var baseX:Number = _vertices[i].x;
                var baseY:Number = _vertices[i].y;
                
                // 力の開始点から頂点までの距離ベクトル
                var dx:Number = baseX - px;
                var dy:Number = baseY - py;
                var d:Number = dx * dx + dy * dy;
                // 力の開始点から頂点までの距離ベクトルの長さ
                var dl:Number = Math.sqrt(d);
                // 正規化された力の開始点から頂点までの距離ベクトル
                var ndx:Number = dl != 0 ? dx / dl : 0;
                var ndy:Number = dl != 0 ? dy / dl : 0;
                
                // 力のベクトルと力の開始点から頂点までの距離ベクトルとの角度
                var t:Number = Math.atan2(nvx * ndy - nvy * ndx, nvx * ndx + nvy * ndy);
                // 0度のとき 1.0 〜 45度の時 0.0 になる係数
                var f:Number = 1.0 - Math.abs(t) / (Math.PI / 4);
                if (f < 0) {
                    f = 0;
                }
                
                // 影響範囲の長さ
                var l:Number = 120.0 * (1.0 + f * 1.2);
                
                // 力の開始点から頂点までの距離が影響範囲内であれば 1.0 に近づく係数
                var factor:Number = 1.0 - d / (l * l);
                if (factor < 0) {
                    factor = 0;
                }
                
                // 力と係数を掛け合わせて頂点の座標に足して移動させる
                //_vertices[i].x = baseX + vx * factor;
                _vertices[i].x = baseX + vx * _forces[i] * factor;
                //_vertices[i].y = baseY + vy * factor;
                _vertices[i].y = baseY + vy * _forces[i] * factor;
            }
        }
        
        /**
         * 各頂点にかかる力を計算する (詳しくは本を見てください)
         */
        private function calcEnergy():void
        {
            for (var i:uint = 0; i < _vertices.length; ++i) {
                _energies[i].x = (_energies[i].x + (_poweredVertices[i].x - _vertices[i].x)) * 0.4;
                _energies[i].y = (_energies[i].y + (_poweredVertices[i].y - _vertices[i].y)) * 0.4;
                
                _vertices[i].x += _energies[i].x;
                _vertices[i].y += _energies[i].y;
            }
        }
        
        /**
         * ENTER_FRAME でレンダリング (詳しくは本を見てください)
         */
        private function enterFrameHandler(e:Event):void
        {
            // 頂点データを元に戻す
            for (var i:uint = 0; i < _vertices.length; ++i) {
                _poweredVertices[i].x = _poweredVertices[i].x;
                _poweredVertices[i].y = _poweredVertices[i].y;                
            }
                        
            // 力があればかける
            if (_power != null) {
                addPower(_power, _poweredVertices, _forces);
            }
            
            // 慣性の計算
            calcEnergy();
            
            //_plane.yaw(1);
        }
        
        /**
         * マウス押し下げイベント
         */
        private function amouseDownHandler(e:MouseEvent):void
        {
            if (!_ctrlKey) return;
            if (_power == null) {
                _power = new Rectangle();                
                _power.x = viewport.interactiveSceneManager.mouse3D.x;
                _power.y = viewport.interactiveSceneManager.mouse3D.y;
            }
        }
        
        /**
         * マウス移動イベント
         */
        private function amouseMoveHandler(e:MouseEvent):void
        {
            if (!_ctrlKey) return;
            if (_power != null) {
                _power.width = (viewport.interactiveSceneManager.mouse3D.x - _power.x) / 1.5;
                _power.height = (viewport.interactiveSceneManager.mouse3D.y - _power.y) / 1.5;
            }
        }
        
        /**
         * マウス押し上げイベント
         */
        private function amouseUpHandler(e:MouseEvent):void
        {
            if (_power != null) {
                _power = null;
            }
        }
        
        /**
         * マウスステージ外イベント
         */
        private function mouseLeaveHandler(e:Event):void
        {
            mouseUpHandler(null);
        }
        
        private var pheight:Number = 0;
        private var pointArray:Array = [];
        
        private function heightSlideHandler( e:Event ):void
        {
            pheight = e.target.value / 100;
            updateVertices();
        }
        
        private function updateVertices():void
        {
            for ( var i:int = 0; i < pointArray.length; i++ ) 
            {
                _plane.geometry.vertices[i].z = pointArray[i] * pheight;
            }
        }
        
        private var _lastRotationX:Number = 0;
        private var _lastRotationY:Number = 0;
        
        private function draw2d( e:Event = null ):void
        {
            addChildAt(_paint, getChildIndex(viewport) + 2);
            _make3dButton.visible = true;
            _draw2dButton.visible = false;
            _heightSlider.visible = false;
            _loadMapDataButton.visible = true;
            
            for ( var i:int = 0; i < pointArray.length; i++ ) 
            {
                _plane.geometry.vertices[i].z = 0;
            }
            
            _lastRotationX = _plane.rotationX;
            _lastRotationY = _plane.rotationY;
            
            _plane.rotationX = 0;
            _plane.rotationY = 0;
            
            _hitArea.removeEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
            
            removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        
        private function make3d( e:Event ):void
        {
            _plane.rotationX = _lastRotationX;
            _plane.rotationY = _lastRotationY;
            
            removeChild( _paint );
            _make3dButton.visible = false;
            _draw2dButton.visible = true;
            _heightSlider.visible = true;
            _loadMapDataButton.visible = false;
            
            var pcanvas:BitmapData = new BitmapData( _imageWidth, _imageHeight, false, 0x000000 );
            pcanvas.draw( _canvas );
            
            var s:int = 0;
            
            for ( var i:int = 0; i <= _plane.segmentsW; i++ ) 
            {
                for ( var j:int = _plane.segmentsH; j >= 0; j-- ) 
                {
                    var xp:int = _imageWidth * ( i / _plane.segmentsW );
                    xp = xp < _imageWidth ? xp : _imageWidth -1;
                    var yp:int = _imageHeight * ( j / _plane.segmentsH );
                    yp = yp < _imageHeight ? yp : _imageHeight -1;
                    pointArray[s] = - ( pcanvas.getPixel( xp, yp ) >> 16);
                    _forces[s] = -pointArray[s] / 100;
                    s++;
                }
            }
            
            updateVertices();
            
            _hitArea.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
            stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
            
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        
        private function loader(func:Function):Loader {
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void { func(loader); } );
            return loader;
        }
        
        private function setCanvas(loader:Loader):void {
                
            var image:BitmapData = Bitmap(loader.content).bitmapData;
            var bmd:BitmapData = new BitmapData(_imageWidth, _imageHeight, true, 0x0);
            var matrix:Matrix = new Matrix();
            
            var rate:Number = image.width / image.height;
            var scale:Number;
            if ( rate > 1 ) {
                scale = _imageWidth / image.width;
                matrix.translate(0, (_imageWidth - (scale * image.height)) / 2);
            }
            else if ( rate < 1 ) {
                scale = _imageHeight / image.height;
                matrix.translate((_imageWidth - (scale * image.width)) / 2, 0);
            }
            else if ( rate == 1 ) {
                scale = _imageWidth / image.width;
            }
            
            matrix.scale(scale, scale);
            bmd.draw( image, matrix);
            image.dispose();
            image = null;
            
            if (_material != null) _material.destroy();
            _material = new BitmapMaterial( bmd );
            _plane.material = _material;
            _material.interactive = true;
            _material.doubleSided = true;
            
            loader.unload();
            
        }
        
        private function setMapData(loader:Loader):void {
            var bmd:Bitmap = Bitmap(loader.content);
            _canvas.copyPixels( bmd.bitmapData, new Rectangle(0, 0, _imageWidth, _imageHeight), new Point() );
            bmd.bitmapData.dispose();
            bmd = null;
            loader.unload();
        }
        
        private function mouseDownHandler( e:Event ):void
        {
            if (_ctrlKey) return;
            curX = mouseX;
            curY = mouseY;
            addEventListener( MouseEvent.MOUSE_MOVE, mouseMoveHandler );
        }
        
        private function mouseUpHandler( e:MouseEvent ):void
        {
            removeEventListener( MouseEvent.MOUSE_MOVE, mouseMoveHandler );
        }
        
        private var curX:Number = 0;
        private var curY:Number = 0;
        
        private function mouseMoveHandler( e:MouseEvent ):void 
        {
            _plane.rotationY += ( curX - mouseX );
            _plane.rotationX -= ( curY - mouseY );
            
            curX = mouseX;
            curY = mouseY;
        }
    }
}





import com.bit101.components.*;
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;

class Paint extends Sprite
{
    
    private var _brush:Brush;
    private var _pointer:Pointer;
    private var _drawField:Sprite;
    private var _background:Bitmap;
    private var _canvas:BitmapData;
    private var _imageHeight:Number;
    private var _imageWidth:Number;
    private var _blurButton:PushButton;
    
    public function Paint( canvas:BitmapData, imageWidth:Number, imageHeight:Number )
    {
        _canvas = canvas;
        _imageWidth = imageWidth;
        _imageHeight = imageHeight;
    }

    public function init():void
    {
        
        var hitArea:Sprite = new Sprite();
        hitArea.graphics.beginFill( 0x0, 0 );
        hitArea.graphics.drawRect( 0, 0, _imageWidth, _imageHeight );
        hitArea.graphics.endFill();
        addChild( hitArea );
        hitArea.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
        stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
        
        this.x = stage.stageWidth - _imageWidth >> 1;
        this.y = stage.stageHeight - _imageHeight >> 1;
        
        _brush = new Brush( 50, 0xFF0000, .5 );
        
        _drawField = new Sprite();
        addChild( _drawField );
        
        var bitmap:Bitmap = new Bitmap(_canvas);
        addChild(bitmap)
        
        _pointer = new Pointer( _brush.thickness );
        addChild( _pointer );
        hitArea.addEventListener( MouseEvent.MOUSE_MOVE, drawPointer);
        
        _blurButton = new PushButton( this, 0, 0, "Blur", blurBitmapData );
        
        var clearButton:PushButton = new PushButton( this, 150, 0, "Clear", clearHandler );
        
        var thicknessSlider:HUISlider = new HUISlider( this, 0, 30, "Thickness", thicknessSliderHandler );
        thicknessSlider.value = 50;
        
        var alphaSlider:HUISlider = new HUISlider( this, 0, 50, "Alpha", alphaSlider );
        alphaSlider.value = 50;
        
    }
    
    private function clearHandler( e:Event ):void
    {
        _canvas.fillRect( _canvas.rect, 0x0 );
    }
    
    private function alphaSlider( e:Event ):void
    {
        _brush.alpha = e.target.value/100;
    }
    
    private function thicknessSliderHandler( e:Event ):void
    {
        _brush.thickness = _pointer.thickness =  e.target.value;
        _pointer.update();
    }
    
    private function blurBitmapData( e:Event ):void
    {
        _canvas.applyFilter(_canvas, _canvas.rect, new Point, new BlurFilter( 32, 32, 4 ));
    }
    
    private function drawPointer(e:Event):void
    {
        _pointer.x = mouseX;
        _pointer.y = mouseY;
        if ( mouseX < 0 || mouseX > _imageWidth || mouseY < 0 || mouseY > _imageHeight ) {
            _pointer.visible = false;
        }
        else {
            _pointer.visible = true;
        }
    }
    
    private function mouseDownHandler( e:MouseEvent ):void
    {
        _pointer.alpha = 0;
        _drawField.graphics.lineStyle( _brush.thickness, _brush.color, _brush.alpha );
        _drawField.graphics.moveTo( mouseX, mouseY + .2 );
        _drawField.graphics.lineTo( mouseX, mouseY );
        _drawField.addEventListener( Event.ENTER_FRAME, drawingHandler );
    }
    
    private function mouseUpHandler( e:MouseEvent ):void
    {
        _pointer.alpha = 1;
        _drawField.graphics.endFill();
        _canvas.draw( _drawField );
        _drawField.graphics.clear();
        _drawField.removeEventListener(Event.ENTER_FRAME, drawingHandler );
    }
    
    private function drawingHandler( e:Event ):void
    {
        _drawField.graphics.lineTo( mouseX, mouseY );
    }
    
}



import flash.display.Shape;

class Pointer extends Shape
{
    public var thickness:uint = 1;
    
    public function Pointer( thickness:uint = 10 )
    {
        this.thickness = thickness;
        this.blendMode = BlendMode.INVERT;
        update();
    }
    
    public function update():void
    {
        graphics.clear();
        
        graphics.lineStyle( 1, 0x000000, .5, false) 
        graphics.drawCircle( 0, 0, thickness/2 );
        graphics.endFill();
    }
    
}



class Brush 
{
    public var thickness:uint = 1;
    public var color:uint = 0x000000;
    public var alpha:Number = alpha;
    
    public function Brush( thickness:uint = 10, color:uint = 0xFF0000, alpha:Number = 1 )
    {
        this.thickness = thickness;
        this.color = color;
        this.alpha = alpha;
    }
    
}