navinfo-web-sdk
Version:
NavinfoWebSDK
251 lines (197 loc) • 5.98 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CanvasTest</title>
<style>
html, body {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background: gray;
}
.canvas {
background: white;
border: 1px black solid;
}
</style>
</head>
<body>
<canvas
id="canvas"
class="canvas"
width="400px"
height="400px"
></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const maxScale = 2;
const minScale = 0.2;
let gWidth = 400;
let gHeight = 400;
let gResolution = 1;
let gScale = 1;
let gOriginX = 0;
let gOriginY = 0;
let gImage = null;
let gDrag = false;
let lastX = 0;
let lastY = 0;
bindEvent(canvas);
drawGrid(ctx, gWidth, gHeight, 10);
loadImage('./test.jpg', img => {
gImage = img;
computeTransform();
redraw(ctx);
});
function redraw(ctx) {
ctx.resetTransform();
clear(ctx, 'white');
drawGrid(ctx, gWidth, gHeight, 10);
// updateTransform();
drawImage(ctx, gImage);
drawLineString(ctx);
}
function clear(ctx, color) {
ctx.save();
ctx.fillStyle = color;
ctx.fillRect(0, 0, gWidth, gHeight);
ctx.restore();
}
function loadImage(src, func) {
const img = new Image();
img.onload = () => {
func(img);
};
img.src = src;
}
function computeTransform() {
const naturalWidth = gImage.naturalWidth;
const naturalHeight = gImage.naturalHeight;
const scaleX = gWidth / naturalWidth;
const scaleY = gHeight / naturalHeight;
const scale = Math.min(scaleX, scaleY);
gScale = scale;
gOriginX = -(gWidth / gScale - naturalWidth) / 2;
gOriginY = -(gHeight / gScale - naturalHeight) / 2;
}
function updateTransform() {
ctx.setTransform(gScale, 0, 0, gScale, gOffsetX, gOffsetY);
}
function drawImage(ctx, image) {
const naturalWidth = image.naturalWidth;
const naturalHeight = image.naturalHeight;
const x = 0 - gOriginX;
const y = 0 - gOriginY;
ctx.drawImage(image, x * gScale, y * gScale, naturalWidth * gScale, naturalHeight * gScale);
}
function drawGrid(ctx, width, height, unit) {
ctx.save();
ctx.beginPath();
const rows = height / unit;
const cols = width / unit;
for (let i = 1; i < rows; ++i) {
const y = unit * i;
ctx.moveTo(0, y);
ctx.lineTo(400, y);
}
for (let j = 1; j < cols; ++j) {
const x = unit * j;
ctx.moveTo(x, 0);
ctx.lineTo(x, 400);
}
ctx.stroke();
ctx.restore();
}
function drawLineString(ctx) {
ctx.strokeStyle = 'red';
let line = [
[0, 300],
[400, 0],
[800, 300],
[400, 600],
[0, 300],
];
line = line.map(item => worldToScreen(item[0], item[1]));
ctx.beginPath();
ctx.moveTo(line[0][0], line[0][1]);
for (let i = 1; i < line.length; ++i) {
ctx.lineTo(line[i][0], line[i][1]);
}
ctx.stroke();
}
function worldToScreen(x, y) {
const xs = (x - gOriginX) * gScale;
const ys = (y - gOriginY) * gScale;
return [xs, ys];
}
function screenToWorld(x, y) {
const xw = gOriginX + x / gScale;
const yw = gOriginY + y / gScale;
return [xw, yw];
}
function bindEvent(canvas) {
canvas.addEventListener('wheel', e => {
let scale = 0;
if (event.deltaY > 0) {
if (gScale <= minScale) {
return true;
}
scale = gScale - 0.1;
} else {
if (gScale >= maxScale) {
return true;
}
scale = gScale + 0.1;
}
const x = e.offsetX / gScale + gOriginX;
gOriginX = x - (x - gOriginX) * gScale / scale;
const y = e.offsetY / gScale + gOriginY;
gOriginY = y - (y - gOriginY) * gScale / scale;
gScale = scale;
redraw(ctx);
});
canvas.addEventListener('mousedown', e => {
gDrag = true;
lastX = e.offsetX;
lastY = e.offsetY;
});
canvas.addEventListener('mousemove', e => {
console.log(e.button);
if (!gDrag) {
return;
}
const offsetX = e.offsetX - lastX;
const offsetY = e.offsetY - lastY;
gOriginX -= offsetX / gScale;
gOriginY -= offsetY / gScale;
lastX = e.offsetX;
lastY = e.offsetY;
redraw(ctx);
});
canvas.addEventListener('mouseup', e => {
gDrag = false;
});
canvas.addEventListener('dragstart', e => {
console.log(e);
});
document.addEventListener('click', e => {
const x = e.offsetX;
const y = e.offsetY;
const coor = screenToWorld(x, y);
console.log(coor);
});
// canvas.addEventListener('mouseleave', e => {
// gDrag = false;
// });
}
</script>
</body>
</html>