From 6675dcb27245bdb19b6d29dd4f8aba9bb3b023b0 Mon Sep 17 00:00:00 2001 From: PMKuipers Date: Tue, 18 Jul 2023 11:45:36 +0200 Subject: [PATCH] Tweak to make arrow end at end point instead of small overlap --- amd/src/css-calc.js | 199 ++++++++++++++++++++++++++++++++++++++++++ amd/src/simpleline.js | 7 +- 2 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 amd/src/css-calc.js diff --git a/amd/src/css-calc.js b/amd/src/css-calc.js new file mode 100644 index 0000000..ed40faf --- /dev/null +++ b/amd/src/css-calc.js @@ -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 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)); + } + \ No newline at end of file diff --git a/amd/src/simpleline.js b/amd/src/simpleline.js index ef8aa3c..7b6da28 100644 --- a/amd/src/simpleline.js +++ b/amd/src/simpleline.js @@ -1,7 +1,7 @@ /*eslint no-console: "off"*/ /*eslint no-trailing-spaces: "off"*/ - +import {calc} from "./css-calc"; /** @@ -321,6 +321,11 @@ export class SimpleLine { const startAnchor = this.getAnchorPoint("start"); 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 elEndPos = getElementPosition(this.end,container);