基于canvas在浏览器上的图片上画线,画出的线条可以自动吸附到附近的人脑医学影像图片黑色区域边上
时间: 2023-05-28 21:05:09 浏览: 66
,实现如下:
1. 获取图片元素及其位置信息。
```
const img = document.getElementById('myImg');
const imgRect = img.getBoundingClientRect();
```
2. 监听鼠标移动事件,根据鼠标位置画线。
```
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
canvas.addEventListener('mousemove', (e) => {
const mouseX = e.clientX - imgRect.left;
const mouseY = e.clientY - imgRect.top;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(mouseX, mouseY);
ctx.lineTo(mouseX + 50, mouseY + 50);
ctx.stroke();
});
```
3. 判断线条与黑色区域的碰撞,如果碰撞则自动吸附。
```
const blackPixels = []; // 黑色像素点坐标数组,由于涉及到图片处理,此处省略
canvas.addEventListener('mousemove', (e) => {
const mouseX = e.clientX - imgRect.left;
const mouseY = e.clientY - imgRect.top;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(mouseX, mouseY);
ctx.lineTo(mouseX + 50, mouseY + 50);
ctx.stroke();
// 判断线条与黑色区域的碰撞
const linePixels = getLinePixels(mouseX, mouseY, mouseX + 50, mouseY + 50);
const isColliding = linePixels.some(pixel => blackPixels.some(blackPixel => pixel[0] === blackPixel[0] && pixel[1] === blackPixel[1]));
// 自动吸附
if (isColliding) {
const nearestPixel = getNearestPixel(linePixels, blackPixels);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(mouseX, mouseY);
ctx.lineTo(nearestPixel[0] - imgRect.left, nearestPixel[1] - imgRect.top);
ctx.stroke();
}
});
// 获取线条上的所有像素点坐标
function getLinePixels(x1, y1, x2, y2) {
const pixels = [];
const dx = Math.abs(x2 - x1);
const dy = Math.abs(y2 - y1);
const sx = x1 < x2 ? 1 : -1;
const sy = y1 < y2 ? 1 : -1;
let err = dx - dy;
let x = x1;
let y = y1;
while (true) {
pixels.push([x, y]);
if (x === x2 && y === y2) {
break;
}
const e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x += sx;
}
if (e2 < dx) {
err += dx;
y += sy;
}
}
return pixels;
}
// 获取线条上离黑色像素点最近的像素点坐标
function getNearestPixel(linePixels, blackPixels) {
let minDistance = Infinity;
let nearestPixel = null;
linePixels.forEach(linePixel => {
blackPixels.forEach(blackPixel => {
const distance = Math.sqrt(Math.pow(linePixel[0] - blackPixel[0], 2) + Math.pow(linePixel[1] - blackPixel[1], 2));
if (distance < minDistance) {
minDistance = distance;
nearestPixel = blackPixel;
}
});
});
return nearestPixel;
}
```
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)