Skip to content

About

A free split-flap message board for any screen: messages, clock, SL departures, weather. Canvas, no build step, no dependencies.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Repository files navigation

Split-Flap Board

A free split-flap message board for any screen. Put a spare monitor on the wall, open the page, and it flips through your messages, the time, departures from the stop nearest you, the weather, exchange rates and countdowns, one letter at a time like a railway board. It starts from one city search, and works almost anywhere in Europe and North America.

Live: maclaine.se/split-flap

A split-flap board showing HELLO FROM A SPARE MONITOR above a row of colour chips

A Vestaboard costs thousands, and screen apps like it charge a monthly fee for each screen. This runs in a browser for nothing and needs no account. Every board lives in the browser that made it, and a board link carries it to another screen. If you want your boards on every device, you can sign in with Google, and they are kept with your account as well.

What it does

  • A physical-looking board. Each flap steps forward through the drum to its letter, folds over its hinge with light and shadow, and settles with a small rebound. Drawn on one canvas, so a Raspberry Pi keeps up.
  • Words: messages with colour chips, rotating messages, big text drawn in colour chips, quotes, and menus with prices lined up on the right.
  • Time: clock and date, a big clock, a word clock ("QUARTER PAST TEN", "KVART ÖVER TIO"), a letter clock where the words for the time light up in a grid of faint letters, countdowns that can also count up from a date, and Today, with the week number, Swedish red days and flag days, and sunrise and sunset.
  • Live: departures from up to four stops, from Transitous almost anywhere and from SL in Stockholm, as a list or a station board. Weather with rain in the next hour, public holidays for your country, a world clock, exchange rates in any of about thirty currencies and a few crypto coins, Swedish electricity spot prices, On this day from Wikipedia, and Follow a URL, which prints lines from any JSON or text address that lets other sites read it.
  • Markets: shares, ETFs and coins as a line of half flaps, green up and red down, with the price and whether the market is open. London and New York are built in through the Worker, which asks Alpha Vantage once a day per symbol for every screen; crypto comes from CoinGecko; anything else from your own key or Google Sheet, kept in your browser (how to set up the sheet).
  • Headlines: RSS, Atom and JSON feeds, one headline at a time. Feeds that block browsers come through the Worker, which fetches only a built-in list (data/feeds.json) and feeds a signed-in account has added, and always hands them back as plain text.
  • Interest rates: the policy rate of the Riksbank, the ECB, the Bank of England or the Fed, when it last moved, and a line over one or five years.
  • Your own sources: an Alpha Vantage key or a published sheet, kept in your browser and, signed in, with your account, encrypted on the server (worker/src/seal.js).
  • The place: one city search in Display, and new boards start from it: the weather, the nearest stop, the holidays, the currency and 12 or 24 hours. Names in Greek and Cyrillic are spelled in Latin letters, and accents the flaps lack are dropped, so no letter prints blank.
  • Pictures: paint with the colour chips, turn a photo into chips in the browser, or run an animated pattern (Nordic flags, rain, waves, confetti).
  • Templates: ten to start from, including Home dashboard, Station board, Café, Office lobby, Letter clock and Everything at once, which fills the screen and rolls every flap the long way round.
  • Playlists and boards: a playlist is what a screen plays, its boards in order and when each one shows. Every board is kept once, in Boards, at its own size and theme, and a playlist points at boards there, so one board can be in several playlists. A board is one screen at a time, one zone or two (header and body, split, ticker row, or stacked halves for portrait screens), each showing a different channel. GLOSSARY.md has the words.
  • The week: a playlist's main view. Boards take turns on their own timers, and a board can have several times, by days of the week or on a date once or every year, which you drag in the week or set on the board. Show alone gives a board its time to itself (the train times on weekday mornings). Today's playlist, beside the week, is what that adds up to. Quiet hours dim or blank the screen overnight.
  • Three themes (Vestaboard Black, Vestaboard White, Solari Amber), any grid from 1 × 4 to 24 × 60, and four transitions at three speeds, previewed on the board as you pick them. Authentic rolls every flap the whole way round.
  • Four flap sounds (Clack, Heavy, Soft, Tick), synthesised: a plastic tick for each flap and a ka-chunk when the last one lands.
  • The editor. Four sections along the top, Showing, Boards, Explore and Account, the same on a phone and a wide screen, and every level has its own address, so the browser's back button goes up one level. Each kind of content is a tile drawn as a small board in the shape of the zone it fills, so you see it before you pick it.
  • Messages are made on the grid in Type, Paint or Photo mode, with undo and redo. A message you change is kept under Earlier messages in this browser.
  • Share by link or QR (Quick Response) code. The link holds the whole playlist with its boards, compressed into the part of the URL after #, which browsers never send to a server. Share as image downloads the board as a PNG.
  • Made for walls: kiosk mode (?kiosk=1), screen wake lock, a one pixel drift against burn-in, offline support, a small note when live data is getting old, and a reload in quiet hours when a new version is live. Every flap can roll once at start up and on the hour. ?bg=transparent draws the board on nothing, for OBS.
  • Stereo flaps: each flap's sound is panned by its column.
  • English and Swedish. Å Ä Ö Æ Ø Ü É each have their own flap, and so does ♥.

