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: Kaleidoscope

mouse right click or Ctrl + click and
from context menu, select or save your image.

Kaleidoscope
@author Test Dept
Get Adobe Flash player
by s8t1h12akj 26 Nov 2013
/**
 * Copyright s8t1h12akj ( http://wonderfl.net/user/s8t1h12akj )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/eTU8
 */

// forked from Test_Dept's Kaleidoscope
//
// mouse right click or Ctrl + click and
// from context menu, select or save your image.
//
package {

    import flash.display.Sprite;

    /**
     * Kaleidoscope
     * @author Test Dept
     */
    [SWF(backgroundColor="#000000", width="465", height="465")]
    public class Kaleidoscope extends Sprite {
        public function Kaleidoscope() {
            addChild(new KaleidoscopeImpl() );    
        }        
    }
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.ContextMenuEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Camera;
import flash.media.Video;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;

import mx.graphics.codec.PNGEncoder;

class KaleidoscopeImpl extends Sprite {

    private static const MAX_SIZE : int = 4096;

    private var _a : UIPoint;
    private var _b : UIPoint;
    private var _c : UIPoint;

    private var _bmp : BitmapData;

    private var _video : Video;

    private var _filename : String;

    private var _fileRef : FileReference;

    private var _markAlpha : Number;

    private var _idleCount : int;

    public function KaleidoscopeImpl() {
        addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    }
    
    private function addedToStageHandler(event : Event) : void {
        
        var width : Number = stage.stageWidth;
        var height : Number = stage.stageHeight;
        
        addChild(_a = new UIPoint(0x000000, 10, height / 2, "a", true) );
        addChild(_b = new UIPoint(0x000000, width - 10, height / 2 - 40, "b", true) );
        addChild(_c = new UIPoint(0x000000, width / 2, height / 2, "c", true) );

        _markAlpha = 0;
        _idleCount = 0;

        _bmp = new BitmapData(width, height, false, 0xffffff);
        _bmp.draw(new RandomImage(width, height) );
        _filename = "IMG.IMG";

        var camera : Camera = Camera.getCamera();
        if (camera != null) {
            camera.setMode(width, height, 16, true);
            _video = new Video(camera.width, camera.height);
            _video.attachCamera(camera);
        } else {
            _video = null;
        }
        
        contextMenu = new ContextMenu();
        contextMenu.hideBuiltInItems();
        contextMenu.customItems.push(createMenuItem("Select Source Image", contextMenu_loadHandler) );
        contextMenu.customItems.push(createMenuItem("Save Image", contextMenu_saveHandler) );

        addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
        addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }

    private function createMenuItem(label : String, handler : Function) : ContextMenuItem {
        var menuItem : ContextMenuItem = new ContextMenuItem(label);
        menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handler);
        return menuItem;
    }

    private function contextMenu_loadHandler(event : ContextMenuEvent) : void {
        _fileRef = new FileReference();
        _fileRef.browse([
            new FileFilter("Image Files", "*.jpg;*.png"),
            new FileFilter("All Files", "*.*"),
        ]);
        _fileRef.addEventListener(Event.SELECT, _fileRef_selectHandler);    
    }
    
    private function _fileRef_selectHandler(event : Event) : void {
        _filename = _fileRef.name;
        _fileRef.load();
        _fileRef.addEventListener(Event.COMPLETE, _fileRef_load_completeHandler);
    }

    private function _fileRef_load_completeHandler(event : Event) : void {
        var loader : Loader = new Loader();
        loader.loadBytes(_fileRef.data);
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, upload_completeHandler);
    }
    
    private function upload_completeHandler(event : Event) : void {
        var loaderInfo : LoaderInfo = event.target as LoaderInfo;
        var bitmap : Bitmap = loaderInfo.content as Bitmap;
        _bmp = bitmap.bitmapData;
        _video = null;
    }
    
    private function contextMenu_saveHandler(event : ContextMenuEvent) : void {

        var sp : Sprite = new Sprite();
        var g : Graphics = sp.graphics;
        g.clear();
        draw(g);

        var scale : Number = 1 / getScale();
        var rect : Rectangle = sp.getBounds(sp);
        
        if (rect.width * scale > MAX_SIZE) {
            scale = MAX_SIZE / rect.width;
        }
        if (rect.height * scale > MAX_SIZE) {
            scale = MAX_SIZE / rect.height;
        }
        
        var bmp : BitmapData = new BitmapData(
            Math.min(rect.width * scale, MAX_SIZE),
            Math.min(rect.height * scale, MAX_SIZE),
            true, 0);
        bmp.draw(sp, new Matrix(scale, 0, 0, scale, -rect.x * scale, -rect.y * scale) );

        var match : Object = /^(.+)\..+$/.exec(_filename);
        
        var newFilename : String = match[1] + "_" + new Date().getTime() + ".png";
        var encoder : PNGEncoder = new PNGEncoder();

        _fileRef = new FileReference();
        _fileRef.save(encoder.encode(bmp), newFilename);
    }

    private function enterFrameHandler(event : Event) : void {

        if (_idleCount > 0) {
            _idleCount--;
        } else {
            _markAlpha = Math.max(0, _markAlpha - 0.04);
        }

        _a.alpha = _markAlpha;
        _b.alpha = _markAlpha;
        _c.alpha = _markAlpha;

        if (_video != null) {
            _bmp.draw(_video, new Matrix(_video.scaleX, 0, 0, _video.scaleY) );
        }

        var g : Graphics = graphics;
        g.clear();
        g.lineStyle(1, 0x000000, _markAlpha);
        draw(g);
    }
    
    private function draw(g : Graphics) : void {

        var a : Point = new Point(_a.x, _a.y);
        var b : Point = new Point(_b.x, _b.y);
        var c : Point = new Point(_c.x, _c.y);

        var o : Point = GeoUtil.getCenter(a, b, c);
                
        var ref_c : Point = GeoUtil.getCRef(a, b, c);

        var p_bc : Point = GeoUtil.getCrossPoint(o, a, b, ref_c);
        var p_ac : Point = GeoUtil.getCrossPoint(o, b, a, ref_c);
        
        var new_c : Point;
        
        if (p_bc != null) {
            new_c = p_bc;    
        } else if (p_ac != null) {
            new_c = p_ac;    
        } else {
            new_c = ref_c;
        }

        var scale : Number = getScale();

        var ksImage : KaleidoscopeImage = new KaleidoscopeImage(
            _bmp.width * scale, _bmp.height * scale);
        g.beginBitmapFill(_bmp);
        ksImage.draw(g, o, a, b, c);
        g.endFill();
    }
    
    private function getScale() : Number {
        return (_bmp.width / _bmp.height > stage.stageWidth / stage.stageHeight)?
            stage.stageWidth / _bmp.width : stage.stageHeight / _bmp.height;            
    }
    
    private function mouseMoveHandler(event : Event) : void {
        _markAlpha = 0.5;
        _idleCount = 20;
    }
}

class KaleidoscopeImage {

    private var _width : Number;
    private var _height : Number;

    private var _maxNest : int;
    
    private var _o : Point;
    
    private var _vertices : Vector.<Number>;
    private var _indices : Vector.<int>;
    private var _uvtData : Vector.<Number>;
    
    public function KaleidoscopeImage(width : Number, height : Number, maxNest : int = 16) {
        _width = width;
        _height = height;
        _maxNest = maxNest;
    }

    public function draw(g : Graphics, o : Point, a : Point, b : Point, c : Point) : void {

        _o = o;
                    
        _vertices = new Vector.<Number>();
        _indices = new Vector.<int>();
        _uvtData = new Vector.<Number>();

         var t : Point = get_uvt(a);
         var u : Point = get_uvt(b);
         var v : Point = get_uvt(c);
        
        addTriangle(a, b, c, t, u, v);
                 
        reflect(a, b, c, t, u, v, 0);
        reflect(b, c, a, u, v, t, 0);
        reflect(c, a, b, v, t, u, 0);

        g.drawTriangles(_vertices, null, _uvtData);
    }
    
    private function reflect(
        a : Point, b : Point, c : Point,
        t : Point, u : Point, v : Point,
        nest : int
    ) : void {

        if (nest > _maxNest) {
            return;
        }

        if (!isVisible(a, b, c) ) {
            return;
        }

        var ref_c : Point = GeoUtil.getCRef(a, b, c);

        var c_bc : Point = GeoUtil.getCrossPoint(_o, a, b, ref_c);
        var c_ac : Point = GeoUtil.getCrossPoint(_o, b, a, ref_c);

        var new_c : Point;
        if (c_bc != null) {
            new_c = c_bc;
        } else if (c_ac != null) {
            new_c = c_ac;
        } else {
            new_c = ref_c;
        }

        var new_v : Point = GeoUtil.createTransformMatrix(a, b, ref_c, t, u, v)
            .transformPoint(new_c);
        
        addTriangle(a, b, new_c, t, u, new_v);

        if (c_bc == null) {
            reflect(new_c, a, b, new_v, t, u, nest + 1);
        }
        if (c_ac == null) {
            reflect(new_c, b, a, new_v, u, t, nest + 1);
        }
    }

