JS/Canvas在图片上画点画线不规则图形,并获取图片上的坐标

直接先上效果

在这里插入图片描述

  • 操作说明:点 【添加区域】 鼠标进行画—— 右键结束画 点【清楚画图】画布初始化,再点【添加区域】画,反复反复,,,,
代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        .wrap{
    

            background: #ccc;
            position: relative;
        }
        .ball{
    
            width:5px;
            height: 5px;
            background: red;
            border-radius: 50%;
            position: absolute;
        }
        .box {
    
            width:416px;
            height:416px;
        }

    </style>
</head>
<body>
<div class="box">
    <div class="wrap">

        <div class="canvas-box" style="width: 416px; height: 416px;" id="Div1"> 
            <canvas id="cvs" width="416" height="416" style="background:url(123.png)">不支持canvas</canvas
这个问题需要使用一些数学和计算机图形学的知识来解决。具体步骤如下: 1. 获取图片并绘制到canvas上。 2. 监听鼠标事件,获取鼠标位置。 3. 根据鼠标位置,计算出线条的起点和终点。 4. 计算线条与图片灰色区域的交点。 5. 将线条的终点自动吸附到交点上。 下面是一个简单的实现示例: ``` // 1. 获取图片并绘制到canvas上 const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); const img = new Image(); img.src = 'image.jpg'; img.onload = () => { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); }; // 2. 监听鼠标事件,获取鼠标位置 let isDrawing = false; let lastX = 0; let lastY = 0; canvas.addEventListener('mousedown', e => { isDrawing = true; lastX = e.offsetX; lastY = e.offsetY; }); canvas.addEventListener('mousemove', e => { if (!isDrawing) return; const currentX = e.offsetX; const currentY = e.offsetY; // 3. 根据鼠标位置,计算出线条的起点和终点 ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(currentX, currentY); ctx.strokeStyle = '#000'; ctx.stroke(); // 4. 计算线条与图片灰色区域的交点 const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; const length = data.length; const grayPixels = []; for (let i = 0; i < length; i += 4) { const gray = (data[i] + data[i + 1] + data[i + 2]) / 3; if (gray < 128) { grayPixels.push({ x: (i / 4) % canvas.width, y: Math.floor(i / (4 * canvas.width)), }); } } const intersections = []; for (let i = 0; i < grayPixels.length - 1; i++) { const p1 = grayPixels[i]; const p2 = grayPixels[i + 1]; const intersection = getLineIntersection(lastX, lastY, currentX, currentY, p1.x, p1.y, p2.x, p2.y); if (intersection) { intersections.push(intersection); } } // 5. 将线条的终点自动吸附到交点上 if (intersections.length > 0) { const closestIntersection = getClosestPoint(currentX, currentY, intersections); ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(closestIntersection.x, closestIntersection.y); ctx.strokeStyle = '#000'; ctx.stroke(); lastX = closestIntersection.x; lastY = closestIntersection.y; } else { lastX = currentX; lastY = currentY; } }); canvas.addEventListener('mouseup', () => { isDrawing = false; }); // 计算两条直线的交点 function getLineIntersection(x1, y1, x2, y2, x3, y3, x4, y4) { const d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (d === 0) { return null; } const x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d; const y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d; if (x < 0 || x > canvas.width || y < 0 || y > canvas.height) { return null; } return { x, y }; } // 计算与目标点最近的交点 function getClosestPoint(x, y, points) { let minDistance = Number.MAX_VALUE; let closestPoint = null; for (const point of points) { const distance = Math.sqrt((x - point.x) ** 2 + (y - point.y) ** 2); if (distance < minDistance) { minDistance = distance; closestPoint = point; } } return closestPoint; } ``` 注意,这只是一个简单的实现示例,还有很多细节需要考虑,比如线条的宽度、灰色区域的阈值、交点的判断等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值