Intermediate
This commit is contained in:
parent
a3251f2fdd
commit
854f3ad13e
1 changed files with 107 additions and 32 deletions
|
@ -27,6 +27,38 @@ const specsCopy = (to, from) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the position of an element relative to another
|
||||||
|
* @param {HTMLElement} el The element whose position to determine
|
||||||
|
* @param {HTMLElement} reference Relative to this element
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const getElementPosition = (el, reference) => {
|
||||||
|
if(!el || !(el instanceof HTMLElement)){
|
||||||
|
// Always return 0,0 if the element is invalid
|
||||||
|
return {x: 0, y: 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reference || !(reference instanceof HTMLElement)){
|
||||||
|
// Take the document body as reference if the reference is invalud
|
||||||
|
reference = document.querySelector("body");
|
||||||
|
}
|
||||||
|
|
||||||
|
if( el.offsetParent === reference){
|
||||||
|
// easily done if the reference element is also the offsetParent..
|
||||||
|
return {x: el.offsetLeft, y: el.offsetTop};
|
||||||
|
} else {
|
||||||
|
const elR = el.getBoundingClientRect();
|
||||||
|
const refR = reference.getBoundingClientRect();
|
||||||
|
|
||||||
|
return {x: elR.left - refR.left,
|
||||||
|
y: elR.top - refR.top};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an element is a containing element and can thus be a parent for absolute positioning
|
* Check if an element is a containing element and can thus be a parent for absolute positioning
|
||||||
* Which is the cas if the element has
|
* Which is the cas if the element has
|
||||||
|
@ -86,6 +118,7 @@ export class SimpleLine {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error("Start element not string or dom element",start);
|
console.error("Start element not string or dom element",start);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate end element
|
// Validate end element
|
||||||
|
@ -100,43 +133,85 @@ export class SimpleLine {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error("End element not string or dom element",start);
|
console.error("End element not string or dom element",start);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate or determine container
|
|
||||||
if(this.specs.container){
|
|
||||||
if(this.specs.container instanceof HTMLElement){
|
|
||||||
this.container = this.specs.container;
|
|
||||||
}
|
|
||||||
else if (typeof this.specs.container === 'string' || this.specs.container instanceof String) {
|
|
||||||
this.container = document.querySelector(this.specs.container);
|
|
||||||
if(!(this.container instanceof HTMLElement)){
|
|
||||||
console.warn("Cannot find specified container element:",this.specs.container);
|
|
||||||
this.specs.container = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.warn("Container specified is not a string or element:",this.specs.container);
|
|
||||||
this.specs.container = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!this.specs.container) { // if originally empty, or cleared
|
|
||||||
// find the first parent element of start that has position css attribute set (or body if none has it set)
|
|
||||||
const body = document.querySelector("body");
|
|
||||||
let el = this.start.parentElement;
|
|
||||||
while( el !== body && !isContainingElement(el)){
|
|
||||||
el = el.parentElement;
|
|
||||||
}
|
|
||||||
this.container = el;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getContainer(){
|
||||||
|
// Validate or determine container
|
||||||
|
let container = this.startstart.offsetParent;
|
||||||
|
if(!container) {
|
||||||
|
if(document.getComputedStyle(this.start).position == "fixed"){
|
||||||
|
container = document.querySelector("body");
|
||||||
|
} else {
|
||||||
|
console.error("Start element has no offsetParent. likely ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAnchorPoint(anchor){
|
||||||
|
|
||||||
|
let el = this.start;
|
||||||
|
if(anchor != "start"){
|
||||||
|
anchor = "end";
|
||||||
|
el = this.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
let x, dirX;
|
||||||
|
let y, dirY;
|
||||||
|
// determine start coordinates
|
||||||
|
if(this.specs.anchors[anchor].includes("left")){
|
||||||
|
x = 0;
|
||||||
|
dirX = -1;
|
||||||
|
} else if (this.specs.anchors[anchor].includes("right")) {
|
||||||
|
x = el.offsetWidth -1;
|
||||||
|
dirX = 1;
|
||||||
|
} else { // center
|
||||||
|
x = el.offsetWidth / 2;
|
||||||
|
dirX = 0;
|
||||||
|
}
|
||||||
|
if(this.specs.anchors[anchor].includes("top")){
|
||||||
|
y = 0;
|
||||||
|
dirY = 1;
|
||||||
|
} else if (this.specs.anchors[anchor].includes("bottom")) {
|
||||||
|
x = el.offsetHeight -1;
|
||||||
|
dirY = -1;
|
||||||
|
} else { // middle
|
||||||
|
x = el.offsetHeight / 2;
|
||||||
|
dirY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rotation = Math.atan2(dirX,dirY);
|
||||||
|
|
||||||
|
return { x: x, y: y, rot: rotation};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
paintSvg(){
|
paintSvg(){
|
||||||
const svg = document.createElement("svg");
|
const container = this.getContainer();
|
||||||
svg.attributes["viewBox"] = "";
|
if (!container) { return; } // Do not create any svg if container is empty
|
||||||
svg.attributes["width"] = "";
|
|
||||||
svg.attributes["height"] = "";
|
if(!this.svg || !(this.svg instanceof HTMLElement)){
|
||||||
|
this.svg = document.createElement("svg");
|
||||||
|
container.append(this.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine proper x, y ,h and w
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.svg.attributes["viewBox"] = `0 0 ${w}, ${h}`;
|
||||||
|
this.svg.attributes["width"] = `${w}px`;
|
||||||
|
this.svg.attributes["height"] = `${h}px`;
|
||||||
|
this.svg.style.position = "absolute";
|
||||||
|
this.svg.style.left = `${x}px`;
|
||||||
|
this.svg.style.top = `${y}px`;
|
||||||
|
|
||||||
|
// Draw the arrows....
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue