二次贝塞尔曲线实例

发表评论 阅读评论

实在抱歉,是二次贝塞尔曲线,不是一次杯赛儿曲线。o(╯□╰)o
鼠标拖动划线,然后拖动变成曲线

这是一个贝塞尔曲线bezierLine的演示demo,如果你看不到这个flash,请到文章页面查看!

前天在天地会看到一朋友说,想要先画一条线,然后可以随意拖动这条线,然后我就想到了二次贝塞尔曲线,真是个好东东,于是就做了个实例,一来给那位朋友帮个忙,二来我博客也好久没更新AS相关的东东了,呵呵。
这里只贴出来BezierLine的代码,要是想看整个实例的源码,在最下面有链接下载的。
废话少说,上代码。

BezierLine:

package com.litefeel.display 
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    /**
     * lite3@qq.com
     * www.litefeel.com
     * @author lite3
     */
    public class BezierLine extends Sprite
    {
        // 终点坐标
        private var endX:Number;
        private var endY:Number;

        private var centerX:Number;
        private var centerY:Number;

        // 控制点坐标
        private var _controlX:Number;
        private var _controlY:Number;

        // 线条样式属性
        private var _thickness:Number;
        private var _color:uint;
        private var _pixelHinting:Boolean;
        private var _scaleMode:String;
        private var _caps:String;
        private var _joints:String;
        private var _miterLimit:Number;

        public function BezierLine(beginX:Number, beginY:Number, endX:Number, endY:Number) 
        {
            this.endX = endX - beginX;
            this.endY = endY - beginY;
            setStyle(3);
            graphics.lineTo(this.endX, this.endY);
            x = beginX;
            y = beginY;
            centerX = this.endX / 2;
            centerY = this.endY / 2;

            this.buttonMode = true;
            this.useHandCursor = true;

            addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        }

        /**
         * 设置线条样式
         * @param   thickness
         * @param   color
         * @param   alpha
         * @param   pixelHinting
         * @param   scaleMode
         * @param   caps
         * @param   joints
         * @param   miterLimit
         */
        public function setStyle(thickness:Number, color:uint = 0, alpha:Number = 1, pixelHinting:Boolean = false, scaleMode:String = "normal", caps:String = null, joints:String = null, miterLimit:Number = 3):void
        {
            _thickness = thickness;
            _color = color;
            this.alpha = alpha;
            _pixelHinting = pixelHinting;
            _scaleMode = scaleMode;
            _caps = caps;
            _joints = joints;
            _miterLimit = miterLimit;
            drawLineByControlPoint(controlX, controlY);
        }

        /**
         * 划线 贝塞尔曲线
         * @param   controlX
         * @param   controlY
         */
        public function drawLineByControlPoint(controlX:Number, controlY:Number):void
        {
            _controlX = controlX;
            _controlY = controlY;

            graphics.clear();
            graphics.moveTo(0, 0);
            graphics.lineStyle(_thickness, _color, 1, _pixelHinting, _scaleMode, _caps, _joints, _miterLimit);
            graphics.curveTo(controlX, controlY, endX, endY);

        }
        /** 控制点X */
        public function get controlX():Number { return _controlX; }

        /** 控制点Y */
        public function get controlY():Number { return _controlY; }

        public function get thickness():Number { return _thickness; }
        public function set thickness(value:Number):void 
        {
            if (_thickness != value)
            {
                _thickness = value;
                drawLineByControlPoint(_controlX, _controlY);
            }
        }

        public function get color():uint { return _color; }
        public function set color(value:uint):void 
        {
            if (_color != value)
            {
                _color = value;
                drawLineByControlPoint(_controlX, _controlY);
            }
        }

        public function get pixelHinting():Boolean { return _pixelHinting; }
        public function set pixelHinting(value:Boolean):void 
        {
            if (_pixelHinting != value)
            {
                _pixelHinting = value;
                drawLineByControlPoint(_controlX, _controlY);
            }
        }

        public function get scaleMode():String { return _scaleMode; }
        public function set scaleMode(value:String):void 
        {
            if (_scaleMode != value)
            {
                _scaleMode = value;
                drawLineByControlPoint(_controlX, _controlY);
            }
        }

        public function get caps():String { return _caps; }
        public function set caps(value:String):void 
        {
            if (_caps != value)
            {
                _caps = value;
                drawLineByControlPoint(_controlX, _controlY);
            }
        }

        public function get joints():String { return _joints; }
        public function set joints(value:String):void 
        {
            if (_joints != value)
            {
                _joints = value;
                drawLineByControlPoint(_controlX, _controlY);
            }
        }

        public function get miterLimit():Number { return _miterLimit; }
        public function set miterLimit(value:Number):void 
        {
            if (_miterLimit != value)
            {
                _miterLimit = value;
                drawLineByControlPoint(_controlX, _controlY);
            }
        }

        private function mouseDownHandler(e:MouseEvent):void 
        {
            stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
        }

        private function mouseMoveHandler(e:MouseEvent):void 
        {
            drawLineByControlPoint((mouseX - centerX) * 2 + centerX, (mouseY - centerY) * 2 + centerY);
        }

        private function mouseUpHandler(e:MouseEvent):void 
        {
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
        }
    }
}

