background
According to business requirements, the mobile terminal of unmanned vehicles in the park needs to load maps. Personally, I gave four solutions at that time
- Reuse our existing map (but is looking for a third party development, and no source code, speechless)
- The solution of 3D map, top view Angle, babylonJs (this was done on the Web end before, but it is heavy on the mobile end, and there is only lane line, building and so on on the Web end, and the page end needs to be a TWO-DIMENSIONAL plane, there is no need for 3D)
- Two dimensional map, load images directly. (This method is the most convenient, but requires the conversion of multiple coordinates)
- Two dimensional map, based on map information, every stroke of their own drawing. (This should be a lot of trouble to think about, but drawing your own is more flexible)
Ps: Baidu, Autonavi and other APIS cannot be used because it is the park map.
Technology selection
Except for eliminating 1, we can consider the other three. The babylonJS scheme has been done before. As long as the overhead view is fixed, the performance is not tested. Building is not drawing due to the lack of data.
The basic requirements
- Map zoom + move
- The icon is located in the middle of the map, indicating the starting point (like taxi APP, you move the map, not the starting point).
- Coordinate conversion (Canvas coordinate, Img coordinate, space coordinate)
The corresponding relationship between Img coordinates and space coordinates is informed by the server. The front end needs to handle canvas coordinates and Img coordinates.
Code implementation
html
I’ll just draw a canvas
<div style="width:800px; height:800px; border: red solid 1px"> <canvas id="canvas" width="800" height="800"></canvas> </div>Copy the code
js
Let’s start with a canvas core function
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
Copy the code
parameter | describe |
---|---|
img | Specify the image, canvas, or video to use. |
sx | Optional. The x position at which the shear began. |
sy | Optional. The y position where the shear started. |
swidth | Optional. The width of the clipped image. |
sheight | Optional. The height of the clipped image. |
x | Place the x position of the image on the canvas. |
y | Place the y coordinate position of the image on the canvas. |
width | Optional. The width of the image to use. (Stretch or zoom out image) |
height | Optional. The height of the image to use. (Stretch or zoom out image) |
Simply put, parameters 2-5 are displayed map information, and parameters 6-9 are displayed window information. X and y are the upper left corner of the map. Width /height needs to take into account scale
context.drawImage(img, 0, 0, img.width, img.height, imgX, imgY, img.width * imgScale, img.height * imgScale);
Copy the code
ImgX, imgY, imgScale, zoomed and moved.
mobile
canvas.onmousedown = function (event) { var pos = windowToCanvas(canvas, event.clientX, event.clientY); let xx = (event.clientX - imgX) / imgScale let yy = (event.clientY - imgY) / imgScale console.log('pos in img:', xx, Width, img.height, canvas.onmousemove = function (event) {canvas.style.cursor = "move"; var pos1 = windowToCanvas(canvas, event.clientX, event.clientY); var x = pos1.x - pos.x; var y = pos1.y - pos.y; pos = pos1; imgX += x; imgY += y; drawImage(); } canvas.onmouseup = function () { canvas.onmousemove = null; canvas.onmouseup = null; canvas.style.cursor = "default"; }}Copy the code
The zoom
var flag = 1 canvas.onmousewheel = canvas.onwheel = function (event) { var pos = windowToCanvas(canvas, event.clientX, event.clientY); event.wheelDelta = event.wheelDelta ? event.wheelDelta : (event.deltaY * (-40)); If (flag) {flag = 0 if (event.wheeldelta > 0) {imgScale *= 1.2; ImgX = imgX * 1.2-pos.x; // imgY = imgY * 1.2-pos. Y; } else {imgScale *= 0.8; ImgX = imgX * 0.8 + pos.x * 0.8; // imgY = imgY * 0.8 + pos.y * 0.8; } drawImage(); setTimeout(() => { flag = 1 }, 500) } event.preventDefault(); // Disable scaling}Copy the code
details
When you zoom, the browser zooms in. That is, not just the Img zoom in canvas. Event.preventdefault (); Block browser default events.
Coordinate transformation
Canvas coordinates are converted to IMG coordinates. Assuming the canvas coordinate is (x,y), it doesn’t have to be the user clicking, for example, our little green dot (indicating the current position, which is not moving) to get the coordinate of the top left corner of img in the canvas is (imgX, imgY), and the corresponding img coordinate is (0,0).
Let iX = (x-imgx)/imgScale let iY = (y-imgy)/imgScale console.log('img Axis :', iX, iY)Copy the code
figure
So that’s pretty much what you need and then you realize that it’s not going to work on mobile and you can just change the mouse related events to touch events. Update it tomorrow and put the source code together