    private function addTriangle(
        a : Point, b : Point, c : Point,
        t : Point, u : Point, v : Point
    ) : void {
        _vertices.push(a.x, a.y, b.x, b.y, c.x, c.y);
        _indices.push(0, 1, 2);
        _uvtData.push(t.x, t.y, u.x, u.y, v.x, v.y);
    }    
    
    private function get_uvt(p : Point) : Point {
        return new Point(p.x / _width, p.y / _height);        
    }
    
    private function isVisible(a : Point, b : Point, c : Point) : Boolean {

        var minX : Number = Math.min(a.x, b.x, c.x);
        var minY : Number = Math.min(a.y, b.y, c.y);
        var maxX : Number = Math.max(a.x, b.x, c.x);
        var maxY : Number = Math.max(a.y, b.y, c.y);
        
        var r1 : Rectangle = new Rectangle(
            0, 0, _width, _height);

        var r2 : Rectangle = new Rectangle(
            minX, minY, maxX - minX, maxY - minY);

        return r1.intersects(r2);
    }
}

class RandomImage extends Sprite {

    public function RandomImage(width : Number, height : Number) {

        var colors : Array = [
            0xff0000,
            0xffff00,
            0x00ff00,
            0x00ffff,
            0x0000ff,
            0xff00ff
        ];
        
//        var rand : Function = Math.random;
        var rand : Function = FakeRand.random;

        var g : Graphics = graphics;
        
        g.clear();
        
        for (var i : int = 0; i < 100; i++) {

            var x : Number = rand() * width;
            var y : Number = rand() * height;
            var r : Number = rand() * 50 + 10;
            var c : uint = colors[i % colors.length];

            g.beginFill(c, 0.4);
            g.drawCircle(x, y, r);
            g.endFill();
        }
    }
}

class FakeRand {

    private var _num : Number;
    private var _digits : int;
    
    public function FakeRand(seed : Number = 0, digits : int = 10000) {
        _num = Math.exp(seed);
        _digits = digits;
    }
    
    public function next() : Number {
        _num = _num * _digits + Math.PI;
        _num = _num - Math.floor(_num);
        return int(_num * _digits) % _digits / _digits;
    }
    
    private static var _instance : FakeRand = new FakeRand();
    
    public static function random() : Number {
        return _instance.next();
    }
}

class GeoUtil {

    public static function getCenter(
        a : Point, b : Point, c : Point
    ) : Point {

        var bc : Point = new Point(
            (b.x + c.x) / 2,
            (b.y + c.y) / 2);

        return new Point(
            a.x + (bc.x - a.x) * 2 / 3,
            a.y + (bc.y - a.y) * 2 / 3);        
    }

    public static function createMatrix(
        a : Point, b : Point, c : Point,
        invert : Boolean = false
    ) : Matrix {

        var m : Matrix = new Matrix(
            b.x - a.x, b.y - a.y,
            c.x - a.x, c.y - a.y);

        if (invert) {
            m.invert();
        }

        return m;
    }
    
    public static function createTransformMatrix(
        a : Point, b : Point, c : Point,
        t : Point, u : Point, v : Point
    ) : Matrix {

        var m1 : Matrix = new Matrix();
        m1.translate(-a.x, -a.y);
        m1.concat(createMatrix(a, b, c, true) );
        m1.concat(createMatrix(t, u, v) );
        m1.translate(t.x, t.y);
        
        return m1;
    } 

    public static function getCRef(
        a : Point, b : Point, c : Point
    ) : Point {

        var m1 : Matrix = new Matrix();
        var m2 : Matrix = new Matrix(
            b.x - a.x, b.y - a.y, a.y - b.y, b.x - a.x);
        var m3 : Matrix = new Matrix(1, 0, 0, -1);

        m1.translate(-a.x, -a.y);
        
        m2.invert();
        m1.concat(m2);
        
        m1.concat(m3);
        
        m2.invert();
        m1.concat(m2);
        
        m1.translate(a.x, a.y);
        
        return m1.transformPoint(new Point(c.x, c.y) );
    }
    
    public static function getCrossPoint(
        o : Point,
        a : Point, b : Point, c : Point
    ) : Point {
        
        var mat : Matrix = new Matrix(
            a.x - o.x, a.y - o.y,
            c.x - b.x, c.y - b.y);
        
        mat.invert();
        
        var st : Point = mat.transformPoint(b.subtract(o) );
        
        var s : Number = st.x;
        var t : Number = -st.y;
        
        if (0 <= t && t <= 1) {
            return new Point(
                o.x + (a.x - o.x) * s,
                o.y + (a.y - o.y) * s);
        } else {
            return null;
        }
    }
}

class UIPoint extends Sprite {

    private var _pressed : Boolean;
    private var _dragX : Number;
    private var _dragY : Number;
    
    public function UIPoint(
        color : uint, x : Number, y : Number, label : String,
        movable : Boolean = false
    ) {

        var g : Graphics = graphics;
        g.clear();
        g.lineStyle(2, 0xffffff ^ color);
        g.beginFill(color);
        g.drawCircle(0, 0, 5);
        g.endFill();
        
        var labelField : TextField = new TextField();
        labelField.type = TextFieldType.DYNAMIC;
        labelField.autoSize = TextFieldAutoSize.LEFT;
        labelField.selectable = false;
        labelField.text = label;
        labelField.x = 4;
        labelField.y = 4;
        addChild(labelField);

        this.x = x;
        this.y = y;
        
        buttonMode = movable;
        useHandCursor = movable;

        if (movable) {
            _pressed = false;
            addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);    
        }
    }
    
    private function mouseDownHandler(event : MouseEvent) : void {

        if (_pressed) return;
        
        stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
        stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
        stage.addEventListener(Event.MOUSE_LEAVE, stage_mouseLeaveHandler);

        _dragX = mouseX;
        _dragY = mouseY;
        _pressed = true;
    }

    private function stage_mouseMoveHandler(event : MouseEvent) : void {
        x += (mouseX - _dragX);
        y += (mouseY - _dragY);
    }
    
    private function stage_mouseUpHandler(event : MouseEvent) : void {
        releaseMouse();
    }
    
    private function stage_mouseLeaveHandler(event : Event) : void {
        releaseMouse();
    }

    private function releaseMouse() : void {

        if (!_pressed) return;

        stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
        stage.removeEventListener(Event.MOUSE_LEAVE, stage_mouseLeaveHandler);
        
        _pressed = false;
    }
}