From 377cd8bcf1b1ca6c4165f63c770ceabea7a7c5cf Mon Sep 17 00:00:00 2001 From: BroodjeAap Date: Sun, 11 Sep 2022 08:45:43 +0000 Subject: [PATCH] hoverable nodes and more --- static/diagram.js | 66 +++++++++++++++++++++++++++------------- static/diagram.ts | 76 +++++++++++++++++++++++++++++------------------ 2 files changed, 93 insertions(+), 49 deletions(-) diff --git a/static/diagram.js b/static/diagram.js index acf64e7..a6d0f10 100644 --- a/static/diagram.js +++ b/static/diagram.js @@ -1,12 +1,13 @@ var DiagramNode = /** @class */ (function () { function DiagramNode(x, y, width, height, label) { + this.hover = false; this.x = x; this.y = y; this.width = width; this.height = height; this.label = label; } - DiagramNode.prototype.pointInDiagram = function (x, y) { + DiagramNode.prototype.pointInNode = function (x, y) { if (x < this.x) { return false; } @@ -38,6 +39,13 @@ function diagramOnMouseMove(ev) { } var Diagrams = /** @class */ (function () { function Diagrams(canvasId) { + this.nodes = new Array(); + this.connections = new Array(); + this.cameraX = 0; + this.cameraY = 0; + this.panning = false; + this.nodeDragging = null; + this.nodeHover = null; this.canvas = document.getElementById(canvasId); if (this.canvas === null) { throw "Could not getElementById " + canvasId; @@ -48,28 +56,38 @@ var Diagrams = /** @class */ (function () { } _diagram = this; this.ctx = ctx; - this.ctx.font = "30px Arial"; + this.ctx.font = "30px Helvetica"; this.canvas.onmousemove = diagramOnMouseMove; this.canvas.onmousedown = diagramOnMouseDown; this.canvas.onmouseup = diagramOnMouseUp; window.onresize = diargramOnResize; - this.nodes = new Array(); - this.connections = new Array(); - this.cameraX = 0; - this.cameraY = 0; } Diagrams.prototype.onmousemove = function (ev) { + var canvasRect = this.canvas.getBoundingClientRect(); + var mouseX = ev.x - canvasRect.left; + var mouseY = ev.y - canvasRect.top; if (this.panning) { this.cameraX += ev.movementX; this.cameraY += ev.movementY; } - if (this.nodeDrag) { - if (this.nodeDragged === null) { - console.error("nodeDrag==true but nodeDragged==null"); - return; + else if (this.nodeDragging != null) { + this.nodeDragging.x = mouseX - this.cameraX - this.nodeDragging.width / 2; + this.nodeDragging.y = mouseY - this.cameraY - this.nodeDragging.height / 2; + } + else if (this.nodeHover != null) { + if (!this.nodeHover.pointInNode(mouseX - this.cameraX, mouseY - this.cameraY)) { + this.nodeHover.hover = false; + this.nodeHover = null; + } + } + else { + for (var _i = 0, _a = this.nodes; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.pointInNode(mouseX - this.cameraX, mouseY - this.cameraY)) { + node.hover = true; + this.nodeHover = node; + } } - this.nodeDragged.x += ev.movementX; - this.nodeDragged.y += ev.movementY; } this.draw(); }; @@ -82,9 +100,8 @@ var Diagrams = /** @class */ (function () { var mouseY = ev.y - canvasRect.top; for (var _i = 0, _a = this.nodes; _i < _a.length; _i++) { var node = _a[_i]; - if (node.pointInDiagram(mouseX, mouseY)) { - this.nodeDrag = true; - this.nodeDragged = node; + if (node.pointInNode(mouseX - this.cameraX, mouseY - this.cameraY)) { + this.nodeDragging = node; return; } } @@ -92,8 +109,7 @@ var Diagrams = /** @class */ (function () { }; Diagrams.prototype.onmouseup = function (ev) { this.panning = false; - this.nodeDrag = false; - this.nodeDragged = null; + this.nodeDragging = null; }; Diagrams.prototype.drawBackground = function () { this.ctx.fillStyle = "#D8D8D8"; @@ -105,13 +121,23 @@ var Diagrams = /** @class */ (function () { Diagrams.prototype.draw = function () { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.drawBackground(); + var fullCircleRadians = Math.PI + (Math.PI * 3); for (var _i = 0, _a = this.nodes; _i < _a.length; _i++) { var node = _a[_i]; - this.ctx.fillStyle = "gray"; + this.ctx.fillStyle = node.hover ? "#303030" : "#161616"; this.ctx.fillRect(node.x + this.cameraX, node.y + this.cameraY, node.width, node.height); - this.ctx.fillStyle = "black"; - this.ctx.font = "30px Arial"; + this.ctx.fillStyle = "#D3D3D3"; + this.ctx.font = "30px Helvetica"; this.ctx.fillText(node.label, node.x + this.cameraX + node.height / 2, node.y + this.cameraY + node.height / 1.5); + this.ctx.strokeStyle = "red"; + this.ctx.fillStyle = "red"; + this.ctx.beginPath(); + this.ctx.arc(node.x + this.cameraX, node.y + node.height / 2 + this.cameraY, node.height / 3, 0, fullCircleRadians); + this.ctx.fill(); + this.ctx.moveTo(node.x + node.width + this.cameraX, node.y + node.height / 2 + this.cameraY); + this.ctx.arc(node.x + node.width + this.cameraX, node.y + node.height / 2 + this.cameraY, node.height / 3, 0, fullCircleRadians); + this.ctx.fill(); + this.ctx.closePath(); } }; Diagrams.prototype.addNode = function (x, y, label) { diff --git a/static/diagram.ts b/static/diagram.ts index 235f685..e8cef40 100644 --- a/static/diagram.ts +++ b/static/diagram.ts @@ -5,6 +5,8 @@ class DiagramNode { width: number; height: number; + hover: boolean = false; + parents: Array; children: Array; @@ -22,7 +24,7 @@ class DiagramNode { this.label = label; } - pointInDiagram(x: number, y: number){ + pointInNode(x: number, y: number){ if (x < this.x){ return false; } @@ -57,17 +59,17 @@ class Diagrams { canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D; - nodes: Array; + nodes: Array = new Array(); - connections: Array<[DiagramNode, DiagramNode]>; + connections: Array<[DiagramNode, DiagramNode]> = new Array(); - cameraX: number; - cameraY: number; + cameraX: number = 0; + cameraY: number = 0; - panning: boolean; + panning: boolean = false; - nodeDrag: boolean; - nodeDragged: DiagramNode | null; + nodeDragging: DiagramNode | null = null; + nodeHover: DiagramNode | null = null; constructor(canvasId: string){ this.canvas = document.getElementById(canvasId) as HTMLCanvasElement; @@ -80,31 +82,39 @@ class Diagrams { } _diagram = this; this.ctx = ctx; - this.ctx.font = "30px Arial"; + this.ctx.font = "30px Helvetica"; this.canvas.onmousemove = diagramOnMouseMove; this.canvas.onmousedown = diagramOnMouseDown; this.canvas.onmouseup = diagramOnMouseUp; window.onresize = diargramOnResize; - - this.nodes = new Array(); - this.connections = new Array(); - - this.cameraX = 0; - this.cameraY = 0; } onmousemove(ev: MouseEvent){ + let canvasRect = this.canvas.getBoundingClientRect(); + let mouseX = ev.x - canvasRect.left; + let mouseY = ev.y - canvasRect.top; + if (this.panning){ this.cameraX += ev.movementX; this.cameraY += ev.movementY; } - if (this.nodeDrag){ - if (this.nodeDragged === null){ - console.error("nodeDrag==true but nodeDragged==null"); - return + else if (this.nodeDragging != null){ + this.nodeDragging.x = mouseX - this.cameraX - this.nodeDragging.width / 2; + this.nodeDragging.y = mouseY - this.cameraY - this.nodeDragging.height / 2; + } + else if (this.nodeHover != null){ + if (!this.nodeHover.pointInNode(mouseX - this.cameraX, mouseY - this.cameraY)){ + this.nodeHover.hover = false; + this.nodeHover = null; + } + } + else { + for (let node of this.nodes){ + if (node.pointInNode(mouseX - this.cameraX, mouseY - this.cameraY)){ + node.hover = true; + this.nodeHover = node; + } } - this.nodeDragged.x += ev.movementX; - this.nodeDragged.y += ev.movementY; } this.draw(); } @@ -117,9 +127,8 @@ class Diagrams { let mouseX = ev.x - canvasRect.left; let mouseY = ev.y - canvasRect.top; for (let node of this.nodes){ - if (node.pointInDiagram(mouseX, mouseY)) { - this.nodeDrag = true; - this.nodeDragged = node; + if (node.pointInNode(mouseX - this.cameraX, mouseY - this.cameraY)) { + this.nodeDragging = node; return; } } @@ -129,8 +138,7 @@ class Diagrams { onmouseup(ev: MouseEvent){ this.panning = false; - this.nodeDrag = false; - this.nodeDragged = null; + this.nodeDragging = null; } drawBackground(){ @@ -144,16 +152,26 @@ class Diagrams { draw(){ this.ctx.clearRect(0,0, this.canvas.width, this.canvas.height); this.drawBackground(); + let fullCircleRadians = Math.PI + (Math.PI * 3); for (let node of this.nodes){ - this.ctx.fillStyle = "gray"; + this.ctx.fillStyle = node.hover ? "#303030" : "#161616"; this.ctx.fillRect(node.x + this.cameraX, node.y + this.cameraY, node.width, node.height); - this.ctx.fillStyle = "black"; - this.ctx.font = "30px Arial"; + this.ctx.fillStyle = "#D3D3D3"; + this.ctx.font = "30px Helvetica"; this.ctx.fillText( node.label, node.x + this.cameraX + node.height / 2, node.y + this.cameraY + node.height / 1.5 ); + this.ctx.strokeStyle = "red"; + this.ctx.fillStyle = "red"; + this.ctx.beginPath() + this.ctx.arc(node.x + this.cameraX, node.y + node.height / 2 + this.cameraY, node.height / 3, 0, fullCircleRadians); + this.ctx.fill(); + this.ctx.moveTo(node.x + node.width + this.cameraX, node.y + node.height / 2 + this.cameraY); + this.ctx.arc(node.x + node.width + this.cameraX, node.y + node.height / 2 + this.cameraY, node.height / 3, 0, fullCircleRadians); + this.ctx.fill(); + this.ctx.closePath(); } }