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

WaveSilk

ざっくりと.
Get Adobe Flash player
by matacat 28 Jan 2011
  • Related works: 4
  • Talk

    matacat at 28 Jan 2011 05:41
    参考サイトを見て考えたことは, ・マウスで引いた線が, 風に流される.  ⇒マウスの軌跡を配列に保存して, 描画のたびに風速を加算する. ・線が残像を描く. しかも線が重なると白っぽくなる.  ⇒BitmapDataインスタンスにdraw(). BlendMode.ADDで. ・線が虹色. だんだん暗くなる.  ⇒HSV色空間を使って, 色相をずらしたり, 輝度を下げたりする.   frocessing.color.ColorHSVが便利. あとは, マウスイベントは適当に間引いたほうが良いだろうなとか, 曲線のほうがきれいだろうなとか, フレーム間を補完するとより布っぽさが出るだろうなとか. 気の向くままに書いたので, 説明には向いてないコードになりました. パーティクル(きらきら光る粒)や, キー操作は実装してません.

    Tags

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

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import frocessing.color.ColorHSV;
    
    public class WaveSilkBasic extends Sprite
    {
        private const WIND_H:Number = 20;
        private const WIND_V:Number = 4;
        private const THICK:Number  = 2;
        private const INTER:int     = 30;
        private const ALPHA:Number  = 0.05;
        private const THIN:int      = 4;
        
        private var silk:BitmapData     = new BitmapData(465, 465, false, 0x000000);
        private var line:Shape          = new Shape();
        private var cmd:Vector.<int>    = new Vector.<int>();
        private var dat:Vector.<Number> = new Vector.<Number>();
        private var pts:Vector.<Number> = new Vector.<Number>();
        private var to:Vector.<Number>  = new Vector.<Number>();
        private var hsv:ColorHSV        = new ColorHSV(0, 0.5, 1);
        private var num:int;
        private var cnt:int;
        
        public function WaveSilkBasic()
        {
            addChild(new Bitmap(silk));
            addChild(line);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        }
        
        private function resetParams():void
        {
            removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            line.graphics.clear();
            line.visible = true;
            cmd.length   = 0;
            dat.length   = 0;
            pts.length   = 0;
            to.length    = 0;
            hsv.h        = 360 * Math.random();
            hsv.v        = 1;
            num          = 2;
            cnt          = 0;
        }
        
        private function onMouseDown(e:MouseEvent):void
        {
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            
            resetParams();
            
            pts[0] = e.stageX;
            pts[1] = e.stageY;
            cmd[0] = 1;
            cmd[1] = 3;
            line.graphics.lineStyle(THICK, hsv.value);
            line.graphics.moveTo(e.stageX, e.stageY);
        }
        
        private function onMouseMove(e:MouseEvent):void
        {
            cnt = (cnt + 1) % THIN;
            if (cnt == 0) {
                pts[num++]  = e.stageX;
                pts[num++]  = e.stageY;
                cmd[num>>1] = 3;
                line.graphics.lineTo(e.stageX, e.stageY);
            }
        }
        
        private function onMouseUp(e:MouseEvent):void
        {
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            line.visible = false;
            if (num > 2) {
                dat.length = to.length = (num << 1) + 2;
                addEventListener(Event.ENTER_FRAME, onEnterFrame);
            }
        }
        
        private function onEnterFrame(e:Event):void
        {
            silk.lock();
            
            var tx:Number = pts[0];
            var ty:Number = pts[1];
            dat[0] = dat[2] = tx;
            dat[1] = dat[3] = ty;
            to[0]  = to[2]  = tx + Math.random() * WIND_H;
            to[1]  = to[3]  = ty + Math.random() * WIND_V;
            pts[0] = to[0];
            pts[1] = to[1];
            
            var i:int, j:int, k:int;
            for (i = 2; i < num; i += 2) {
                j  = (i << 1) + 2;
                tx = pts[i];
                ty = pts[i+1>>0];
                dat[j]      = tx;
                dat[j+1>>0] = ty;
                to[j]       = tx + Math.random() * WIND_H;
                to[j+1>>0]  = ty + Math.random() * WIND_V;
                dat[j-2>>0] = (tx + dat[j-4>>0]) / 2;
                dat[j-1>>0] = (ty + dat[j-3>>0]) / 2;
                tx = to[j];
                ty = to[j+1>>0];
                to[j-2>>0]  = (tx + to[j-4>>0]) / 2;
                to[j-1>>0]  = (ty + to[j-3>>0]) / 2;
                pts[i]      = tx;
                pts[i+1>>0] = ty;
            }
            k = dat.length;
            dat[k-2>>0] = dat[k-4>>0];
            dat[k-1>>0] = dat[k-3>>0];
            to[k-2>>0]  = to[k-4>>0];
            to[k-1>>0]  = to[k-3>>0];
            
            for (i = 0; i < INTER; i++) {
                line.graphics.clear();
                line.graphics.lineStyle(THICK, hsv.value, ALPHA);
                line.graphics.drawPath(cmd, dat);
                silk.draw(line, null, null, BlendMode.ADD);
                for (j = 0; j < k; j++) {
                    dat[j] = dat[j] + (to[j] - dat[j]) / (INTER - i);
                }
                hsv.h += 0.5;
            }
            
            hsv.v -= 0.02;
            
            if (hsv.v <= 0) {
                removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            }
            
            silk.unlock();
        }
    }
}