top: 0;
left: 0;
height: 100%;
+
+ /* Hide everything by default. We only show it once the user has
+ * submitted the menu form */
+ display: none;
}
/* The blinking fade in/out animation for the ticket date and time */
url("data:font/woff2;base64,@CBPBOLD@") format("woff2")
}
- #serviceletter {
+ #serviceid {
font-family: "CharmBypass Bold", sans-serif;
font-weight: bold;
}
</head>
<body>
+ <div id="menu">
+ <form>
+ <fieldset>
+ <legend>BaltimoreLink (Bus, Light Rail, Metro)</legend>
+ <input type="hidden" name="servicename" value="BaltimoreLink" />
+ <input type="submit" name="go" value="Generate Ticket" />
+ </fieldset>
+ </form>
+ <form>
+ <fieldset>
+ <legend>Commuter Bus</legend>
+ <input type="hidden" name="serviceid" value="R" />
+ <input type="hidden" name="servicename" value="Commuter Bus" />
+ <div>
+ <input type="radio" id="zone1" name="zone" value="Zone 1" />
+ <label for="zone1">Zone 1</label>
+ </div>
+ <div>
+ <input type="radio" id="zone2" name="zone" value="Zone 2" />
+ <label for="zone2">Zone 2</label>
+ </div>
+ <div>
+ <input type="radio" id="zone3" name="zone" value="Zone 3" />
+ <label for="zone3">Zone 3</label>
+ </div>
+ <div>
+ <input type="radio" id="zone4" name="zone" value="Zone 4" />
+ <label for="zone4">Zone 4</label>
+ </div>
+ <div>
+ <input type="radio" id="zone5" name="zone" value="Zone 5" />
+ <label for="zone5">Zone 5</label>
+ </div>
+
+ <input type="submit" name="go" value="Generate Ticket" />
+ </fieldset>
+ </form>
+ <form>
+ <fieldset>
+ <legend>MARC Train</legend>
+ <input type="hidden" name="serviceid" value="R" />
+ <input type="hidden" name="servicename" value="MARC Train" />
+ <input type="submit" name="go" value="Generate Ticket" />
+ </fieldset>
+ </form>
+ </div>
+
@SVGDATA@
<script>
}
+ /******************************/
+ /* Set the service identifier */
+ /******************************/
+ function set_service_id() {
+ const sid = document.getElementById("serviceid");
+
+ /* Get the "serviceid" from the querystring if it's there */
+ let params = new URLSearchParams(document.location.search);
+ if (params.get("serviceid")) {
+ sid.textContent = params.get("serviceid");
+ }
+
+ /* Otherwise, leave it at "F" */
+ }
+
+ /******************************/
+ /* Set the service name */
+ /******************************/
+ function set_service_name() {
+ const sid = document.getElementById("servicename");
+
+ /* Get the "servicename" from the querystring if it's there */
+ let params = new URLSearchParams(document.location.search);
+ if (params.get("servicename")) {
+ sid.textContent = params.get("servicename");
+ }
+
+ /* Otherwise, leave it at "BaltimoreLink" */
+ }
+
/****************************************/
/* Set and reposition the security code */
/****************************************/
function center_code() {
/* Center the security code inside its red box */
const ct = document.getElementById("codetext");
+ const bg = document.getElementById("codebg");
/* First, find the center of the red box */
- const r1 = document.getElementById("codebg").getBoundingClientRect();
+ const r1 = bg.getBoundingClientRect();
const c1 = r1.left + (r1.width / 2);
/* Now the center of the code text */
/* What do we add to c2 to make it equal to c1? */
const hdelta = c1 - c2;
+ /* We've measured everything so far in "client rect"
+ * coordinates, because that's the only available measurement
+ * we have for the width of the <text> element after futzing
+ * with its contents. But when we reposition that <text>
+ * element, it will be by adjusting its "x" attribute, and
+ * that attribute uses a different coordinate system than the
+ * client rect does. Specifically, "x" refers to an offset
+ * within the SVG's coordinate system, and the client rect
+ * coordinates are pixels on-screen. To convert between the
+ * two, we can take the "width" attribute of the background
+ * element and compare it to the width of the background
+ * element's client rect. Since the size of the background is
+ * fixed, this should give us a multiplier that turns client recr
+ * distances (what we have) into SVG distances (what we want) */
+ const client_to_svg = parseFloat(bg.getAttribute("width"))/r1.width;
+
+ /* Convert hdelta from client rect to SVG coordinates */
+ const svg_hdelta = hdelta * client_to_svg;
+
/* Since this <text> element has an "x" attribute it's easier for
* us to shift that than it is to mess with the "left" style. */
- ct.setAttribute("x", parseFloat(ct.getAttribute("x")) + hdelta);
- }
-
- function center_code_repeatedly() {
- /* Lets us call center_code five times on page load. Why we
- * need to do this is an interesting (i.e. stupid) topic for
- * conversation. */
- center_code();
- center_code();
- center_code();
- center_code();
- center_code();
+ ct.setAttribute("x", parseFloat(ct.getAttribute("x")) + svg_hdelta);
}
/*****************************************/
}
}
+ /******************************************/
+ /* Display the ticket (and hide the menu) */
+ /******************************************/
+
+ function go() {
+ const svg = document.querySelector("svg");
+ const menu = document.getElementById("menu");
+ svg.style.display = "initial";
+ menu.style.display = "none";
+ }
/*****************************************************/
/* Add event handlers for all of the functions above */
/*****************************************************/
- /* Center the ticket once when the page has loaded */
- window.addEventListener("load", center_ticket);
+ const params = new URLSearchParams(document.location.search);
+ if (params.get("go")) {
+ /* First unhide the SVG (swap it with the form) */
+ window.addEventListener("load", go);
+
+ /* Center the ticket once when the page has loaded */
+ window.addEventListener("load", center_ticket);
- /* Re-center the ticket when the window is resized */
- window.addEventListener("resize", center_ticket);
+ /* Re-center the ticket when the window is resized */
+ window.addEventListener("resize", center_ticket);
- /* Set the security code text when the page has loaded */
- window.addEventListener("load", set_code);
+ /* Set the service identifier when the page has loaded */
+ window.addEventListener("load", set_service_id);
- /* Center the security code text when the page has loaded; in
- * particular, after we set it. And then center it again. And
- * again and again and again. Why? I'm glad you asked. Because
- * it doesn't actually get centered the first time; it's off by
- * a few pixels. But then if we center it _again_, it moves a
- * little closer to the true center. Do that enough times and
- * any errors become unnoticeable. */
- window.addEventListener("load", center_code_repeatedly);
+ /* Set the service name when the page has loaded */
+ window.addEventListener("load", set_service_name);
- /* Re-center the security code when the window is resized,
- * and in particular after the ticket is re-centered */
- window.addEventListener("resize", center_code);
+ /* Set the security code text when the page has loaded */
+ window.addEventListener("load", set_code);
- /* Set the ticket expiration date/time upon page load */
- window.addEventListener("load", set_ticket_expiry);
+ /* Center the security code text when the page has loaded; in
+ * particular, after we set the code. */
+ window.addEventListener("load", center_code);
- /* Swap colors when the screen is tapped */
- document.body.addEventListener("click", swap_colors);
+ /* Set the ticket expiration date/time upon page load */
+ window.addEventListener("load", set_ticket_expiry);
+
+ /* Swap colors when the screen is tapped */
+ document.body.addEventListener("click", swap_colors);
+ }
</script>
</body>