diff -r 770c613c424f -r bb1eff4091ab svghmi/svghmi.js --- a/svghmi/svghmi.js Thu Sep 22 09:42:38 2022 +0200 +++ b/svghmi/svghmi.js Wed Sep 28 09:19:07 2022 +0200 @@ -532,8 +532,49 @@ current_visible_page = page_name; }; +/* From https://jsfiddle.net/ibowankenobi/1mmh7rs6/6/ */ +function getAbsoluteCTM(element){ + var height = svg_root.height.baseVal.value, + width = svg_root.width.baseVal.value, + viewBoxRect = svg_root.viewBox.baseVal, + vHeight = viewBoxRect.height, + vWidth = viewBoxRect.width; + if(!vWidth || !vHeight){ + return element.getCTM(); + } + var sH = height/vHeight, + sW = width/vWidth, + matrix = svg_root.createSVGMatrix(); + matrix.a = sW; + matrix.d = sH + var realCTM = element.getCTM().multiply(matrix.inverse()); + realCTM.e = realCTM.e/sW + viewBoxRect.x; + realCTM.f = realCTM.f/sH + viewBoxRect.y; + return realCTM; +} + +function apply_reference_frames(){ + const matches = svg_root.querySelectorAll("g[svghmi_x_offset]"); + matches.forEach((group) => { + let [x,y] = ["x", "y"].map((axis) => Number(group.getAttribute("svghmi_"+axis+"_offset"))); + let ctm = getAbsoluteCTM(group); + // zero translation part of CTM + // to only apply rotation/skewing to offset vector + ctm.e = 0; + ctm.f = 0; + let invctm = ctm.inverse(); + let vect = new DOMPoint(x, y); + let newvect = vect.matrixTransform(invctm); + let transform = svg_root.createSVGTransform(); + transform.setTranslate(newvect.x, newvect.y); + group.transform.baseVal.appendItem(transform); + ["x", "y"].forEach((axis) => group.removeAttribute("svghmi_"+axis+"_offset")); + }); +} + // Once connection established ws.onopen = function (evt) { + apply_reference_frames(); init_widgets(); send_reset(); // show main page