A board showing the Swedish flag in blue and yellow colour chips, part of the Nordic flags pattern

The same board in the Solari Amber theme showing Stockholm weather and a countdown to midsummer

Accounts

An account is optional. Without one, boards live in the browser that made them, as they always have. Sign in with Google and they are kept with the account too, and come back on any device you sign in on. The browser stays the working copy, so the board runs offline and a wall screen never waits on the server. A board changed in two places keeps both versions. Wall screens use board links and never sign in.

The account stores the Google account id, the name, the email, the boards and playlists, and Home, in a Cloudflare D1 database in the EU. It keeps no IP addresses, browser details or Google tokens, and there are no analytics. Export my account and Delete account are in the editor. The full notice is privacy.html, at maclaine.se/en/split-flap/privacy.

The server is a Cloudflare Worker in worker/, with its own dependencies and README. The app itself still has none.

Put it on a monitor

Raspberry Pi. Install Raspberry Pi OS with desktop. Build your board on your phone, press Share, and open the link on the Pi with ?kiosk=1 added before the #. To start it at boot, add this to ~/.config/labwc/autostart (Bookworm with Wayland; older releases call the browser chromium-browser):

chromium --kiosk --noerrdialogs --disable-infobars "https://maclaine.se/split-flap?kiosk=1#b=..."

Opening the same link at every boot is safe: a board with the same id replaces itself instead of piling up copies.

Cast a tab from Chrome to a Chromecast or Google TV, then press Fullscreen. An old laptop works too: turn off sleep, open the link, press F.

Run your own copy

There is no build step and no dependencies. Any static file server will do:

git clone https://github.com/MMacLaine/split-flap.git
cd split-flap
npm run serve                 # then open http://localhost:8801 (python3 -m http.server 8801 works too)

Tests use Node's built-in runner: npm test (Node 18 or newer).

The SL station list in data/sl-sites.json is baked from SL's open site list; refresh it with node _dev/fetch-sl-sites.mjs.

How it is built

