Tweak to make arrow end at end point instead of small overlap

This commit is contained in:
PMKuipers 2023-07-18 11:45:36 +02:00
parent 2a845a961a
commit 6675dcb272
2 changed files with 205 additions and 1 deletions

199
amd/src/css-calc.js Normal file
View file

@ -0,0 +1,199 @@
/*eslint no-trailing-spaces: "off"*/
/*eslint no-eval: "off"*/
/***********************************
* Licence: MIT
* (c) 2023 Morglod/jchnkl
* converted from the typescript @ https://github.com/Morglod/csscalc/
*/
// units -> pixels
export const Absolute = {
/** browser version of pixel */
px: 1,
/** One centimeter. 1cm = 96px/2.54 */
cm: 96 / 2.54,
/** One millimeter. 1mm = 1/10th of 1cm */
mm: 96 / 25.4,
/** One quarter of a millimeter. 1Q = 1/40th of 1cm */
Q: 96 / 101.6,
/** One inch. 1in = 2.54cm = 96px */
in: 96,
/** One pica. 1pc = 12pt = 1/6th of 1in */
pc: 96 / 6,
/** One point. 1pt = 1/72nd of 1in */
pt: 96 / 72
};
// units ->(calc context)-> pixels
export const Relative = {
/**
* Equal to 1% of the height of the viewport
* @param {number} count
* @param {object} ctx
*/
vh: (count = 1, ctx) => {
return ((ctx ? ctx.viewportHeight : window.innerHeight) / 100) * count;
},
/**
* Equal to 1% of the width of the viewport
* @param {number} count
* @param {object} ctx
*/
vw: (count = 1, ctx) => {
return ((ctx ? ctx.viewportWidth : window.innerWidth) / 100) * count;
},
/**
* 1/100th of the smallest viewport side
* @param {number} count
* @param {object} ctx
*/
vmin: (count = 1, ctx) => {
return (
((ctx
? Math.min(ctx.viewportWidth, ctx.viewportHeight)
: Math.min(window.innerWidth, window.innerHeight)) /
100) *
count
);
},
/**
* 1/100th of the largest viewport side
* @param {number} count
* @param {object} ctx
*/
vmax: (count = 1, ctx) => {
return (
((ctx
? Math.max(ctx.viewportWidth, ctx.viewportHeight)
: Math.max(window.innerWidth, window.innerHeight)) /
100) *
count
);
},
/**
* Represents the font-size of <html> element
* @param {number} count
* @param {object} ctx
*/
rem: (count = 1, ctx) => {
return (
(ctx
? ctx.htmlFontSize
: parseFloat(
window.getComputedStyle(document.querySelector("html")).fontSize
)) * count
);
},
/**
* percent of width
* @param {number} count
* @param {object} ctx
*/
"%w": (count = 1, ctx) => {
return ((ctx ? ctx.width : document.body.clientWidth) / 100) * count;
},
/**
* percent of height
* @param {number} count
* @param {object} ctx
*/
"%h": (count = 1, ctx) => {
return ((ctx ? ctx.height : document.body.clientHeight) / 100) * count;
}
};
export const Units = {
...Relative,
...Absolute
};
export const UnitRegexpStr = `(?:\\s|^)(\\d*(?:\\.\\d+)?)(${Object.keys(
Units
).join("|")})(?:\\s|$|\\n)`;
export const UnitRegexp = new RegExp(UnitRegexpStr);
export const UnitRegexpGM = new RegExp(UnitRegexpStr, "gm");
/**
*
* @param {*} count
* @param {*} fromUnits
* @param {*} toUnits
* @param {*} ctx
* @returns
*/
export function convert(count, fromUnits, toUnits, ctx = calcCtx()) {
const baseUnit = Units[fromUnits];
const basePx =
typeof baseUnit === "function" ? baseUnit(count, ctx) : baseUnit * count;
const dstUnit = Units[toUnits];
const dstBasePx = typeof dstUnit === "function" ? dstUnit(1, ctx) : dstUnit;
return basePx / dstBasePx;
}
/**
*
* @param {*} expr
* @param {*} toUnits
* @param {*} ctx
* @returns
*/
export function convertAllInStr(expr, toUnits, ctx = calcCtx()) {
return expr.replace(UnitRegexpGM, (substr, count, unit) => {
return convert(parseFloat(count), unit, toUnits, ctx).toString();
});
}
/**
*
* @param {*} el
* @returns
*/
export function calcCtx(el) {
if (el) {
const rect = el.getBoundingClientRect();
return {
width: rect.width,
height: rect.height,
viewportWidth: window.innerWidth,
viewportHeight: window.innerHeight,
htmlFontSize: parseFloat(
window.getComputedStyle(document.querySelector("html")).fontSize
),
};
} else {
return {
width: document.body.clientWidth,
height: document.body.clientHeight,
viewportWidth: window.innerWidth,
viewportHeight: window.innerHeight,
htmlFontSize: parseFloat(
window.getComputedStyle(document.querySelector("html")).fontSize
)
};
}
}
/**
*
* @param {*} expression
* @param {*} el_ctx
* @param {*} ctx
* @returns
*/
export function calc(expression, el_ctx, ctx) {
if (el_ctx === undefined) {ctx = calcCtx(); }
else {
if (el_ctx instanceof HTMLElement) {
if (!ctx) {ctx = calcCtx(el_ctx); }
} else {
ctx = el_ctx;
}
}
return eval(convertAllInStr(expression, "px", ctx));
}

View file

@ -1,7 +1,7 @@
/*eslint no-console: "off"*/ /*eslint no-console: "off"*/
/*eslint no-trailing-spaces: "off"*/ /*eslint no-trailing-spaces: "off"*/
import {calc} from "./css-calc";
/** /**
@ -321,6 +321,11 @@ export class SimpleLine {
const startAnchor = this.getAnchorPoint("start"); const startAnchor = this.getAnchorPoint("start");
const endAnchor = this.getAnchorPoint("end"); const endAnchor = this.getAnchorPoint("end");
// make it a little shorter at the end to compensate for the size of the arrow
const strokeWpx = calc(this.specs.stroke);
endAnchor.x += endAnchor.dir.x * strokeWpx *1.5;
endAnchor.y += endAnchor.dir.y * strokeWpx *1.5;
const elStartPos = getElementPosition(this.start,container); const elStartPos = getElementPosition(this.start,container);
const elEndPos = getElementPosition(this.end,container); const elEndPos = getElementPosition(this.end,container);