源码下载☞

标签: ,

  1. lite3 | | #1

    @疯兔子
    恩,是的,这里的控制点是变化的

  2. 疯兔子 | #2

    如果在不改变原锚点的话,是不是应该同时再加一个控制点,这样原来的锚点还是锚点,控制点还是控制点,应该是这样吧?

  3. 疯兔子 | #3

    你好,现在才看到你的文章,如何才能才线段上加锚点呢?

  4. wei | #4

    private function mouseMoveHadnler(e:MouseEvent):void
    {
    canvas.graphics.clear();
    canvas.graphics.moveTo(lockX, lockY);
    canvas.graphics.lineStyle(1,0x0099ff);
    canvas.graphics.lineTo(canvas.mouseX, canvas.mouseY);
    }
    我直接在flex中放入一个 并在canvas按下mouse,移动。却看不到线。请教下

  5. wei | #5

    flash转成flex怎么转哟?

  6. wei | #6

    哦,谢谢你了。你真好

  7. lite3 | | #7

    这个是Flash 项目,不是Flex项目,要装Flash CS 3 或者4才能编译的

  8. wei | #8

    你好,我下下来是
    bezierLine.as3proj,
    bezierLine.fla
    bezierExample.as
    bezierLine.swf
    cn这些内容,可我不知怎么运行哟,自己重编译你的源文件运行。
    我一般都用<mx:application来运行。没看你的有
    非常感谢你的源代码

  9. sdffdg | #9

    很不错啊。I like it!

  10. lite3 | | #10

    @kolou
    有什么问题可以来这里留言或者自己M我qq,非常乐意跟大家讨论,共同学习的 :razz:

  11. kolou | #11

    帅哥,爱死你了,哈哈
    一直被贝兹曲线的某个问题困扰,现在搞定了

  12. lite3 | | #12

    @hsy168

    不好意思,我用CS4做的,保存的是CS4 :grin:
    你可能用的是CS3吧, 现已换成CS3的了,
    请你重新下载,所有问题应该就都可以解决了
    (*^__^*) 嘻嘻…… 谢谢支持

  13. hsy168 | #13

    问题在这里canvas=this.getChildByName("_canvas") as Sprite;
    另外你的fla我打不开,所以我自己写了个fla,并在库里添加了相应的组件,但测试下却出现了上面的提示,请解释下原因谢谢

  14. hsy168 | #14

    不知是什么原因
    你的代码测试时出现如下提示:
    TypeError: Error #1009: 无法访问空对象引用的属性或方法。
    at BezierLineExample/::init()
    at BezierLineExample$iinit()

  1. 本文目前尚无任何 trackbacks 和 pingbacks.
回到顶部