+++ /dev/null
-<!doctype html>
-<html lang="en-US">
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
-
- <title>
- CharmBypass.
- </title>
-
- <style>
- /*
- * Reset styles for the html and body elements, the only two HTML
- * elements we use. */
- html, body {
- margin: 0;
- padding: 0;
- border: 0;
- font-weight: normal;
- font-style: inherit;
- font-size: 100%;
- line-height: 1.5;
- font-family: inherit;
- text-align: inherit;
- text-decoration: none;
- vertical-align: baseline;
- background: transparent;
- }
-
- html, body {
- /* To create our "window" onto the scene, we're going to slide the
- * SVG off the left-hand side of the screen, and we don't want
- * scroll bars to appear. */
- overflow: hidden;
- }
-
- svg {
- /* Set the height to 100% of the screen, which we'll keep; and the
- * initial position to (0,0), which we're going to change
- * every time the window is resized, because the exact amount
- * that we have to slide the SVG to the left to get the ticket
- * into the center will change. */
- position: fixed;
- top: 0;
- left: 0;
- height: 100%;
- }
-
- /* The blinking fade in/out animation for the ticket date and time */
- @keyframes blink {
- 25% {
- opacity: 0.5;
- }
- 50% {
- opacity: 0;
- }
- 75% {
- opacity: 0.5;
- }
- }
-
- #tickettime, #ticketdate {
- animation: blink 2s linear infinite;
- }
-
- /* Define, load, and specify the custom font we use for the ticket
- * date, time, and service name. */
- @font-face {
- font-family: "CharmBypass Regular";
- src:
- url("data:font/woff2;base64,@CBPREGULAR@") format("woff2")
- }
-
- #servicename, #tickettime, #ticketdate {
- font-family: "CharmBypass Regular";
- }
-
- @font-face {
- font-family: "CharmBypass Bold";
- src:
- url("data:font/woff2;base64,@CBPBOLD@") format("woff2")
- }
-
- #serviceletter {
- font-family: "CharmBypass Bold";
- }
-
- /************************/
- /* Scrolling animations */
- /************************/
-
- /* Bus */
- @keyframes busroll {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(100%);
- }
- }
-
- #bus {
- animation: busroll 23s linear infinite;
- }
-
-
- /* Tram */
- @keyframes tramroll {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(100%);
- }
- }
-
- #tram {
- animation: tramroll 17s linear infinite;
- }
-
-
- /* Tram */
- @keyframes trainroll {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(100%);
- }
- }
-
- #train {
- animation: trainroll 11s linear infinite;
- }
-
-
- /* Clouds */
- @keyframes cloudsfloat {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(-50%);
- }
- }
-
- #clouds {
- animation: cloudsfloat 40s linear infinite;
- }
-
- @keyframes cloudscopyfloat {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(-50%);
- }
- }
-
- #cloudscopy {
- animation: cloudscopyfloat 40s linear infinite;
- }
-
-
- /* Trees */
- @keyframes treespass {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(-50%);
- }
- }
-
- #trees {
- /* The trees move a little faster than the clouds */
- animation: treespass 30s linear infinite;
- }
-
- @keyframes treescopypass {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(-50%);
- }
- }
-
- #treescopy {
- /* The trees move a little faster than the clouds */
- animation: treescopypass 30s linear infinite;
- }
-
-
- /* City skyline */
- @keyframes cityscroll {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(-50%);
- }
- }
-
- #city {
- /* The city moves faster than the clouds but slower
- * than the trees */
- animation: cityscroll 35s linear infinite;
- }
-
- @keyframes citycopyscroll {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(-50%);
- }
- }
-
- #citycopy {
- /* The city moves faster than the clouds but slower
- * than the trees */
- animation: citycopyscroll 35s linear infinite;
- }
- </style>
- </head>
-
- <body>
- @SVGDATA@
-
- <script>
- /******************************************/
- /* First, set up the ticket date and time */
- /******************************************/
-
- /* There are two parameters, time and date, that we store in one
- * underlying "date" variable. Default both to an hour from now. This
- * is sensible because the date/time shown on your ticket is its
- * EXPIRATION time, and tickets are valid for two hours. Having it
- * show one hour in the future means that you didn't just use your
- * ticket a second ago (if you just got caught on the light rail, for
- * example) but also means that it's not expiring for a while.
- */
- const date = new Date();
-
- /* Add an hour. We use the low-level get/setTime to change the number
- * of milliseconds since the epoch that this date represents. Obviously
- * correct, and avoids all suspicious corner cases (well, for a few more
- * decades). */
- date.setTime(date.getTime() + (60*60*1000));
-
- /* All <text> elements produced by inkscape contain a single <tspan>
- * that itself contains the actual text. */
- tt = document.getElementById("tickettime");
- tt.firstChild.textContent = date.toLocaleTimeString();
-
- const td = document.getElementById("ticketdate");
- const dateopts = {
- day: "2-digit",
- month: "2-digit",
- year: "2-digit"
- };
- td.firstChild.textContent = date.toLocaleDateString("en-US", dateopts);
-
-
- /************************************************************/
- /* Second, add the onclick handler for the night/day switch */
- /************************************************************/
-
- /* We always start in "day" mode */
- is_day = true;
-
- function set_day() {
- sky.style.fill = "#efb02f";
- }
-
- function set_night() {
- sky.style.fill = "#143b66";
- }
-
- function swap_colors() {
- if (is_day) {
- set_night();
- is_day = false;
- }
- else {
- set_day();
- is_day = true;
- }
- }
-
- document.body.addEventListener("click", swap_colors);
-
-
- /*************************************************/
- /* Finally, center the ticket within the browser */
- /*************************************************/
- function center_ticket() {
- /* We're relying on the SVG being the full height of the
- * viewport already, and on the aspect ratio being
- * preserved. First, find the center of the ticket. */
- const r = document.getElementById("ticket").getBoundingClientRect();
- const c = r.left + (r.width / 2);
-
- /* That's the center-line of the ticket. We want to move it to
- * the center-line of the viewport. */
- const vc = document.documentElement.clientWidth / 2;
-
- /* This is how much we need to translate the SVG */
- const delta = vc - c;
-
- /* But before we can set the absolute left-coordinate of the
- * SVG, we need to know where it is now. Note: without the
- * "px" this doesn't default to pixels like CSS does. */
- const svg = document.querySelector("svg");
- svg.style.left = (svg.getBoundingClientRect().left + delta) + "px";
- }
-
- /* Re-center it when the window is resized */
- window.addEventListener("resize", center_ticket);
-
- /* Center it once when the page has loaded, too */
- window.addEventListener("load", center_ticket);
- </script>
- </body>
-</html>