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: 文字にモザイクをかけるよ!

なんやかんやしてやっとできますた。
ソースコードコピペして全部選択でスクロールとかちょっと楽しいかも。
コンテキストメニューでの操作には対応してません。というかできませんでした。
Event.CUT とか Event.SELECT_ALL じゃないのかなぁ…
/**
 * Copyright matacat ( http://wonderfl.net/user/matacat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/8WiZ
 */

// forked from cuegraphix's 文字にモザイクをかけるよ!

// なんやかんやしてやっとできますた。
// ソースコードコピペして全部選択でスクロールとかちょっと楽しいかも。
// コンテキストメニューでの操作には対応してません。というかできませんでした。
// Event.CUT とか Event.SELECT_ALL じゃないのかなぁ…

package
{
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFieldType;
    import flash.text.TextFormat;
    
    public class MosaicTF extends Sprite
    {
        public static const MOSAIC_SIZE:uint = 5;
        
        private var tf:TextField;
        private var tfDummy:TextField;
        private var tfBmp:BitmapData;
        private var mosaic:Bitmap;
        
        private var fr:Function;
        private var tfRect:Rectangle;
        private var pixRect:Rectangle;
        private var isStillSelecting:Boolean;
        
        public function MosaicTF():void
        {
            var wz:int = stage.stageWidth  - 20;
            var hi:int = stage.stageHeight - 40;
            
            var fm:TextFormat = new TextFormat("Verdana", 24);
            
            tf                   = new TextField();
            tf.type              = TextFieldType.INPUT;
            tf.border            = true;
            tf.background        = true;
            tf.backgroundColor   = 0x869CA7;
            tf.multiline         = true;
            tf.defaultTextFormat = fm;
            tf.text              = "文字を選択すると\nモザイクをかけるよ!";
            tf.x                 = 10;
            tf.y                 = 10;
            tf.width             = wz;
            tf.height            = hi;
            addChild(tf);
            
            tf.addEventListener   (MouseEvent.MOUSE_DOWN,  whatsDown);
            tf.addEventListener   (KeyboardEvent.KEY_DOWN, whatsDown);
            tf.addEventListener   (Event.SCROLL,           whatsUp);
            stage.addEventListener(MouseEvent.MOUSE_UP,    whatsUp);
            tf.addEventListener   (KeyboardEvent.KEY_UP,   whatsUp);
            
            tfDummy                   = new TextField();
            tfDummy.type              = TextFieldType.DYNAMIC;
            tfDummy.border            = false;
            tfDummy.background        = true;
            tfDummy.backgroundColor   = tf.backgroundColor;
            tfDummy.multiline         = tf.multiline;
            tfDummy.defaultTextFormat = tf.defaultTextFormat;
            tfDummy.text              = tf.text;
            tfDummy.x                 = 0;
            tfDummy.y                 = 0;
            tfDummy.width             = wz;
            tfDummy.height            = hi;
            
            tfBmp = new BitmapData(wz, hi, false);
            
            mosaic   = new Bitmap( new BitmapData(wz, hi, true, 0) );
            mosaic.x = tf.x;
            mosaic.y = tf.y;
            addChild(mosaic);
            
            fr               = mosaic.bitmapData.fillRect;
            tfRect           = new Rectangle(2, 2, wz - 4, hi - 4);
            pixRect          = new Rectangle(0, 0, MOSAIC_SIZE, MOSAIC_SIZE);
            isStillSelecting = false;
            
            var btn:Sprite      = new Sprite();
            var btnlb:TextField = new TextField();
            
            btnlb.autoSize = TextFieldAutoSize.CENTER;
            btnlb.text     = "語包切替";
            
            btn.graphics.lineStyle(2, 0x7F7F7F);
            btn.graphics.beginFill(0xCFCFCF);
            btn.graphics.drawRect(0, 0, btnlb.width + 10, btnlb.height);
            btn.buttonMode    = true;
            btn.mouseChildren = false;
            
            btnlb.x = btn.width - btnlb.width >> 1;
            btn.addChild(btnlb);
            btn.x = tf.x;
            btn.y = tf.y + hi + 5;
            addChild(btn);
            
            btn.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void
            {
                if (tf.wordWrap = tfDummy.wordWrap = !tf.wordWrap) btnlb.text = "クレラップ";
                else                                               btnlb.text = "サンホイル";
            });
            
            stage.focus = tf;
            tf.setSelection( 9, 13 );
        }
        
        
        private function whatsDown(e:Event):void
        {
            mosaic.visible   = false;
            isStillSelecting = true;
        }
        
        
        private function whatsUp(e:Event = null):void
        {
            var prevBgn:int;
            var prevEnd:int;
            
            if (e is KeyboardEvent) {
                if (KeyboardEvent(e).shiftKey) return;
                else isStillSelecting = false;
            } else if (e is MouseEvent) isStillSelecting = false;
            
            if (isStillSelecting || tf.selectionBeginIndex == tf.selectionEndIndex) return;
            
            if (e.type == Event.SCROLL) {
                mosaic.visible = false;
                if (drawMos()) mosaic.visible = true;
            } else if (prevBgn != tf.selectionBeginIndex || prevEnd != tf.selectionEndIndex) {
                drawMos();
                mosaic.visible = true;
            }
            
        }
        
        
        private function drawMos():Boolean
        {
            var cb:Function = tf.getCharBoundaries;
            var li:Function = tf.getLineIndexOfChar;
            var lm:Function = tf.getLineMetrics;
            
            var bgnIdx:int  = tf.selectionBeginIndex;
            var endIdx:int  = tf.selectionEndIndex - 1;
            
            var topLine:int = tf.scrollV - 1;
            var btmLine:int = tf.bottomScrollV - 1;
            
            var curCrt:int;
            var endCrt:int;
            
            if (li(bgnIdx) < topLine) {
                if (li(endIdx) < topLine) return false;
                else curCrt  = tf.getLineOffset(topLine);
            } else   curCrt  = bgnIdx;
            
            if (li(endIdx) > btmLine) {
                if (li(bgnIdx) > btmLine) return false;
                else endCrt = tf.getLineOffset(btmLine + 1) - 1;
            } else   endCrt = endIdx;
            
            var hOfs:int = tf.scrollH;
            var vOfs:int = 0;
            for (var i:int = 0; i < topLine; i++) vOfs += lm(i).height;
            
            tfDummy.text    = tf.text + "\n";
            tfDummy.scrollH = tf.scrollH;
            tfDummy.scrollV = tf.scrollV;
            tfBmp.draw(tfDummy);
            fr(tfRect, 0);
            
            var headBds:Rectangle;
            var tailBds:Rectangle;
            var uniRect:Rectangle;
            var endLine:int = li(endCrt);
            
            loop:
            for (;;) {
                while (!( headBds = cb(curCrt) )) if (++curCrt > endCrt) break loop;
                
                i = li(curCrt);
                if (i == endLine) curCrt = endCrt;
                else {
                    while (li(++curCrt) == i);
                    curCrt--;
                }
                
                while (!( tailBds = cb(curCrt--) ));
                
                uniRect    = headBds.union(tailBds);
                uniRect.x -= hOfs;
                uniRect.y -= vOfs;
                pixelization(tfRect.intersection(uniRect));
                
                if (li(curCrt) == endLine) break loop;
                while (li(++curCrt) == i);
            }
            
            tf.scrollH = tfDummy.scrollH;
            return true;
        }
        
        private function pixelization(rect:Rectangle):void
        {
            if (rect.width == 0 || rect.height == 0) return;
            
            var interRect:Rectangle;
            
            for (var j:int = rect.top, l:int = rect.bottom; j < l; j += MOSAIC_SIZE) {
                for (var i:int = rect.left, k:int = rect.right; i < k; i += MOSAIC_SIZE) {
                    pixRect.x = i;
                    pixRect.y = j;
                    interRect = pixRect.intersection(rect);
                    if (interRect.width != 0 && interRect.height != 0) fr(interRect, avg());
                }
            }
            
            function avg():uint
            {
                var color:uint;
                var r:uint = 0;
                var g:uint = 0;
                var b:uint = 0;
                var c:int  = 0;
                
                for (var n:int = interRect.top, p:int = interRect.bottom; n < p; n++) {
                    for (var m:int = interRect.left, o:int = interRect.right; m < o; m++) {
                        color = tfBmp.getPixel(m, n);
                        r += color >> 16 & 0xFF;
                        g += color >>  8 & 0xFF;
                        b += color       & 0xFF;
                        c++;
                    }
                }
                
                return 0xFF << 24 | r / c << 16 | g / c << 8 | b / c << 0;
            }
        }
    }
}