]> gitweb.michael.orlitzky.com - charm-bypass.git/commitdiff
index.html.in: refactor the toggle_qr_focus() function
authorMichael Orlitzky <michael@orlitzky.com>
Thu, 11 Sep 2025 03:40:52 +0000 (23:40 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Thu, 11 Sep 2025 03:40:52 +0000 (23:40 -0400)
1. Adjust to the recent conversion of resize_ticket() to CSS
   transforms.
2. Refine the ticket dimensions to match those of CharmPass.
   This is still pretty hacky and may not work in all cases,
   but on a fresh page load in a desktop browser, everything
   is where it should be.
3. Simplify / clean up the code a little bit (using forEach,
   classList, etc.)

index.html.in

index ad58d2313d4c410d56bd24bf28c1c0b41daa2176..8b4f6e9f2981ffca3c15bf079b21ec3864781f7d 100644 (file)
        * 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.
-       *
-       * A posteriori, using CSS was the right way to do this, because
-       * the commuter bus and MARC train tickets are initially sized
-       * with the transform _attribute_. The CSS property takes
-       * precedence, but when we unset the CSS property, whatever
-       * scaling factor was set in the attribute kicks back in. So
-       * ultimately we don't have to worry about the initial ticket
-       * size: the scaled-up size for the QR focus is always bigger
-       * than the ticket; everything just works.
        */
       function toggle_qr_focus(event) {
-        /* Don't swap night/day if the tap was on the QR code. */
+        /* Don't swap night/day if the tap was on the QR code */
         event.stopPropagation();
 
         const codetext = document.getElementById("codetext");
         const tbbg = document.getElementById("ticketbottombg");
         const zone = document.getElementById("zone");
 
-        let ticket_class;   /* transparent, or none (opaque) */
-        let qr_class;       /* big, or none (normal sized) */
-        let qr_transform;   /* text of the transform style to be set */
-        let tbbg_transform; /* transform (resize) of ticket bottom */
-        let t_transform;    /* upwards ticket translation */
-
-        if (qr.getAttribute("class") == "big") {
-          ticket_class = "";
-          qr_class = "";
-          qr_transform = "";
-          tbbg_transform = "";
-          t_transform = "";
+        /* Elements that need to fade in/out */
+        const ticket_elts = [
+          codetext,
+          codebg,
+          origindest,
+          serviceid,
+          servicename,
+          zone
+        ];
+
+        if (qr.classList.contains("big")) {
+          /* Put things back to normal */
+          ticket_elts.forEach(e => {
+            e.classList.remove("transparent");
+          });
+          resize_ticket(); /* resets t and tbbg */
+          qr.style.transform = "";
+          qr.classList.remove("big");
+          return;
         }
-        else {
-          ticket_class = "transparent";
-          qr_class = "big";
-
-          /* 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 y-translations for the QR code and ticket by contrast
-           * were pretty much chosen on vibes. All tickets grow up/down
-           * more or less equal amounts: BaltimoreLink tickets grow the
-           * most, Commuter bus tickets grow a little less, and MARC
-           * train tickets grow only tiny bit.
-           *
-           * Note: the fucked up spacing around the QR code is there in
-           * CharmPass, too -- that's not my fault.
-           */
-          const client_width = codebg.getBoundingClientRect().width;
-          const svg_width = parseFloat(codebg.getAttribute("width"));
-          const svg_to_client = client_width / svg_width;
-          const qr_xoffset = -6.56 * svg_to_client;
-          const qr_yoffset = 43 * svg_to_client;
-
-          /* 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 params = new URLSearchParams(document.location.search);
-          let t_yoffset = -40;
-          if (params.get("servicename") === "Commuter Bus") {
-            t_yoffset -= 9.33;
-          }
-          else if (params.get("servicename") === "MARC Train") {
-            t_yoffset -= 67.17;
-          }
-          t_yoffset *= svg_to_client;
-
-          /* The _CSS_ translate transform takes comma-separated strings,
-           * and is specified in px. */
-          const qr_translate = `${qr_xoffset}px, ${qr_yoffset}px`;
-          const t_translate = `0, ${t_yoffset}px`;
-
-          /* The scale factors can easily be measured in CharmPass by
-           * taking two screenshots, pre- and post-tap. */
-          qr_transform = `scale(4.13333333) translate(${qr_translate})`;
-          tbbg_transform = "scale(1, 1.47)";
-          t_transform = `translate(${t_translate})`;
+
+        /* 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 y-translations for the QR code and ticket by contrast
+         * were pretty much chosen on vibes. All tickets grow up/down
+         * more or less equal amounts: BaltimoreLink tickets grow the
+         * most, Commuter bus tickets grow a little less, and MARC
+         * train tickets grow only tiny bit.
+         *
+         * 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;
+
+        /* The _CSS_ translate transform takes comma-separated strings,
+         * and is specified in px. */
+        const qr_translate = `${qr_xoffset}px, ${qr_yoffset}px`;
+
+        /* 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 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;
+        }
+        else if (params.get("servicename") === "MARC Train") {
+          t_yoffset -= 27;
         }
+        t_yoffset *= svg2c;
 
         /* The origindest and zone are only visible on commuter bus and
          * MARC train tickets, but they're hidden with "display: none",
          * so we don't have to worry about making them opaque. */
-        codetext.setAttribute("class", ticket_class);
-        codebg.setAttribute("class", ticket_class);
-        origindest.setAttribute("class", ticket_class);
-        serviceid.setAttribute("class", ticket_class);
-        servicename.setAttribute("class", ticket_class);
-        zone.setAttribute("class", ticket_class);
-
-        tbbg.style.transform = tbbg_transform;
-        t.style.transform = t_transform;
+        ticket_elts.forEach(e => {
+          e.classList.add("transparent");
+        });
+
+        /* Keep in mind that this clobbers whatever scale() and
+         * translate() were set initially in resize_ticket() */
+        t.style.transform = `translate(0, ${t_yoffset}px)`;
+        tbbg.style.transform = "scale(1, 1.47)";
         qr.style.transform = qr_transform;
-        qr.setAttribute("class", qr_class);
+        qr.classList.add("big");
       }