使用html5,鼠标绘制贝赛尔曲线

本文介绍了一个基于HTML5 Canvas的绘图系统实现,重点展示了如何利用JavaScript进行贝塞尔曲线和图片元素的绘制及交互操作。包括响应鼠标事件来调整图形、实现图形选择和移动等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!DOCTYPE html />
<html>
<head>
    <title></title>
    <script src="PPTEditorResource/jquery-1.10.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        //全局的绘图api,该对象,通过 GetContext()方法取得使用
        var g_context = null;
        //返回当前的绘图对象
        function GetContext() {
            if (!g_context)
                g_context = $('#myCanvas').get(0).getContext('2d');
            return g_context;
        }

        //元素的位置定义类
        //起始点坐标,宽,高
        function ElementPositionClass(startPosition, width, height) {
            this.Base = PointXYOverLoadPoint;
            this.Base(startPosition);
            this.Width = width;
            this.Height = height;
        }
        //记录在画板中的所有元素的绘制顺序,在绘画类的基类中自增
        var g_ElementNumber = 0;
        //记录所有元素的数组
        var g_ElementArray = new Array();
        ///所有tools的基类
        function ToolsBaseClass(p0, name, translateName, toolsType, isEnable) {
            this.p0 = p0;
            this.ZIndex = g_ElementNumber++;
            //控件的名称
            this.Name = name;
            //控件的翻译名称
            this.TranslateName = translateName;
            ///标记是哪一种类型,比如如果是动作类型,那么可能需要特殊处理(将所设置的动作,全部列出来)
            this.ToolsType = toolsType;
            //控件的是否可以使用
            this.IsEnable = isEnable;
            ///未实现方法,留着让子类实现
            this.Update = function () { alert('developping'); };   //点击tools时,要执行的方法,用来更新右边的属相窗口
            this.GetExeString = function () { return 'alert("developping");'; };  //由应用按钮,调用.
            //将要判断位置的元素,加入到全局数组中,供以后判断位置和重新绘制图形
            g_ElementArray[this.ZIndex] = this;
            this.Draw = function () {
                alert('由子类实现');
            };
            this.JudgeCheckPosition = function () {
                alert('由子类实现');
            };
            //设置选中时,图形的突出显示
            this.SelectLineWidth = 1;
        }
        ///定义tools有几种type,相当于类中的枚举
        ToolsBaseClass.ToolsType = {
            normalToolsType: 1, //基本类型,比如css的设置
            actionType: 2//动作类型
        };
        //对鼠标坐标点,进行封装的类
        function PointXY(x, y) {
            this.PointX = x;
            this.PointY = y;
        };
        //重载一下pointXY的类构造函数
        //参数是鼠标的点击事件对象
        function PointXYOverLoad(mouseCientArgument) {
            this.Base = PointXY;
            this.Base(mouseCientArgument.clientX, mouseCientArgument.clientY);
        }
        //重载一下pointXY的类构造函数
        //参数为自定义的对象,该对象有2个属性:PointX,PointY
        function PointXYOverLoadPoint(pointXY) {
            this.Base = PointXY;
            this.Base(pointXY.PointX, pointXY.PointY);
        }
        //代表bezier curve的类,
        //初始化时,需要传递4个点的坐标
        //包含方法:
        //1.画出贝赛尔曲线.
        //2.显示贝塞尔曲线的框架
        function bezierCurveClass(p0, p1, p2, p3) {
            this.Base = ToolsBaseClass;
            this.Base(p0, 'bezierCurveClass', '贝赛尔曲线', ToolsBaseClass.ToolsType.actionType, true);
            //控制点1
            this.p1 = p1;
            //控制点2
            this.p2 = p2;
            //控制点3
            this.p3 = p3;
            //绘制控制点时,控制点的高度
            var height = 10;

            this.DrawBezierCurve = function () {
                var context = GetContext();
                context.beginPath();
                context.moveTo(this.p0.PointX, this.p0.PointY);
                context.bezierCurveTo(this.p1.PointX, this.p1.PointY, this.p2.PointX, this.p2.PointY, this.p3.PointX, this.p3.PointY);
                context.strokeStyle = "red";
                context.stroke();
            };

            this.ShowOutLine = function () {
                //绘制Bezier curve的框架
                var context = GetContext();
                context.strokeStyle = "black";
                context.beginPath();
                context.moveTo(this.p0.PointX, this.p0.PointY);
                //绘制起始点
                context.lineWidth = this.SelectLineWidth;
                context.strokeRect(this.p0.PointX, this.p0.PointY, height, height);
                context.lineWidth = 1;
                context.lineTo(this.p1.PointX, this.p1.PointY);
                //绘制第一个控制点
                context.lineWidth = this.SelectLineWidth;
                context.strokeRect(this.p1.PointX, this.p1.PointY, height, height);
                context.moveTo(this.p2.PointX, this.p2.PointY);
                //绘制第二个控制点
                context.lineWidth = this.SelectLineWidth;
                context.strokeRect(this.p2.PointX, this.p2.PointY, height, height);
                context.lineWidth = 1;
                context.lineTo(this.p3.PointX, this.p3.PointY);
                //绘制第三个控制点
                context.lineWidth = this.SelectLineWidth;
                context.strokeRect(this.p3.PointX, this.p3.PointY, height, height);

                context.stroke();
                context.lineWidth = 1;
            };

            this.Draw = function () {
                this.ShowOutLine();
                this.DrawBezierCurve();
            };

            //判断是否选中当前的图形元素
            this.JudgeCheckPosition = function (pointXY) {
                //判断控制点p0是否被选中
                if (CheckPosition(pointXY, new ElementPositionClass(this.p0, height, height))) {
                    $('#myCanvas').on('mousemove', { rt: this }, function (e) {
                        console.log('moveMouse: ' + (e.clientX - $('#myCanvas').offset().left) + ',' + (e.clientY - $('#myCanvas').offset().top));
                        //                        console.log('CurrentSelectPoint :' + e.data.rt.CurrentSelectPoint.PointX + ',' + e.data.rt.CurrentSelectPoint.PointY);
                        e.data.rt.p0 = new PointXY((e.clientX - $('#myCanvas').offset().left), (e.clientY - $('#myCanvas').offset().top));

                        console.log('p0 :' + e.data.rt.p0.PointX + ',' + e.data.rt.p0.PointY);

                        ReDraw();
                    });
                    console.log('select');
                    return true;
                }
                //判断控制点p1是否被选中
                else if (CheckPosition(pointXY, new ElementPositionClass(this.p1, height, height))) {
                    $('#myCanvas').on('mousemove', { rt: this }, function (e) {
                        console.log('moveMouse: ' + (e.clientX - $('#myCanvas').offset().left) + ',' + (e.clientY - $('#myCanvas').offset().top));
                        //                        console.log('CurrentSelectPoint :' + e.data.rt.CurrentSelectPoint.PointX + ',' + e.data.rt.CurrentSelectPoint.PointY);
                        e.data.rt.p1 = new PointXY((e.clientX - $('#myCanvas').offset().left), (e.clientY - $('#myCanvas').offset().top));

                        console.log('p1 :' + e.data.rt.p1.PointX + ',' + e.data.rt.p1.PointY);

                        ReDraw();
                    });
                    console.log('select');
                }
                //判断控制点p2是否被选中
                else if (CheckPosition(pointXY, new ElementPositionClass(this.p2, height, height))) {
                    $('#myCanvas').on('mousemove', { rt: this }, function (e) {
                        console.log('moveMouse: ' + (e.clientX - $('#myCanvas').offset().left) + ',' + (e.clientY - $('#myCanvas').offset().top));
                        //                        console.log('CurrentSelectPoint :' + e.data.rt.CurrentSelectPoint.PointX + ',' + e.data.rt.CurrentSelectPoint.PointY);
                        e.data.rt.p2 = new PointXY((e.clientX - $('#myCanvas').offset().left), (e.clientY - $('#myCanvas').offset().top));

                        console.log('p2 :' + e.data.rt.p2.PointX + ',' + e.data.rt.p2.PointY);

                        ReDraw();
                    });
                    console.log('select');
                }
                //判断控制点p3是否被选中
                else if (CheckPosition(pointXY, new ElementPositionClass(this.p3, height, height))) {
                    $('#myCanvas').on('mousemove', { rt: this }, function (e) {
                        console.log('moveMouse: ' + (e.clientX - $('#myCanvas').offset().left) + ',' + (e.clientY - $('#myCanvas').offset().top));
                        //                        console.log('CurrentSelectPoint :' + e.data.rt.CurrentSelectPoint.PointX + ',' + e.data.rt.CurrentSelectPoint.PointY);
                        e.data.rt.p3 = new PointXY((e.clientX - $('#myCanvas').offset().left), (e.clientY - $('#myCanvas').offset().top));

                        console.log('p3 :' + e.data.rt.p3.PointX + ',' + e.data.rt.p3.PointY);

                        ReDraw();
                    });
                    console.log('select');
                }
                else {
                    return false;
                }
                return true;
            };
        };

        //代表图片类型
        //初始化时,需要传递初始点的坐标
        function ImageClass(pointXY, width, height, image) {
            this.Base = ToolsBaseClass;
            this.Base(pointXY, 'ImageClass', '图片', ToolsBaseClass.ToolsType.actionType, true);
            //记录当前设置的图像
            this.ImageObject = image;
            //绘制区域的宽度
            this.Width = width;
            //绘制区域的高度
            this.Height = function () {
                return (image.Height / image.Width) * this.Width;
            };

            //覆盖基类方法,画出该对象
            this.Draw = function () {
                var context = GetContext();
                context.drawImage(this.ImageObject, this.p0.PointX, this.p0.PointY, this.Width, this.Height);
            };
        }

        function CheckPosition(pointXY, elementPositionClass) {
            var x = pointXY.PointX;
            var y = pointXY.PointY;

            if (x >= elementPositionClass.PointX && x <= (elementPositionClass.PointX + elementPositionClass.Width) && (y >= elementPositionClass.PointY) && (y <= elementPositionClass.PointY + elementPositionClass.Height)) {
                return true;
            }
            else {
                return false;
            }
        }

        function huizhi(toolstype) {
            if (!currentClientIndex)
                currentClientIndex = new PointXY(50, 50);
            switch (toolstype) {

                case "bezier":
                    new bezierCurveClass(currentClientIndex, new PointXY(50 + currentClientIndex.PointX, currentClientIndex.PointY - 50), new PointXY(50 + currentClientIndex.PointX, 50 + currentClientIndex.PointY), new PointXY(100 + currentClientIndex.PointX, currentClientIndex.PointY));
                    break;

                case "image":
                    var imageObj = new Image();
                    imageObj.src = "";
                    imageObj.Width = "";
                    imageObj.Height = "";
                    new ImageClass(currentClientIndex, 400, 300, imageObj);
                    break;

                default:
                    alert(toolstype);
                    break;
            }


            ReDraw();
        };
        //记录当前鼠标的点击坐标
        var currentClientIndex = null;

        //得到点击的图形元素,加粗显示选中的图形
        function GetClickElement(pointXY) {
            for (i in g_ElementArray) {
                if (g_ElementArray[i].JudgeCheckPosition(pointXY)) {
                    g_ElementArray[i].SelectLineWidth = 3;
                }
                else {
                    g_ElementArray[i].SelectLineWidth = 1;
                }
            }
            ReDraw();
        }
        //根据数组中存放的元素,重新绘制这些元素
        function ReDraw() {
            GetContext().clearRect(0, 0, 1000, 800);
            for (i in g_ElementArray) {
                console.log('ReDraw');
                g_ElementArray[i].Draw();
            }
        }

        $(function () {
            //绑定监听事件,用来确定,用户点击的是哪一个绘制的图形
            $('#myCanvas').mousedown(function (e) {
                GetClickElement(new PointXY(e.clientX - this.offsetLeft, e.clientY - this.offsetTop));
            })
            .mouseup(function (e) {
                currentClientIndex = new PointXY(e.clientX - this.offsetLeft, e.clientY - this.offsetTop);
                console.log("click Index: " + currentClientIndex.PointX + ':' + currentClientIndex.PointY);
                console.log("mousemove event off");
                $('#myCanvas').unbind("mousemove");
            });
        });

    </script>
</head>
<body>
    <input id="button1" type="button" value="添加贝塞尔动作" οnclick="huizhi('bezier');" />
    <input id="button2" type="button" value="插入一个图像" οnclick="huizhi('image');" />
    <canvas id="myCanvas" width="1000" height="800" style="border: 1px solid #ccc;">
     浏览器不支持
    </canvas>
    <input id="button3" type="button" value="test" οnclick="test();" />
    <script type="text/javascript">
        function test() {
            setTimeout('ReDraw()', 100);
        }
    
    </script>
</body>
</html>


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值