File What it does
src/renderer.js The canvas board: glyph atlas, fold, stagger, frame budget. Its constants are the design spec.
src/charset.js The drum (74 flaps), typed text to flaps, Vestaboard character codes for import.
src/content.js Layouts, zones and what each channel prints, as pure functions.
src/almanac.js Week numbers, Swedish red days and flag days, sunrise and sunset.
src/pixels.js The 3 × 5 pixel font and the animated colour patterns.
src/templates.js The ready-made boards.
src/sound.js The four synthesised flap sounds.
src/schedule.js Board timers, times by day or date, Show alone, quiet hours, and the week and Today's playlist from the same rule.
src/week.js The week view and Today's playlist.
src/route.js The editor's addresses after #, and Back as one level up.
src/live.js The fetchers (departures, SL, Open-Meteo, holidays, electricity, exchange rates and coins, Wikipedia, Follow a URL), stop and city search.
src/place.js The place: country, time zone, 12 or 24 hours, and the currency for each country.
src/transit.js Transitous replies to departures and stops, shared by the app and the Worker.
src/sources.js Every outside source, its terms and its credit.
src/markets.js The line chart in half flaps, exchange hours, and the Markets zone.
src/connections.js Your own key or sheet, kept in this browser, and the line a sheet builds.
data/markets.json The built-in symbols the Worker will fetch.
src/store.js localStorage, board links, and the sanitizer every imported board goes through (the Worker uses it too).
src/account.js Signing in, and keeping this browser's boards in step with the account.
src/sync.js The sync rules as pure functions: merging, deletes, and whose boards are whose.
worker/ The accounts API (a Cloudflare Worker with D1 and Better Auth), and the cached data routes for departures.
privacy.html The privacy notice (the Swedish one is in site/).
src/app.js Control bar, share, kiosk mode, and the board state the editor works on.
src/editor.js The editor drawer: the sections, Showing, Boards, a playlist, a board with its content, Explore, Account, and the more menu.
src/looks.js Looks (0.11): materials, type, letter colours and walls from the design handover, the Make your own matrix, and what a screen shows (lookFor). Shared with the Worker.
src/ambient.js The light round the frame, the sky's weather on the wall and the smoothness steps (0.11.1). All CSS layers over the canvas, so Classic's pixels never change.
src/meter.js The Music meter's engine and Listen (0.11.2): the microphone on its own AudioContext, only between Listen and Stop.
src/lookSheet.js The look sheet, opened from every Change: the cards, the preview under the gold bar, Make your own, and the Look row.
src/library.js Boards and playlists (0.10.1): a playlist resolved with its boards, taken apart again after an edit, and the migration from storyboards, shared with the Worker.
src/catalogue.js The picker's tiles, their defaults and their option fields.
src/composer.js Type, Paint and Photo on the grid, undo and redo, earlier messages.
src/photo.js A photo to colour chips, with dithering.

The visual design (tile anatomy, fold shading, themes, timing) came from a design pass documented in DESIGN-HANDOVER.md, with the prototype and spec sheet in design/. The editor came from a second pass, in DESIGN-HANDOVER-editor.md and design/editor/, and its structure from a third, in DESIGN-HANDOVER-0.7.md and design/0.7/. What might come next is in ROADMAP.md.

Data and credits

  • Departures: Transitous, with timetables from these sources and map data from OpenStreetMap contributors, and in Stockholm SL through Trafiklab.
  • Public holidays: Nager.Date.
  • Interest rates: the ECB Data Portal, the Federal Reserve Bank of New York, the Bank of England and Sveriges Riksbank.
  • Stock and ETF prices: Alpha Vantage, through Split-Flap's place in its programme for open-source projects.
  • Crypto prices: CoinGecko.
  • Weather and city search: Open-Meteo, CC BY 4.0 (Creative Commons Attribution 4.0).
  • Electricity prices: elprisetjustnu.se.
  • Exchange rates: European Central Bank reference rates through Frankfurter.
  • On this day: Wikipedia, CC BY-SA 4.0 (Creative Commons Attribution-ShareAlike 4.0).
  • Every source is keyless. Transitous is asked through the Worker, which caches each stop for a minute so every screen watching it shares one request; the rest are read straight from your browser. src/sources.js lists each source with its terms, the date they were read and who to contact. Follow a URL only reads the addresses you give it.
  • QR codes: qrcode-generator by Kazuhiko Arase, MIT, vendored in src/vendor/.
  • Fonts: DM Mono, Schibsted Grotesk, Plus Jakarta Sans and Cormorant Garamond, all SIL Open Font License 1.1.

QR Code is a registered trademark of DENSO WAVE INCORPORATED. Vestaboard is a trademark of Vestaboard, Inc.; this project is not affiliated with it.

Licence

MIT. Made by Matthew MacLaine.

About

A free split-flap message board for any screen: messages, clock, SL departures, weather. Canvas, no build step, no dependencies.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages