From: Michael Orlitzky Date: Thu, 11 Sep 2025 14:21:21 +0000 (-0400) Subject: index.html.in,TODO: fix the QR placement issue X-Git-Url: http://gitweb.michael.orlitzky.com/?a=commitdiff_plain;h=026d86718fdf5b390466db9fb17ce24e7f236d62;p=charm-bypass.git index.html.in,TODO: fix the QR placement issue It turns out, we DON'T need to adjust our vertical offsets by the svg-to-client unit ratio. I don't fully understand why, but I think it has something to do with declaring the height of the tableau to be fixed at 100% = 1080, and modern browsers treating "pixels" as an abstraction. In any case, it works fine without the fudge factor in both WebKit and Firefox. --- diff --git a/TODO b/TODO index 1fb90bd..208896c 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,3 @@ 1. In lieu of the 0th item, can you email yourself an HTML file and open it with e.g. gmail? - -2. When the browser window is resized, the QR code is not scaled and - repositioned correctly (it can overlap the top half of the ticket). diff --git a/index.html.in b/index.html.in index b70c62a..70170a6 100644 --- a/index.html.in +++ b/index.html.in @@ -584,18 +584,6 @@ } - /** - * Convert SVG units into client (HTML/CSS) units based - * on the declared/rendered width of the code background. - */ - function svg_to_client() { - const codebg = document.getElementById("codebg"); - const client_width = codebg.getBoundingClientRect().width; - const svg_width = parseFloat(codebg.getAttribute("width")); - return client_width / svg_width; - } - - /** * Resize the ticket background based on the service name. * The BaltimoreLink, Commuter Bus, and MARC Train tickets @@ -649,12 +637,8 @@ /* Scale up the background */ tbbg.style.transform = `scale(1, ${tbbg_yscale})`; - /* The scale is unit-agnostic, but the translations need - * to be in px (not SVG units) for CSS. */ - const svg2c = svg_to_client(); - t_yoffset *= svg2c; - sn_yoffset *= svg2c; - + /* When offsetting SVG elements, the pixels are apparently + * already scaled. */ t.style.transform = `translate(0, ${t_yoffset}px)`; sn.style.transform = `translate(0, ${sn_yoffset}px)`; @@ -738,9 +722,11 @@ * element's client rect. Since the size of the background is * fixed, this should give us a multiplier that turns client rect * distances (what we have) into SVG distances (what we want). */ + const client_width = codebg.getBoundingClientRect().width; + const svg_width = parseFloat(codebg.getAttribute("width")); /* Convert hdelta from client rect to SVG coordinates */ - const svg_hdelta = hdelta / svg_to_client(); + const svg_hdelta = hdelta * (svg_width / client_width); /* Since this element has an "x" attribute it's easier for * us to shift that than it is to mess with the "left" style. */ @@ -817,11 +803,7 @@ * to compute the offset on-the-fly. It's easy to figure out * the offset in SVG coordinates, but it turns out that WebKit * won't do transition effects for the SVG "transform" attribute. - * So to get transitions, we have to use the "transform" style - * instead. But, the "transform" style uses pixels! Ergo, we - * must first convert between the two using an object whose - * size is known. We use the same trick when centering the - * security code within its box. + * So to get transitions, we have to use the "transform" style. */ function toggle_qr_focus(event) { /* Don't swap night/day if the tap was on the QR code */ @@ -860,13 +842,12 @@ /* Otherwise, focus the QR code. */ - /* Compute the QR x-translation amount in pixels using the - * (known) width of the security code box. The magic offset - * was measured by scaling up the QR code in the SVG, and - * then centering it on the ticket. This gives you the - * offset in SVG units, which we then have to DIVIDE by the - * scaling factor, because when we scale the QR code in a - * second, the scaling is going to affect the translation. + /* The magic QR x-offset was measured by scaling up the QR + * code in the SVG, and then centering it on the ticket. This + * gives you the offset in SVG units, which we then have to + * DIVIDE by the scaling factor, because when we scale the QR + * code in a second, the scaling is going to affect the + * translation. * * The y-translations for the QR code and ticket by contrast * were pretty much chosen on vibes. All tickets grow up/down @@ -877,9 +858,8 @@ * Note: the fucked up spacing around the QR code is there in * CharmPass, too -- that's not my fault. */ - const svg2c = svg_to_client(); - const qr_xoffset = -6.56 * svg2c; - const qr_yoffset = 43 * svg2c; + const qr_xoffset = -6.56; + const qr_yoffset = 40; /* The _CSS_ translate transform takes comma-separated strings, * and is specified in px. */ @@ -887,23 +867,24 @@ /* The scale factors can easily be measured in CharmPass by * taking two screenshots, pre- and post-tap. */ - const qr_transform = `scale(4.13333333) translate(${qr_translate})`; - - /* Overriding the transform attribute with the CSS property - * Just Works for the scale() transform, but the "translate" - * transform needs some extra help because the Commuter Bus - * and MARC Train tickets are not in the right place to begin - * with. The relevant magic numbers can be found in the - * resize_ticket() function. */ + const qr_scale = 620/150; + const qr_transform = `scale(${qr_scale}) translate(${qr_translate})`; + + /* I'd love to tell you that these magic numbers match + * those in resize_ticket(), but they don't. After scaling + * the background downwards, we want to translate back up + * whatever amount makes the ticket look like it expanded + * up/down the same amount. So these numbers depend not + * only on the initial offsets in resize_ticket(), but + * also the background scale factor. */ const params = new URLSearchParams(document.location.search); let t_yoffset = -50; /* upwards translation of the ticket */ if (params.get("servicename") === "Commuter Bus") { - t_yoffset -= 13.5; + t_yoffset -= 12.5; } else if (params.get("servicename") === "MARC Train") { - t_yoffset -= 27; + t_yoffset -= 25; } - t_yoffset *= svg2c; /* The origindest and zone are only visible on commuter bus and * MARC train tickets, but they're hidden with "display: none",