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

IK Test(Sliver Chain)

もう腐るほどIKはWonderflに溢れてますが。。。
IKのテストを兼ねて、銀の鎖です。メタルです。
ポイントはIKではなく、鎖の質感。ちょっとは鎖に見えると幸いです。
元ネタは昔みたPhotoShopのテクスチャ本です。角度によって、ちょっとだけ陰影の付き方が変わるよ!

深度管理がオカシイのはご愛嬌ってことでw

#9/17 深度のオカシイところを修正。ちゃんと先頭が上にくるよ!
/**
 * Copyright motikawa_rgm ( http://wonderfl.net/user/motikawa_rgm )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9CU7
 */

package  
{
    import flash.display.*;
    import flash.events.Event;
    import flash.geom.Point;
    import flash.filters.DropShadowFilter;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import jp.progression.commands.lists.LoaderList;
    import jp.progression.commands.net.LoadBitmapData;
    import jp.progression.events.ExecuteEvent;
    import net.hires.debug.Stats;
    import flash.system.Security;
    /**
     * 
     * @Author motikawa / t.okazaki
     */
    [SWF(width = 465, height = 465, backgroundColor = 0xffffff, frameRate = 60)]
    public class Main extends Sprite
    {
        private static const CHAIN_NUM:int = 201;
        private var _chains:Vector.<IKChain>;
        private var _container:Sprite;
        public function Main() 
        {
            _init();
        }
        private function _init():void
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            var llist:LoaderList = new LoaderList();
            llist.addCommand(new LoadBitmapData(new URLRequest("http://assets.wonderfl.net/images/related_images/4/44/4414/441464e04ce95146813dbe1d1cce43f6e8764828"), { context:new LoaderContext(true) } ));
            llist.addCommand(new LoadBitmapData(new URLRequest("http://assets.wonderfl.net/images/related_images/5/57/57e8/57e8d4f9a43047ff3636c836c072eea10b359446"), { context:new LoaderContext(true) } ));
            llist.addEventListener(ExecuteEvent.EXECUTE_COMPLETE, _onComplete);
            llist.execute();
            
        }
        
        private function _onComplete(e:Event):void
        {
            var llist:LoaderList = e.target as LoaderList;
                
            IKChain.center = new Point(stage.stageWidth * .5, stage.stageHeight * .5);
            Chain.initialize(llist.latestData[1], llist.latestData[0]);
            
            _chains = new Vector.<IKChain>(CHAIN_NUM, true);
            addChildAt(_container = new Sprite(), 0);
            addChild(new Stats());
            
            var c:IKChain,
                i:int = 0,
                len:int = CHAIN_NUM -1;
            //2010/09/17 深度の変更方法を追加
            for (i = 0 ; i < CHAIN_NUM; i++) _chains[i] = _container.addChildAt(new IKChain(i % 2), 0) as IKChain;
            //深度の変更
            for ( i = 1 ; i < CHAIN_NUM - 1; i += 2) _container.setChildIndex(_chains[i], _container.getChildIndex(_chains[i -1]));
            
            _container.filters = [new DropShadowFilter(4, 45, 0x0, .6, 4, 4, 1)];
            addEventListener(Event.ENTER_FRAME, _loop);
        }
        private function _loop(e:Event):void
        {
            var i:int = 0, len:int = _chains.length, c:IKChain;
            
            (_chains[0] as IKChain).dragTo(stage.mouseX, stage.mouseY);
            
            for (i = 1; i < len; i++)
            {
                c = _chains[i];
                c.dragToTarget(_chains[i - 1]);
            }
        }
    }
}
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
import flash.utils.ByteArray;
class Chain extends Bitmap
{
    private namespace type1 = "type1";
    private namespace type2 = "type2";
    private static const BLUR:BlurFilter = new BlurFilter(8, 8, 2);
    private static const OVERLAY_COLOR:uint = 0xcccccc;
    private static const ZERO_POS:Point = new Point();
    
