Canvas加载图片并可缩放并可点击绘制点及图片像素点坐标
浮华与是非 10/22/2024 Canvas
# 前言
与人员定位系统对接时,有个获取图片指定位置的像素图标(以图片的左上角为(0,0)点)。
# 一、原生js方式
用原生的点击事件和event中的layerX和layerY,发现可行。
<body>
<img src="./0.jpg" />
<script>
document.addEventListener('click',(event)=>{
console.log(event.layerX,event.layerY);
})
</script>
</body>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
但是有几个不便:
- 1.图片很大,会出现上下、左右的滚动条;
- 2.缩放只能靠缩放浏览器的缩放来控制;
- 3.后续绘制线、面貌似没有可行度。
# 二、用canvas方式
有一个想法,就是将canvas当作地图,可以缩放、平移、点击、绘制;图片是就是地图,坐标原点是图片的左上角。 查找了这方面的例子,有个相近的,稍微改改就能用,下面是修改后的代码:
<body>
<canvas id="canvas" width="800" height="800"></canvas>
<script type="text/javascript" src="main.js"></script>
</body>
1
2
3
4
2
3
4
main.js
var canvas, cxt;
var img,//图片对象
imgIsLoaded,//图片是否加载完成;
imgX = 0, // 在canvas上放置图片x坐标;
imgY = 0, // 在canvas上放置图片y坐标;
imgScale = 1;
canvas = document.getElementById('canvas');
cxt = canvas.getContext('2d');
loadImg();
function loadImg() {
img = new Image();
img.onload = function () {
imgIsLoaded = true;
drawImage();
}
img.src = "0.jpg";
}
function drawImage() {
cxt.clearRect(0, 0, canvas.width, canvas.height);
// drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
// img 规定要使用的图像、画布或视频。
// sx 可选。开始剪切的 x 坐标位置。
// sy 可选。开始剪切的 y 坐标位置。
// swidth 可选。被剪切图像的宽度。
// sheight 可选。被剪切图像的高度。
// x 在画布上放置图像的 x 坐标位置。
// y 在画布上放置图像的 y 坐标位置。
// width 可选。要使用的图像的宽度。(伸展或缩小图像)
// height 可选。要使用的图像的高度。(伸展或缩小图像)
cxt.drawImage(img, 0, 0, img.width, img.height, imgX, imgY, img.width * imgScale, img.height * imgScale);
}
canvas.onmousedown = function (event) {
var pos = windowToCanvas(canvas, event.clientX, event.clientY); // 当前canvas坐标
canvas.onmousemove = function (event) {
canvas.onclick = null;
canvas.style.cursor = "move";
var pos1 = windowToCanvas(canvas, event.clientX, event.clientY);
var x = pos1.x - pos.x; // canvas坐标中的鼠标偏移量x
var y = pos1.y - pos.y; // canvas坐标中的鼠标偏移量y
pos = pos1; // 现在canvas坐标
imgX += x;
imgY += y;
drawImage();
}
canvas.onmouseup = function () {
canvas.onmousemove = null;
canvas.onmouseup = null;
canvas.style.cursor = "default";
}
canvas.onclick = getImagePointPixel;
}
canvas.onmousewheel = canvas.onwheel = function (event) {
var pos = windowToCanvas(canvas, event.clientX, event.clientY);
event.wheelDelta = event.wheelDelta ? event.wheelDelta : (event.deltaY * (-40));
if (event.wheelDelta > 0) {
imgScale *= 2;
imgX = imgX * 2 - pos.x;
imgY = imgY * 2 - pos.y;
} else {
imgScale /= 2;
imgX = imgX * 0.5 + pos.x * 0.5;
imgY = imgY * 0.5 + pos.y * 0.5;
}
drawImage();
}
// 屏幕坐标转换为canvas坐标
function windowToCanvas(canvas, x, y) {
var rect = canvas.getBoundingClientRect();
return {
x: x - rect.left - (rect.width - canvas.width) / 2,
y: y - rect.top - (rect.height - canvas.height) / 2
};
}
// 鼠标点击事件处理函数
canvas.onclick = getImagePointPixel;
function getImagePointPixel(e) {
var rect = canvas.getBoundingClientRect();
var x = e.clientX - rect.left - imgX;
var y = e.clientY - rect.top - imgY;
x = Math.round(x / imgScale);
y = Math.round(y / imgScale);
// 鼠标在图片上的像素坐标
console.log(`{ "x":${x}, "y":${y} }`)
cxt.beginPath();
cxt.fillStyle = 'red';
cxt.arc(e.clientX, e.clientY, 5, 0, 2 * Math.PI); // 绘制一个圆形,作为点
cxt.fill();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99