canvas-任意画多个凸多边形

项目中需要用到鼠标点画任意多个角的凸多边形,不允许有凹进去的角,思路是用到直线方程判断落点的位置,前两个点可以任意落点,从第三个点开始起进行判断,如果落点与之前的点结合之后形成的是凹进去的角,则不允许落点,单击画点,双击闭合路径,代码如下:

html:

<canvas id="canvas" width="800" height="500">当前浏览器不支持canvas,请更换浏览器使用!</canvas>

直接使用canvas标签

js:

    var canvas = document.getElementById("canvas") //获取到canvas元素
    var context = canvas.getContext("2d") //获取上下文的环境

    function drawPoint(cxt, x, y, w, borderWidth, borderColor, fillColor) {
        cxt.beginPath()
        cxt.moveTo(x - w, y - w)
        cxt.lineTo(x + w, y - w)
        cxt.lineTo(x + w, y + w)
        cxt.lineTo(x - w, y + w)
        cxt.lineWidth = borderWidth
        cxt.strokeStyle = borderColor
        cxt.fillStyle = fillColor
        cxt.closePath()
        cxt.fill()
        cxt.stroke()
    }

    function drawPolygon(cxt, dbl, borderWidth, borderColor, fillColor, t) {
        for (var i = 0; i < dbl.length; i++) {
            drawPoint(cxt, dbl[i].x, dbl[i].y, 2, 1, 'red', 'skyblue')
        }
        cxt.moveTo(dbl[0].x, dbl[0].y)
        for (var i = 1; i < dbl.length; i++) {
            cxt.lineTo(dbl[i].x, dbl[i].y)
        }
        if (t) {
            cxt.closePath()
            cxt.fillStyle = fillColor
            cxt.fill()
        }
        cxt.lineWidth = borderWidth
        cxt.strokeStyle = borderColor
        cxt.stroke()
    }

    function z(x, y, x1, y1, x2, y2) {
        if (((x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)) > 0) {
            return 1
        } else if (((x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)) < 0) {
            return 3
        } else {
            return 2
        }
    }

获取到canvas之后,定义画点和连线以及闭合路径的函数

var timeId;
    var dbl = [], arr = []
    canvas.ondblclick = function () {
        if (arr.length > 2) {
            drawPolygon(context, arr, 1, 'red', "rgba(0, 0, 0, .1)", true)
            // 这里执行完成闭合之后,清空坐标数组,便于另外新建
            dbl = arr
            arr = []
        }
    }
    canvas.onclick = function (e) {
        clearTimeout(timeId);
        timeId = setTimeout(function () {
            x = e.offsetX
            y = e.offsetY
            if (arr.length >= 3) {
                var n1= z(arr[2].x, arr[2].y, arr[0].x, arr[0].y, arr[1].x, arr[1].y)
                var n2 = z(arr[arr.length - 1].x, arr[arr.length - 1].y, arr[0].x, arr[0].y, x, y) 
                var n3= z(arr[1].x, arr[1].y, arr[0].x, arr[0].y, x, y)
                var n4= z(arr[arr.length - 1].x, arr[arr.length - 1].y, arr[arr.length - 2].x, arr[arr.length - 2].y, x, y)
                if (n1=== 1) {
                    // 代表第2点在线左边,这时判断第4个点的位置,如果在左边就不允许落点
                    if (n2 === 1 || n3=== 1 || n4=== 1) {
                        return
                    }
                }
                if (n1=== 3) {
                    // 代表第2点在线右边,这时判断第4个点的位置,如果在右边就不允许落点
                    if (n2 === 3 || n3=== 3 || n4=== 3) {
                        return
                    }
                }
                arr.push({x: x, y: y})
            }
            arr.length < 3 ? arr.push({x: x, y: y}) : null
            drawPolygon(context, arr, 1, 'blue')

        }, 250)

    }

根据判断落点位置的函数来进行落点位置的控制,最后双击进行闭合路径填充颜色,另外项目里还有用到画任意数量大小矩形,思路也是差不多的,我是通过的鼠标点击后移动鼠标来实现控制

转载于:https://my.oschina.net/mdu/blog/1475262

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值