    type1 static var _bytes:Vector.<ByteArray>;
    type2 static var _bytes:Vector.<ByteArray>;
    type1 static var _rect:Rectangle;
    type2 static var _rect:Rectangle;
    public static function initialize(bmd1:BitmapData,bmd2:BitmapData):void
    {
        type1::_bytes = new Vector.<ByteArray>(360, true);
        type2::_bytes = new Vector.<ByteArray>(360, true);
        type1::_rect = new Rectangle(0, 0, bmd1.width, bmd1.height);
        type2::_rect = new Rectangle(0, 0, bmd2.width, bmd2.height);
        
        var overlay:BitmapData = new BitmapData(1, 1, false, OVERLAY_COLOR),
            bevel:BevelFilter = new BevelFilter(2, 0, 0xffffff, 1, 0x444444, 1, 2, 2, 4, 1),
            i:int = 0 , len:int = 360;
        for (i = 0 ; i < len ; i++)
        {
            bevel.angle = i;
            type1::_bytes[i] = _makeChain(bevel, bmd1, overlay);
            type2::_bytes[i] = _makeChain(bevel, bmd2, overlay);
        }
    }
    private static function _makeChain(bevelFilter:BevelFilter,base:BitmapData,overlay:BitmapData):ByteArray
    {
        var bmd:BitmapData = base.clone(),
            mt:Matrix = new Matrix(base.width, 0, 0, base.height),
            newBmd:BitmapData = new BitmapData(base.width, base.height, true, 0x0);
        bmd.applyFilter(bmd, bmd.rect, ZERO_POS, BLUR);
        bmd.applyFilter(bmd, bmd.rect, ZERO_POS, bevelFilter);
        bmd.draw(overlay, mt, null, BlendMode.OVERLAY);
        newBmd.copyPixels(bmd, bmd.rect, ZERO_POS, base);
        return newBmd.getPixels(newBmd.rect);
    }
    
    private var _angle:Number;
    private var _ns:Namespace;
    public function Chain(type:uint)
    {
        if (type == 1) _ns = type1;
        else _ns = type2;
        
        super(new BitmapData(_ns::_rect.width, _ns::_rect.height, true, 0x0) , "auto", true);
        bevelAngle = 0;
    }
    public function get bevelAngle():int { return _angle; }
    public function set bevelAngle(value:int):void
    {
        if (_angle == value) return;
        while (value >= 360) value -= 360;
        while (value <  0  ) value += 360;
        _angle = int(value);
        _ns::_bytes[_angle].position = 0;
        bitmapData.setPixels(bitmapData.rect, _ns::_bytes[_angle]);
    }
}

class IKChain extends Sprite
{
    public static var center:Point;
    public static const RADIAN:Number = Math.PI / 180;
    private var _length:Number;
    private var _chain:Chain;
    public function IKChain(type:uint)
    {
        addChildAt(_chain = new Chain(type), 0);
        _chain.smoothing = true;
        _chain.scaleX = _chain.scaleY = .3;
        _length = width * .5;
        _chain.y -= _chain.height * .5;
    }
    public function dragTo(xpos:Number, ypos:Number):void
    {
        var dx:Number = xpos - x,
            dy:Number = ypos - y,
            rad:Number = Math.atan2(dy, dx),
            degree:Number = rad / RADIAN;
        rotation = degree;
        x = xpos - Math.cos(rad) * _length;
        y = ypos - Math.sin(rad) * _length;
        _updateAngle();
    }
    public function dragToTarget(chain:IKChain):void
    {
        var dx:Number = chain.x - x,
            dy:Number = chain.y - y,
            rad:Number = Math.atan2(dy, dx),
            degree:Number = rad / RADIAN;
        rotation = degree;
        x = chain.x - Math.cos(rad) * _length;
        y = chain.y - Math.sin(rad) * _length;
        _updateAngle();
    }
    private function _updateAngle():void
    {
        if (center)    _chain.bevelAngle = Math.atan2(center.y - y , center.x - x) / RADIAN  - 90;
    }
}