canvas如何使鼠标选中的线条高亮

新手上路,请多包涵

用canvas画了多条车辆轨迹线段,怎么点击某个线段使其高亮显示

阅读 5.7k
1 个回答
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>canvas</title>
</head>

<body>
    <canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>
</body>
<script>
    let canvas = document.getElementById("myCanvas");
    let ctx = canvas.getContext("2d");
    //模拟后台传来的刹车线数据
    // coordinate坐标数组 x起点x y起点y isMouseOver鼠标是否在这条线上
    let carData = [{
        coordinate: [{
            x: 30,
            y: 20
        }, {
            x: 15,
            y: 25
        }, {
            x: 20,
            y: 60
        }, {
            x: 10,
            y: 80
        }],
        isMouseOver: false,
    }, {
        coordinate: [{
            x: 60,
            y: 20
        }, {
            x: 45,
            y: 25
        }, {
            x: 50,
            y: 60
        }, {
            x: 40,
            y: 80
        }],
        isMouseOver: false,
    }]
    //刚进入页面调用画图函数
    drawCanvas()
    //canvas在浏览器的位置
    let x = getX(canvas)
    let y = getY(canvas)
    //给canvas绑上监听事件,如果你需要click事件就换掉mousemove
    canvas.addEventListener("mousemove", pitchOn);
    //监听具体执行的函数
    function pitchOn() {
        let mouse = event || ev;
        //算准canvas中的坐标
        let canvasX = mouse.clientX - x;
        let canvasY = mouse.clientY - y;
        isOnCarWire(canvasX, canvasY)
    }
    //判断传入的坐标点是否在刹车线上
    function isOnCarWire(canvasX, canvasY) {
        for (let i = 0; i < carData.length; i++) {
            drawWire(carData[i].coordinate)
            //判断点是否在图形内
            if (ctx.isPointInPath(canvasX, canvasY)) {
                carData[i].isMouseOver = true
                drawCanvas()
            } else {
                carData[i].isMouseOver = false
                drawCanvas()
            }
        }
    }
    //重绘canvas
    function drawCanvas(canvasX, canvasY) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        for (let i = 0; i < carData.length; i++) {
            drawWire(carData[i].coordinate)
            if (carData[i].isMouseOver) {
                ctx.strokeStyle = "red";
            } else {
                ctx.strokeStyle = "green";
            }
            ctx.stroke()
        }
    }
    //根据传进来的坐标点数组画出一条线
    function drawWire(coordinate) {
        ctx.beginPath();
        for (let j = 0; j < coordinate.length; j++) {
            if (j == 0) {
                ctx.moveTo(coordinate[j].x - 0.5, coordinate[j].y - 0.5)
            } else {
                ctx.lineTo(coordinate[j].x - 0.5, coordinate[j].y - 0.5)
            }
        }
        for (let j = coordinate.length; j > 0; j--) {
            ctx.lineTo(coordinate[j - 1].x + 0.5, coordinate[j - 1].y + 0.5)
        }
        ctx.closePath();
        ctx.stroke()
    }
    //x距离屏幕的位置
    function getX(obj) {
        let parObj = obj;
        let left = obj.offsetLeft;
        while ((parObj = parObj.offsetParent)) {
            left += parObj.offsetLeft;
        }
        return left;
    }
    //y距离屏幕的位置
    function getY(obj) {
        let parObj = obj;
        let top = obj.offsetTop;
        while ((parObj = parObj.offsetParent)) {
            top += parObj.offsetTop;
        }
        return top;
    }
</script>

</html>

图片描述
利用了canvas的isPointInPath方法来检测点是否在图形内,监听坐标不停地判断是否点在图形内,然后重绘图片就可以实现这个功能,click事件性能肯定比mousemove强的多,我这个写法如果项目复杂起来需要判断和重绘的会越来越多,不知道还有没有大神给出其它方案,希望可以解决你的问题~

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题