Creating replacement for leaderline
This commit is contained in:
parent
340b0eef6b
commit
a3251f2fdd
1 changed files with 143 additions and 0 deletions
143
amd/src/simpleline.js
Normal file
143
amd/src/simpleline.js
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*eslint no-console: "off"*/
|
||||
|
||||
/**
|
||||
* Copies defined properties in to, over from the from object. Does so recursively
|
||||
* Ysed to copy user defined parameters onto a pre-existing object with defaults preset.
|
||||
* @param {Object} to The object to copy to
|
||||
* @param {Object} from The object tp copy from (but only the properties already named in "to")
|
||||
*/
|
||||
const specsCopy = (to, from) => {
|
||||
for(const ix in to){
|
||||
if(from.hasOwnProperty(ix)){
|
||||
if( typeof to[ix] == "object"
|
||||
&& typeof from[ix] == "object")
|
||||
{
|
||||
if(Array.isArray(to[ix])){
|
||||
if(Array.isArray(from[ix])){
|
||||
to[ix] = Array.from(from[ix]);
|
||||
} // else, skip...
|
||||
} else {
|
||||
specsCopy(to[ix], from[ix]); // recursive copy
|
||||
}
|
||||
}
|
||||
else {
|
||||
to[ix] = from[ix];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 1 A position value other than static (fixed, absolute, relative, or sticky).
|
||||
* 2 A transform or perspective value other than none
|
||||
* 3 A will-change value of transform or perspective
|
||||
* 4 A filter value other than none or a will-change value of filter (only works on Firefox)
|
||||
* 5 A contain value of layout, paint, strict or content (e.g. contain: paint;)
|
||||
* 6 A container-type value other than normal
|
||||
* 7 A backdrop-filter other than none (e.g. backdrop-filter: blur(10px);)
|
||||
* @param {HTMLElement} el
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
const isContainingElement = (el) => {
|
||||
const cssStyle = getComputedStyle(el);
|
||||
return ["fixed","absolute","relative","sticky",].includes(cssStyle.position)
|
||||
|| cssStyle.transform !== "none"
|
||||
|| cssStyle.perspective !== "none"
|
||||
|| ["transform","perspective"].includes(cssStyle.willChange)
|
||||
|| cssStyle.filter !== "none"
|
||||
|| cssStyle.contain == "paint"
|
||||
|| cssStyle.backdropFilter !== "none";
|
||||
};
|
||||
|
||||
export class SimpleLine {
|
||||
|
||||
constructor(start, end, specs){
|
||||
this.svg = null;
|
||||
|
||||
// setup defaults
|
||||
this.specs = {
|
||||
container: null,
|
||||
class: "",
|
||||
colors: {
|
||||
line : "currentcolor",
|
||||
arrow: "currentcolor",
|
||||
},
|
||||
anchors: {
|
||||
// top, middle, bottom
|
||||
// left, center, right
|
||||
start: ["middle","right"],
|
||||
end: ["middle", "left"],
|
||||
}
|
||||
};
|
||||
|
||||
specsCopy(this.specs,specs);
|
||||
|
||||
// Validate start element
|
||||
if(start instanceof HTMLElement) {
|
||||
this.start = start;
|
||||
} else if (typeof this.start === 'string' || this.start instanceof String) {
|
||||
this.startSelector = start;
|
||||
this.start = document.querySelector(start);
|
||||
if(!(this.start instanceof HTMLElement)){
|
||||
console.error("Cannot find start element:",start);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
console.error("Start element not string or dom element",start);
|
||||
}
|
||||
|
||||
// Validate end element
|
||||
if(end instanceof HTMLElement) {
|
||||
this.end = end;
|
||||
} else if (typeof this.end === 'string' || this.end instanceof String) {
|
||||
this.endSelector = end;
|
||||
this.end = document.querySelector(end);
|
||||
if(!(this.end instanceof HTMLElement)){
|
||||
console.error("Cannot find end element:",end);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
console.error("End element not string or dom element",start);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
paintSvg(){
|
||||
const svg = document.createElement("svg");
|
||||
svg.attributes["viewBox"] = "";
|
||||
svg.attributes["width"] = "";
|
||||
svg.attributes["height"] = "";
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in a new issue