forked from: pencil tool

by PESakaTFM forked from pencil tool (diff: 23)
Noticing that the drawing data in the canvas gets really big and starts to
lag in responsiveness over time (a lot of time granted, but still), I figured
I would show you a better way, codeonwort.
♥0 | Line 93 | Modified 2012-07-28 06:50:10 | MIT License
play

ActionScript3 source code

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


// forked from codeonwort's pencil tool
/*
Noticing that the drawing data in the canvas gets really big and starts to
lag in responsiveness over time (a lot of time granted, but still), I figured
I would show you a better way, codeonwort.
*/
package {
    
    import flash.display.Sprite
    import flash.display.Shape
    import flash.events.Event
    import flash.events.MouseEvent
    import flash.geom.Point;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    
    public class PencilDrawing extends Sprite {
        
        private const SAMPLING_UNIT:Number = 50 // 50 픽셀 이동할 때마다 노드 추출
        
        private var canvas:Bitmap;
        private var canvasData:BitmapData;
        private var pen:Shape;
        private var nodes:Vector.<Node> = new Vector.<Node>
        
        private var start:Point, end:Point
        private var movement:Number = 0 // 이동 거리

        public function PencilDrawing() {
            stage ? init() : addEventListener(Event.ADDED_TO_STAGE, init)
        }
        
        private function init($:Event=null):void {
            removeEventListener(Event.ADDED_TO_STAGE, arguments.callee)
            
            pen = new Shape();
            canvasData = new BitmapData(465,465,false,0xffffff);
            addChild(canvas = new Bitmap(canvasData))
            start = new Point
            end = new Point
            
            stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing)
            stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing)
        }
        
        private function startDrawing($:MouseEvent):void {
            start.x = mouseX ; start.y = mouseY
            movement = 0
            nodes.push(new Node(start.clone(), new Point))
            stage.addEventListener(MouseEvent.MOUSE_MOVE, draw)
        }
        
        private function stopDrawing($:MouseEvent):void {
            end.x = mouseX ; end.y = mouseY
            nodes.push(new Node(end.clone(), new Point))
            drawSpline(nodes[nodes.length-2], nodes[nodes.length-1])
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, draw)
        }
        
        private function draw($:MouseEvent):void {
            end.x = mouseX ; end.y = mouseY
            var dx:Number = end.x - start.x
            var dy:Number = end.y - start.y
            var dist:Number = Math.sqrt(dx*dx + dy*dy)
            movement += dist
            if(movement >= SAMPLING_UNIT){
                var velocity:Point = end.subtract(start)
                velocity.normalize(1)
                velocity.x *= movement
                velocity.y *= movement
                var node:Node = new Node(end.clone(), velocity)
                nodes.push(node)
                movement = 0
                drawSpline(nodes[nodes.length-2], nodes[nodes.length-1])
            }
            start.x = end.x
            start.y = end.y
        }
        
        private function drawSpline(n0:Node, n1:Node):void {
            var _a:Point = new Point(2*n0.p.x-2*n1.p.x+n0.v.x+n1.v.x, 2*n0.p.y-2*n1.p.y+n0.v.y+n1.v.y)
            var _b:Point = new Point(-3*n0.p.x+3*n1.p.x-2*n0.v.x-n1.v.x, -3*n0.p.y+3*n1.p.y-2*n0.v.y-n1.v.y)
            var _c:Point = new Point(n0.v.x, n0.v.y)
            var _d:Point = new Point(n0.p.x, n0.p.y)
            var t:Number, t2:Number, t3:Number
            var xt:Number, yt:Number
            
            pen.graphics.clear();
            pen.graphics.lineStyle(0, 0x00)
            pen.graphics.moveTo(n0.p.x, n0.p.y)
            for(var i:int=1; i<=30; i++){
                t = i / 30
                t2 = t * t
                t3 = t2 * t
                xt = _a.x*t3 + _b.x*t2 + _c.x*t + _d.x
                yt = _a.y*t3 + _b.y*t2 + _c.y*t + _d.y
                pen.graphics.lineTo(xt, yt)
            }
            pen.graphics.lineStyle()
            canvasData.draw(pen);
        }

    }
    
}

////////////////////////
// outside of package //
////////////////////////

import flash.geom.Point

class Node {
    
    private var _point:Point, _velocity:Point, _time:uint
    
    public function Node(p:Point, v:Point) {
        _point = p
        _velocity = v
    }
    
    public function get p():Point { return _point }
    public function get v():Point { return _velocity }
    
}