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