hoverable nodes and more

This commit is contained in:
BroodjeAap 2022-09-11 08:45:43 +00:00
parent d4be01166c
commit 377cd8bcf1
2 changed files with 93 additions and 49 deletions

View file

@ -1,12 +1,13 @@
var DiagramNode = /** @class */ (function () { var DiagramNode = /** @class */ (function () {
function DiagramNode(x, y, width, height, label) { function DiagramNode(x, y, width, height, label) {
this.hover = false;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.width = width; this.width = width;
this.height = height; this.height = height;
this.label = label; this.label = label;
} }
DiagramNode.prototype.pointInDiagram = function (x, y) { DiagramNode.prototype.pointInNode = function (x, y) {
if (x < this.x) { if (x < this.x) {
return false; return false;
} }
@ -38,6 +39,13 @@ function diagramOnMouseMove(ev) {
} }
var Diagrams = /** @class */ (function () { var Diagrams = /** @class */ (function () {
function Diagrams(canvasId) { 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); this.canvas = document.getElementById(canvasId);
if (this.canvas === null) { if (this.canvas === null) {
throw "Could not getElementById " + canvasId; throw "Could not getElementById " + canvasId;
@ -48,28 +56,38 @@ var Diagrams = /** @class */ (function () {
} }
_diagram = this; _diagram = this;
this.ctx = ctx; this.ctx = ctx;
this.ctx.font = "30px Arial"; this.ctx.font = "30px Helvetica";
this.canvas.onmousemove = diagramOnMouseMove; this.canvas.onmousemove = diagramOnMouseMove;
this.canvas.onmousedown = diagramOnMouseDown; this.canvas.onmousedown = diagramOnMouseDown;
this.canvas.onmouseup = diagramOnMouseUp; this.canvas.onmouseup = diagramOnMouseUp;
window.onresize = diargramOnResize; window.onresize = diargramOnResize;
this.nodes = new Array();
this.connections = new Array();
this.cameraX = 0;
this.cameraY = 0;
} }
Diagrams.prototype.onmousemove = function (ev) { 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) { if (this.panning) {
this.cameraX += ev.movementX; this.cameraX += ev.movementX;
this.cameraY += ev.movementY; this.cameraY += ev.movementY;
} }
if (this.nodeDrag) { else if (this.nodeDragging != null) {
if (this.nodeDragged === null) { this.nodeDragging.x = mouseX - this.cameraX - this.nodeDragging.width / 2;
console.error("nodeDrag==true but nodeDragged==null"); this.nodeDragging.y = mouseY - this.cameraY - this.nodeDragging.height / 2;
return; }
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(); this.draw();
}; };
@ -82,9 +100,8 @@ var Diagrams = /** @class */ (function () {
var mouseY = ev.y - canvasRect.top; var mouseY = ev.y - canvasRect.top;
for (var _i = 0, _a = this.nodes; _i < _a.length; _i++) { for (var _i = 0, _a = this.nodes; _i < _a.length; _i++) {
var node = _a[_i]; var node = _a[_i];
if (node.pointInDiagram(mouseX, mouseY)) { if (node.pointInNode(mouseX - this.cameraX, mouseY - this.cameraY)) {
this.nodeDrag = true; this.nodeDragging = node;
this.nodeDragged = node;
return; return;
} }
} }
@ -92,8 +109,7 @@ var Diagrams = /** @class */ (function () {
}; };
Diagrams.prototype.onmouseup = function (ev) { Diagrams.prototype.onmouseup = function (ev) {
this.panning = false; this.panning = false;
this.nodeDrag = false; this.nodeDragging = null;
this.nodeDragged = null;
}; };
Diagrams.prototype.drawBackground = function () { Diagrams.prototype.drawBackground = function () {
this.ctx.fillStyle = "#D8D8D8"; this.ctx.fillStyle = "#D8D8D8";
@ -105,13 +121,23 @@ var Diagrams = /** @class */ (function () {
Diagrams.prototype.draw = function () { Diagrams.prototype.draw = function () {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.drawBackground(); this.drawBackground();
var fullCircleRadians = Math.PI + (Math.PI * 3);
for (var _i = 0, _a = this.nodes; _i < _a.length; _i++) { for (var _i = 0, _a = this.nodes; _i < _a.length; _i++) {
var node = _a[_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.fillRect(node.x + this.cameraX, node.y + this.cameraY, node.width, node.height);
this.ctx.fillStyle = "black"; this.ctx.fillStyle = "#D3D3D3";
this.ctx.font = "30px Arial"; 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.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) { Diagrams.prototype.addNode = function (x, y, label) {

View file

@ -5,6 +5,8 @@ class DiagramNode {
width: number; width: number;
height: number; height: number;
hover: boolean = false;
parents: Array<DiagramNode>; parents: Array<DiagramNode>;
children: Array<DiagramNode>; children: Array<DiagramNode>;
@ -22,7 +24,7 @@ class DiagramNode {
this.label = label; this.label = label;
} }
pointInDiagram(x: number, y: number){ pointInNode(x: number, y: number){
if (x < this.x){ if (x < this.x){
return false; return false;
} }
@ -57,17 +59,17 @@ class Diagrams {
canvas: HTMLCanvasElement; canvas: HTMLCanvasElement;
ctx: CanvasRenderingContext2D; ctx: CanvasRenderingContext2D;
nodes: Array<DiagramNode>; nodes: Array<DiagramNode> = new Array();
connections: Array<[DiagramNode, DiagramNode]>; connections: Array<[DiagramNode, DiagramNode]> = new Array();
cameraX: number; cameraX: number = 0;
cameraY: number; cameraY: number = 0;
panning: boolean; panning: boolean = false;
nodeDrag: boolean; nodeDragging: DiagramNode | null = null;
nodeDragged: DiagramNode | null; nodeHover: DiagramNode | null = null;
constructor(canvasId: string){ constructor(canvasId: string){
this.canvas = document.getElementById(canvasId) as HTMLCanvasElement; this.canvas = document.getElementById(canvasId) as HTMLCanvasElement;
@ -80,31 +82,39 @@ class Diagrams {
} }
_diagram = this; _diagram = this;
this.ctx = ctx; this.ctx = ctx;
this.ctx.font = "30px Arial"; this.ctx.font = "30px Helvetica";
this.canvas.onmousemove = diagramOnMouseMove; this.canvas.onmousemove = diagramOnMouseMove;
this.canvas.onmousedown = diagramOnMouseDown; this.canvas.onmousedown = diagramOnMouseDown;
this.canvas.onmouseup = diagramOnMouseUp; this.canvas.onmouseup = diagramOnMouseUp;
window.onresize = diargramOnResize; window.onresize = diargramOnResize;
this.nodes = new Array();
this.connections = new Array();
this.cameraX = 0;
this.cameraY = 0;
} }
onmousemove(ev: MouseEvent){ onmousemove(ev: MouseEvent){
let canvasRect = this.canvas.getBoundingClientRect();
let mouseX = ev.x - canvasRect.left;
let mouseY = ev.y - canvasRect.top;
if (this.panning){ if (this.panning){
this.cameraX += ev.movementX; this.cameraX += ev.movementX;
this.cameraY += ev.movementY; this.cameraY += ev.movementY;
} }
if (this.nodeDrag){ else if (this.nodeDragging != null){
if (this.nodeDragged === null){ this.nodeDragging.x = mouseX - this.cameraX - this.nodeDragging.width / 2;
console.error("nodeDrag==true but nodeDragged==null"); this.nodeDragging.y = mouseY - this.cameraY - this.nodeDragging.height / 2;
return }
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(); this.draw();
} }
@ -117,9 +127,8 @@ class Diagrams {
let mouseX = ev.x - canvasRect.left; let mouseX = ev.x - canvasRect.left;
let mouseY = ev.y - canvasRect.top; let mouseY = ev.y - canvasRect.top;
for (let node of this.nodes){ for (let node of this.nodes){
if (node.pointInDiagram(mouseX, mouseY)) { if (node.pointInNode(mouseX - this.cameraX, mouseY - this.cameraY)) {
this.nodeDrag = true; this.nodeDragging = node;
this.nodeDragged = node;
return; return;
} }
} }
@ -129,8 +138,7 @@ class Diagrams {
onmouseup(ev: MouseEvent){ onmouseup(ev: MouseEvent){
this.panning = false; this.panning = false;
this.nodeDrag = false; this.nodeDragging = null;
this.nodeDragged = null;
} }
drawBackground(){ drawBackground(){
@ -144,16 +152,26 @@ class Diagrams {
draw(){ draw(){
this.ctx.clearRect(0,0, this.canvas.width, this.canvas.height); this.ctx.clearRect(0,0, this.canvas.width, this.canvas.height);
this.drawBackground(); this.drawBackground();
let fullCircleRadians = Math.PI + (Math.PI * 3);
for (let node of this.nodes){ 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.fillRect(node.x + this.cameraX, node.y + this.cameraY, node.width, node.height);
this.ctx.fillStyle = "black"; this.ctx.fillStyle = "#D3D3D3";
this.ctx.font = "30px Arial"; this.ctx.font = "30px Helvetica";
this.ctx.fillText( this.ctx.fillText(
node.label, node.label,
node.x + this.cameraX + node.height / 2, node.x + this.cameraX + node.height / 2,
node.y + this.cameraY + node.height / 1.5 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();
} }
} }