如何使用光标/鼠标绘制“波浪线”

时间:2011-12-09 20:56:56

标签: flash actionscript-3 flex

我的客户现在已经要求用光标/鼠标绘制一条波浪线,如下所示:

Wavy Line http://www.endeavoursportsgroup.com/images/WavyLine.png

我在下面的代码中使用光标/鼠标绘制一条线,但我仍然坚持如何使线“波浪”。这实际上是通过绘制我之前正在处理的虚线来修改代码,因此可能会有一些遗留下来的代码,我将在稍后删除。

有人可以帮助我实现我被要求使用下面的代码创建的波浪线,或建议另一种方法来实现这一目标吗?

提前致谢!

package
{
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.net.FileReference;
import flash.utils.ByteArray;

import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.graphics.codec.PNGEncoder;

public class DrawingArea extends UIComponent
{
    private var isDrawing:Boolean = false;
    private var x1:int;
    private var y1:int;
    private var x2:int;
    private var y2:int;
    private var LastX:int = 0;
    private var LastY:int = 0;

    public var drawColor:uint = 0x0000FF;

    public function DrawingArea()
    {
        super();

        var p1:Point = new Point();
        var p2:Point = new Point();

        p1.x = 0;
        p1.y = 0;
        p2.x = 200;
        p2.y = 200;

        addEventListener(FlexEvent.CREATION_COMPLETE, function(event:FlexEvent):void {
            graphics.clear();

            graphics.beginFill(0xffffff, 0.00001);
            graphics.drawRect(0, 0, width, height);
            graphics.endFill();
        });

        addEventListener( MouseEvent.MOUSE_DOWN, mouseDown );
        addEventListener( MouseEvent.MOUSE_MOVE, mouseMove );
        addEventListener( MouseEvent.MOUSE_UP, mouseUp);
    }
    private function mouseDown(event:MouseEvent):void {
        x1 = mouseX;
        y1 = mouseY;
        isDrawing = true;
    }
    private function mouseMove(event:MouseEvent):void {
        if (!event.buttonDown)
        {
            isDrawing = false;
        }

        x2 = mouseX;
        y2 = mouseY;
        if (isDrawing )
        {
            var p1:Point = new Point();
            var p2:Point = new Point();
            p1.x = x1;
            p1.y = y1;
            p2.x = x2;
            p2.y = y2;

            graphics.lineStyle(2,0x00FF00,2);
            graphics.lineStyle(1, drawColor);
            graphics.moveTo(x1, y1);
            graphics.lineTo(x2, y2);
            x1 = x2;
            y1 = y2;
            LastX = x2;
            LastY = y2;
        }
    }
    private function mouseUp(event:MouseEvent):void {
        isDrawing = false;
    }
}
}

3 个答案:

答案 0 :(得分:1)

