Last active
March 21, 2024 10:06
-
-
Save klevcsoo/86ff50ffa7d8d157166fe18a9c4b1c0f to your computer and use it in GitHub Desktop.
A simple map renderer in Typescript using the Canvas API. I found it in an old project of mine.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function attachMapRenderer(canvas: HTMLCanvasElement, mapUrl: string) { | |
const img = new Image(); img.src = mapUrl; | |
img.onload = () => { | |
const wCanvas = canvas.width, hCanvas = canvas.height; | |
const wImg = img.width, hImg = img.height; | |
const dragMarginX = wImg - wCanvas, dragMarginY = hImg - hCanvas; | |
const ctx = canvas.getContext('2d'); | |
if (!ctx) throw new Error('Canvas API error'); | |
let confirmedPos = [ 0, 0 ]; | |
let dragging = false; | |
let dragStartPos = [ 0, 0 ]; | |
let dragMovePos = [ ...confirmedPos ]; | |
let zoomScale = 1; | |
const drawMap = () => { | |
ctx.save(); ctx.setTransform(1, 0, 0, 1, 0, 0); | |
ctx.clearRect(0, 0, wCanvas, hCanvas); ctx.restore(); | |
ctx.drawImage( | |
img, dragMovePos[ 0 ], dragMovePos[ 1 ], | |
wCanvas * zoomScale, hCanvas * zoomScale, | |
0, 0, wCanvas, hCanvas | |
); | |
/* | |
Draw optional map data, points of interest, overlays, | |
other stuff over the map. Example: | |
mapData.forEach((poi) => { | |
const [ x, y ] = poi.location.map((v, i) => v - dragMovePos[ i ]); | |
const rs = renderStyle[ poi.type ]; | |
const textOffset = rs.drawIndicator(ctx, [ x, y ]); | |
ctx.fillText(poi.name, x + textOffset[ 0 ], y + textOffset[ 1 ]); | |
}); | |
*/ | |
/* | |
Draw optional debug information. Example: | |
ctx.font = '14px Arial'; | |
ctx.fillText(`confirmed_pos=${ confirmedPos }`, 20, hCanvas - 80); | |
ctx.fillText(`drag_start_pos=${ dragStartPos }`, 20, hCanvas - 60); | |
ctx.fillText(`drag_move_pos=${ dragMovePos }`, 20, hCanvas - 40); | |
ctx.fillText(`zoom_scale=${ zoomScale }`, 20, hCanvas - 20); | |
*/ | |
}; | |
const stopDrag = () => { dragging = false; confirmedPos = [ ...dragMovePos ]; drawMap(); }; | |
// ---------- CANVAS EVENTS ---------- | |
canvas.onmousedown = ({ clientX: x, clientY: y }) => { | |
dragging = true; dragStartPos = [ x, y ]; | |
}; | |
canvas.onmouseup = () => { | |
stopDrag(); | |
}; | |
canvas.onmouseleave = () => { | |
stopDrag(); | |
}; | |
canvas.onmousemove = (event) => { | |
event.preventDefault(); | |
if (!dragging) return; | |
const { clientX: x, clientY: y } = event; | |
const tx = confirmedPos[ 0 ] + (dragStartPos[ 0 ] - x); | |
const ty = confirmedPos[ 1 ] + (dragStartPos[ 1 ] - y); | |
dragMovePos[ 0 ] = tx <= 0 ? 0 : tx >= dragMarginX ? dragMarginX : tx; | |
dragMovePos[ 1 ] = ty <= 0 ? 0 : ty >= dragMarginY ? dragMarginY : ty; | |
drawMap(); | |
}; | |
drawMap(); | |
}; | |
} | |
export default attachMapRenderer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment