当前位置:网站首页>Draw multiple polygons using canvas

Draw multiple polygons using canvas

2022-06-09 09:18:00 ⑥②

Go straight to the code

HTML Code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html, body {
        }
    </style>
    <script defer src="test.js"></script>
</head>
<body>
<canvas id="canvas" width="960" height="540"
        style="width:960px;height:540px;  background:url('https://img0.baidu.com/it/u=2183579431,409639925&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281');background-size: contain"></canvas>
</body>
<script>


</script>
</html>

 JS Code

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d');

let clientX = 0, clientY = 0,  //  Coordinates of the mouse position 
    points = [],   //  Store the clicked coordinate node data 
    polygonFillStyle = 'rgba(255,0,0,.2)',
    rectFillStyle = 'yellow',
    lineStyle = 'red',
    lineWidth = 3

ctx.lineJoin = 'round'
ctx.strokeStyle = lineStyle
ctx.lineWidth = lineWidth
/**
 *  Empty Canvas Content 
 */
function clear() {
    ctx.fillStyle = 'transparent'
    ctx.clearRect(0, 0, canvas.width, canvas.height)
}

/**
 *  Initialize listening events 
 */
function initEvent(){
    //  Monitor mouse movement events 
    canvas.addEventListener('mousemove', (e) => {
        let {x,y} = windowToCanvas(e.clientX,e.clientY)
        clientX = x
        clientY = y
    })

    //  Monitor mouse click events 
    canvas.addEventListener('click', (e) => {
        let len = points.length
        let cIndex = 0
        //  Initialize the storage node array 
        if (len === 0) {
            points[cIndex] = []
        } else {
            cIndex = len - 1
            if (typeof points[len - 1] === 'undefined') {
                points[cIndex] = []
            }
        }
        let lastPoints = points[cIndex]
        let lastPointsLen = lastPoints.length
        if (lastPointsLen === 0) {
            //  If space is 0 Words , Directly add 
            points[cIndex].push([clientX, clientY])
        } else {
            //  If it's not zero , Just judge whether it is on the existing point , If so, close the path , If not , Continue to add nodes 
            let lastStartX = lastPoints[0][0],
                lastStartY = lastPoints[0][1]
            if (isInPoint(clientX, clientY, lastStartX, lastStartY)) {
                points[cIndex].push([lastStartX, lastStartY])
                points[len] = []
            } else {
                points[cIndex].push([clientX, clientY])
            }
        }
    })

}

/**
 *  Draw a line segment between two points 
 * @param points
 */
function drawLine(points) {
    ctx.beginPath()
    for (let i = 0; i < points.length; i++) {
        let p = points[i]
        let cx = p[0], cy = p[1]

        //  Initialization starting point 
        if (i === 0) {
            ctx.moveTo(cx, cy)
        }

        //  Draw a line 
        ctx.lineTo(cx, cy)
        //  Draw a small rectangle at the point 
        // ctx.fillRect(cx - 5, cy - 5, 10, 10)
    }
    ctx.stroke()
}

/**
 *  Draw the background color between line segments 
 * @param points
 */
function drawPolygon(points) {
    if (points.length < 1) {
        return;
    }

    let len = points.length
    let moveX = clientX, moveY = clientY,
        startX = points[0][0], startY = points[0][1],
        endX = points[len - 1][0], endY = points[len - 1][1]

    ctx.fillStyle = polygonFillStyle
    for (let i = 0; i < points.length; i++) {
        let p = points[i]
        let cx = p[0], cy = p[1]
        //  Initialization starting point 
        if (i === 0) {
            ctx.moveTo(cx, cy)
        }
        //  Draw a line 
        ctx.lineTo(cx, cy)
    }
    if (isInPoint(moveX, moveY, startX, startY)) {
        ctx.lineTo(startX, startY)
    } else {
        ctx.lineTo(clientX, clientY)
    }

    ctx.fill()
}

/**
 *  Draw the mouse following line segment 
 */
function drawFollowLine(points) {
    if (points.length < 1) {
        ctx.fillRect(clientX - 5, clientY - 5, 10, 10)
        return;
    }
    ctx.save()
    let len = points.length
    //  Determine whether it coincides with the first node 
    let moveX = clientX, moveY = clientY,
        startX = points[0][0], startY = points[0][1],
        endX = points[len - 1][0], endY = points[len - 1][1]


    ctx.beginPath()
    ctx.moveTo(endX, endY)
    ctx.fillStyle = rectFillStyle
    //  If the mouse is near the first point ,, Just force the mouse to the first point 
    if (isInPoint(moveX, moveY, startX, startY)) {
        ctx.lineTo(startX, startY)
        //  Draw a small rectangle , Follow the mouse 
        ctx.fillRect(startX - 5, startY - 5, 10, 10)
    } else {
        ctx.lineTo(moveX, moveY)
        //  Draw a small rectangle , Follow the mouse 
        ctx.fillRect(clientX - 5, clientY - 5, 10, 10)
        // ctx.arc(clientX , clientY,10, 0 , 2*Math.PI, true)
        // ctx.fill()
    }
    ctx.closePath()
    ctx.stroke()
    ctx.restore()
}


/**
 *  Determine whether a point is near another point 
 */
function isInPoint(x, y, tx, ty) {
    let r = Math.sqrt(Math.pow(x - tx, 2) + Math.pow(y - ty, 2))
    if (r <= 20) {
        return true
    }
    return false
}


/**
 *  Convert window coordinates to Canvas coordinate 
 * @param x  window x coordinate 
 * @param y  window y coordinate 
 * @returns {
   {x: number, y: number}}
 */
function windowToCanvas(x, y) {
    let bbox = canvas.getBoundingClientRect();
    return {
        x: x - bbox.left * (canvas.width  / bbox.width),
        y: y - bbox.top  * (canvas.height / bbox.height)
    };
}


/**
 *  Start function 
 */
function start() {
    initEvent()

    let refresh = function (){
        window.requestAnimationFrame(() => {
            clear()
            let len = points.length
            for (let i = 0; i < points.length; i++) {
                drawLine(points[i])
                drawPolygon(points[i])
                if (i == len - 1) {
                    //  Just follow the last polygon with the mouse 
                    drawFollowLine(points[i])
                }
            }

            refresh()
        })
    }
    refresh()
}
start()

原网站

版权声明
本文为[⑥②]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206090858570623.html