请尝试以下代码。这不是理想的,但它可能会给你一些想法。

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;

    public class CurvedLineTest extends Sprite
    {
        private static const DRAW_STEP:Number = 2;

        private var curveWidth:Number;
        private var curvePeriod:Number;
        private var smoothing:Number;

        private var prevPos:Point = new Point();
        private var curveLength:Number;
        private var smoothedN:Point = new Point();

        public function CurvedLineTest(curveWidth:Number = 10, curvePeriod:Number = 15, smoothFactor:Number = 80)
        {
            this.curveWidth = curveWidth;
            this.curvePeriod = curvePeriod;
            this.smoothing = Math.min(Math.max(smoothFactor, 0), 100) / 100;

            if( stage )
            {
                onAddedToStage();
            }
            else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

            // test: simulating fast mouse movements
            moveToPoint(10, 10);
            drawToPoint(15, 15);
            drawToPoint(35, 35);
            drawToPoint(60, 90);
            drawToPoint(150, 190);
            drawToPoint(350, 300);
        }

        private function onAddedToStage(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
        }

        private function onRemovedFromStage(e:Event):void
        {
            removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
            stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        }

        private function onMouseDown(e:MouseEvent):void
        {
            moveToPoint(mouseX, mouseY);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        }

        private function onMouseMove(e:MouseEvent):void
        {
            drawToPoint(mouseX, mouseY);
            e.updateAfterEvent();
        }

        private function moveToPoint(x:Number, y:Number):void
        {
            prevPos.x = x;
            prevPos.y = y;
            curveLength = 0;
            graphics.moveTo(x, y);
        }

        private function drawToPoint(x:Number, y:Number):void
        {
            // displacement vector
            var d:Point = new Point(x - prevPos.x, y - prevPos.y);

            // length of displacement vector
            var dl:Number = Math.sqrt(d.x * d.x + d.y * d.y);

            // normalized displacement vector
            var nd:Point = new Point(d.x / dl, d.y / dl);

            // normal to the displacement vector
            var cn:Point = normal(nd);

            var currentDl:Number = DRAW_STEP;
            while( currentDl <= dl )
            {
                // incrementing base curve length by the length of the step displacement
                curveLength += DRAW_STEP;

                // base curve coords of the current step
                var stepX:Number = prevPos.x + nd.x * DRAW_STEP;
                var stepY:Number = prevPos.y + nd.y * DRAW_STEP;

                // smoothing the normal to prevent ragged lines
                smoothedN.x = smoothing * smoothedN.x + (1 - smoothing) * cn.x;
                smoothedN.y = smoothing * smoothedN.y + (1 - smoothing) * cn.y;

                // wave form
                var wave:Number = curveWidth * Math.sin(Math.PI * curveLength / curvePeriod);

                // adding normal component to the current point of base curve
                var wavedX:Number = stepX + wave * smoothedN.x;
                var wavedY:Number = stepY + wave * smoothedN.y;

                // drawing waved curve
                graphics.lineStyle(1.5, 0);
                graphics.lineTo(wavedX, wavedY);

                // drawing base curve
                graphics.lineStyle(0, 0xBB2233, 0.5);
                graphics.moveTo(prevPos.x, prevPos.y);
                graphics.lineTo(stepX, stepY);

                // drawing normal
                graphics.lineStyle(0, 0x3322BB, 0.2);
                graphics.moveTo(prevPos.x, prevPos.y);
                graphics.lineTo(stepX + wave * smoothedN.x, stepY + wave * smoothedN.y);

                graphics.moveTo(wavedX, wavedY);

                // remembering current base curve point
                prevPos.x = stepX;
                prevPos.y = stepY;

                currentDl += DRAW_STEP;
            }
        }

        /**
         * Calculates normal to the given vector (in clockwise direction).
         */
        private function normal(vec:Point):Point
        {
            var d:Number = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
            return new Point(-vec.y / d, vec.x / d);
        }

        private function onMouseUp(e:MouseEvent):void
        {
            graphics.clear();
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        }
    }
}

答案 1 :(得分:0)

这是Sin(或Cos)曲线。将MouseMove更改为此应修复它。我假设积分和'最后'变量是旧的。这应该根据您在曲线中的位置向上或向下移动Y坐标,使用x坐标作为弧度角度。

    private function mouseMove(event:MouseEvent):void {
    if (!event.buttonDown)
    {
        isDrawing = false;
    }

    x2 = mouseX;
    y2 = mouseY;
    if (isDrawing )
    {
        //var p1:Point = new Point();
       // var p2:Point = new Point();
       // p1.x = x1;
       // p1.y = y1;
       // p2.x = x2;
       // p2.y = y2;

    y2 = Math.Sin(x2)+y2*(HeightOfThe Curve)
        graphics.lineStyle(2,0x00FF00,2);
        graphics.lineStyle(1, drawColor);
        graphics.moveTo(x1, y1);
        graphics.lineTo(x2, y2);
        x1 = x2;
        y1 = y2;
        //LastX = x2;
       // LastY = y2;
    }
}

应自动计算负数。

我再也不知道如何让它在曲线上工作。它可以正常工作但看起来很时髦,直到你回到水平(或至少大部分水平)的运动。

我目前无法自行测试,但我认为如果您已经知道如何绘制直线,那就是您需要做的全部。

答案 2 :(得分:0)

另一种可能性是spark.Path和使用QuadraticBezier的模式。 我相信文档提供了非常详细的解释和示例。