diff options
author | sanine <sanine.not@pm.me> | 2022-05-31 22:54:59 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-05-31 22:54:59 -0500 |
commit | f82f540a0cf07e8fd95e36dea10a49aa839832d0 (patch) | |
tree | a0855b56182f521781a0b33247e5f08a23604f1f | |
parent | 5efc7885e1c3959aa165be640858ffb3f8a5860b (diff) |
move test.js and package.json to the root
-rw-r--r-- | notes.md | 24 | ||||
-rw-r--r-- | package.json (renamed from src/package.json) | 0 | ||||
-rw-r--r-- | src/Canvas.js | 144 | ||||
-rw-r--r-- | test.js (renamed from src/test.js) | 0 |
4 files changed, 24 insertions, 144 deletions
@@ -67,3 +67,27 @@ would represent things like individual buildings and only be visible when highly Node should be able to indicate things like climate regions or land use patterns as well, and those kinds of nodes should be on their own layers, so that the user can view or ignore relevant data at any time. + + +nodes +----- + +node types: + - point + - path + - polygon + +all nodes can be selected to view properties in the right pane. They can then be edited by clicking a button on the pane. + +All nodes can be moved when editing. Path and polygon nodes can have their constituent points moved and can insert new nodes. + +Nodes have an associated "relevance level" + + - building (smallest) + - neighborhood + - city + - province + - nation + - global (largest) + +depending on a map's scale, some of these may not be relevant (i.e. a map only showing a city would not use higher relevance levels). diff --git a/src/package.json b/package.json index bedb411..bedb411 100644 --- a/src/package.json +++ b/package.json diff --git a/src/Canvas.js b/src/Canvas.js deleted file mode 100644 index 6dff7bd..0000000 --- a/src/Canvas.js +++ /dev/null @@ -1,144 +0,0 @@ -import { clamp } from './modules/Util.js'; - -class Canvas { - constructor(rootId) { - const root = document.getElementById(rootId); - - this.element = document.createElement('canvas'); - this.context = this.element.getContext('2d'); - - /* state variables */ - this.scale = 1; - this.zoom = 1; - const ZOOM_SPEED = 1.2; - - this.mouse = { - screenPos: { x: 0, y: 0 }, - drawingPos: { x: 0, y: 0 }, - }; - this.pan = { x: 0, y: 0 }; - this.panning = false; - - /* callbacks */ - this.onDraw = null; - this.onMouseMove = null; - this.onMouseDown = null; - this.onMouseUp = null; - - /* register event listeners */ - - /* mouse movement */ - this.element.addEventListener('mousemove', e => { - this.mouse.screenPos.x = e.offsetX; - this.mouse.screenPos.y = e.offsetY; - - const [xd, yd] = this.screenToDrawingPos(e.offsetX, e.offsetY); - - /* compute movement */ - const dx = e.movementX / (this.zoom * this.scale); - const dy = e.movementY / (this.zoom * this.scale); - - /* pan? */ - if (this.panning) { - this.pan.x += dx; - this.pan.y += dy; - this.setTransform(); - } - - this.mouse.drawingPos.x = xd; - this.mouse.drawingPos.y = yd; - - if (this.onMouseMove) this.onMouseMove(this.mousePos); - }); - - /* clicking */ - this.element.addEventListener('mousedown', e => { - e.preventDefault(); - if (e.button === 1) this.panning = true; - if (this.onMouseDown) this.onMouseDown(e); - }); - this.element.addEventListener('mouseup', e => { - if (e.button === 1) this.panning = false; - if (this.onMouseUp) this.onMouseUp(e); - }); - - /* mouse leave */ - this.element.addEventListener('mouseleave', e => { - this.panning = false; - }); - - /* mouse wheel */ - this.element.addEventListener('wheel', e => { - if (this.panning) return; // don't zoom and pan simultaneously - - const delta = e.deltaY < 0 ? ZOOM_SPEED : 1/ZOOM_SPEED; - const alpha = (1/delta) - 1; - - /* zoom in */ - this.zoom *= delta; - this.zoom = clamp(this.zoom, 1, 1000); - this.setTransform(); - - /* pan to keep mouse in the same place */ - const [mouseX, mouseY] = this.screenToDrawingPos(this.mouse.screenPos.x, this.mouse.screenPos.y); - this.pan.x += mouseX - this.mouse.drawingPos.x; - this.pan.y += mouseY - this.mouse.drawingPos.y; - this.setTransform(); - this.draw(); - }); - - /* finalize setup */ - this.fillWindow(); - window.addEventListener('resize', () => this.fillWindow()); - root.appendChild(this.element); - } - - setTransform() { - /* clamp pan */ - const xMax = this.pixelsToUnits(this.element.width) - 1; - const yMax = this.pixelsToUnits(this.element.height) - 1; - this.pan.x = clamp(this.pan.x, xMax, 0); - this.pan.y = clamp(this.pan.y, yMax, 0); - - this.context.setTransform(1, 0, 0, 1, 0, 0); - this.context.scale(this.zoom * this.scale, this.zoom * this.scale); - this.context.translate(this.pan.x, this.pan.y); - } - - fillWindow() { - const width = window.innerWidth; - const height = window.innerHeight; - this.scale = Math.max(width, height); - - this.element.width = width; this.element.height = height; - this.setTransform(); - - this.draw(); - } - - pixelsToUnits(value) { - return value / this.zoom / this.scale; - } - - unitsToPixels(value) { - return value * this.zoom * this.scale; - } - - screenToDrawingPos(xs, ys) { - const matrix = this.context.getTransform(); - matrix.invertSelf(); - - /* compute drawing-space position */ - const x = matrix.a*xs + matrix.b*ys + matrix.e; - const y = matrix.c*xs + matrix.d*ys + matrix.f; - - return [ x, y ]; - } - - draw() { - this.context.clearRect(0, 0, 1, 1); - if (this.onDraw) this.onDraw(this.context); - } -} - -export default Canvas; |