Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
사이버펑크 스타일 네온 지도와 MapLibre GL 기반 실시간 우회 경로 제공 PWA형 턴바이턴 GPS 내비게이터, 별도 앱 불필요
Turn-by-turn GPS navigator PWA with a Cyberpunk inspired neon map style. MapLibre GL, live rerouting, no native app required
라이프스타일TypeScript · JavaScriptGitHub @ggigelmo온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
GPS navigator with a Cyberpunk aesthetic.
It's a PWA: deployed as a website and added to the iPhone home screen,
where it launches fullscreen with no Safari bar.
• Vector tile map with a custom style: bluish-black background, roads in
yellow and cyan with a neon glow, buildings extruded in red.
• POI icons by business type (130 categories mapped).
• The camera follows you and turns with your heading. While moving, the
GPS is in charge; stopped, the phone's compass is, because coords.heading
comes back as null without movement.
• HUD with speedometer, heading, accuracy, and position.README 전문 보기 ↗GPS navigator with a Cyberpunk aesthetic.
It's a PWA: deployed as a website and added to the iPhone home screen, where it launches fullscreen with no Safari bar.
In production: https://games-map.ggigelmo.workers.dev
Map and position
coords.heading
comes back as null without movement.Search and go
DIAG panel
Measures on the real device what can't be assumed: GPS accuracy and interval, standalone mode, screen lock, available synthesis voices, and compass. It exists because several of the project's decisions depended on data only the iPhone could provide.
npm install
npm run dev
Open http://localhost:5173. Add ?lab for style-tuning desktop controls
(jumps between cities, a zoom sweep, a zoom/pitch/bearing readout).
The repo is an npm workspace: it's installed and run from the root, not
from app/. If 5173 is taken, PORT=5174 npm run dev.
On localhost the Stadia API works without a key (with a stricter rate
limit), so there's nothing to configure for development.
npm test
47 tests, all over pure logic. They cover what can't be checked without driving: projection onto the route, next maneuver, remaining distance and time, deviation detection, and the reroute state machine.
GPS traces are generated by walking a real polyline captured from the
API (app/src/services/routing.fixture.ts). Three cases that matter:
| Case | What it checks |
|---|---|
| Clean run | Maneuvers advance in order and a deviation is never declared |
| Deliberate deviation | The deviation fires on the third reading, and not before |
| ±60 m noise | Must not declare a deviation: it's the false positive that ruins these apps |
style/build.mjs style generator <- this is where the look is tuned
style/cyberpunk.json generated artifact (35 layers), portable to any MapLibre
assets/lib/poi-icons.mjs POI glyphs and which business gets each one
assets/lib/raster.mjs RGBA rasterizer and PNG encoder, no dependencies
assets/make-sprite.mjs draws the POI sprite (1x and 2x)
assets/make-icons.mjs draws the PWA icons
app/src/
main.ts wiring and UI state machine
map/map.ts map, cameras (following / preview / navigation), marker
hud/ speedometer and readouts
search/ fullscreen search
route/ route layer on the map and summary card
nav/ navigation: PURE logic + orchestrator
snap.ts projects your position onto the route
progress.ts next maneuver, remaining distance and time
off-route.ts deviation detection
session.ts state machine (the only impure thing in the folder)
maneuver-card.ts next-turn card
services/
geolocation.ts sole owner of watchPosition
compass.ts device compass
heading.ts who's in charge of heading: GPS while moving, compass while stopped
keep-awake.ts keeps the screen from turning off
stadia.ts shared HTTP client
geocoding.ts destination autocomplete
routing.ts Valhalla routes and polyline decoder
geo-math.ts haversine and distance/time formatting
diag/probe.ts diagnostics panel
docs/findings.md pitfalls found and why the code is the way it is
docs/status.md project status and what's left
The nav/ folder is deliberately split into pure logic and an orchestrator:
it's the only thing that makes it possible to test the behavior without
going out on the road.
style/cyberpunk.json is never hand-edited: style/build.mjs generates
it from a palette and a road-class table. Edit build.mjs, save, and the
map updates itself without reloading the page or losing the camera (a Vite
plugin re-runs the generator and HMR reapplies the style).
The neon comes from stacking three line layers per road class:
| layer | width | line-blur | opacity | role |
|---|---|---|---|---|
glow | x3 to x5.5 | high | 0.10 - 0.45 | the color halo |
mid | x1.7 | low | 0.40 | the body |
core | x1 | 0 | 1 | the lightened filament |
The two knobs that matter most:
coreLighten per class. Go above ~0.4 and it kills the color and
everything turns white: the map stops looking like neon and starts
looking like a normal map with light-colored streets.Buildings come out red because of a shader interaction discovered while investigating a bug and kept on purpose. It's explained in docs/findings.md §1, along with how to turn them back blue.
Every business carries its category's icon: a medpoint cross for pharmacies and health centers, a glass for bars, a noodle cup for restaurants, a box for shops, an arrow for stops and stations, towers for schools and offices.
Everything comes from assets/lib/poi-icons.mjs, the single source of
truth:
ICONS = the 15 glyphs, drawn as code (no SVG, no dependencies).MEMBERS = which business types get each icon, tagged with OpenMapTiles
class labels (130 types mapped).Both generators pull from that file, so they can't get out of sync:
assets/make-sprite.mjs draws the sprite, and style/build.mjs builds the
style's icon-image expression.
npm run sprite
To change which icon a business type gets, move its tag from one list
to another in MEMBERS. A tag in two lists throws an error at generation
time, because a MapLibre match expression rejects repeated tags, and that
would break the whole style on load.
To add a new icon, drop its glyph into ICONS and its list into
MEMBERS. It's drawn in a 24x24 box with segment, polyline, polygon,
and circle; the generator already paints the plate and border before
calling the glyph.
Maneuver arrows are separate (nav/maneuver-card.ts) and are inline SVG,
because they live in the HUD, not on the map: they need neither a sprite
nor SDF glyphs.
All glyphs are original, in the game's visual language. They are not Cyberpunk 2077's own assets, which are the property of CD Projekt Red.
| What | Who | Key |
|---|---|---|
| Vector tiles | OpenFreeMap (OpenMapTiles schema) | Not needed |
| Destination autocomplete | Stadia Maps (Pelias) | By domain |
| Driving routes | Stadia Maps (Valhalla) | By domain |
There is no API key in the code. Stadia authenticates by domain: it
validates the Origin and Referer headers that the browser sends on its
own. Just register the domain in Stadia's panel, under Authentication
Configuration:
games-map in
Subdomain and ggigelmo.workers.dev in Domain. No https://.401 No valid authentication provided.
Debugging in that window isn't worth it.Worth keeping in mind: if Referrer-Policy: no-referrer is ever set on the
site, authentication stops working.
Known limitation: since there's no per-user key, search and routing share one free-tier quota across every visitor to the live demo. If it runs out for the month, the search box shows "demo search limit reached for now, try again later" instead of results — that's the quota talking, not a bug.
Valhalla returns instructions already drafted in whatever language is requested, including three variants meant to be read aloud. That's what made adding voice easy.
Already configured. In Workers & Pages → Create → Import a repository,
with ggigelmo/games-map:
| Field | Value |
|---|---|
| Build command | npm run build |
| Deploy command | npx wrangler deploy |
| Root directory | / |
The build runs from the repo root, not from app/. That works because the
root package.json declares app as an npm workspace: npm install
installs the workspace's dependencies and npm run build delegates to it.
It also keeps the build from having to go up a level to find style/.
wrangler.jsonc defines a Worker with no code, only assets, so it
doesn't carry a main. To validate the configuration without deploying or
needing credentials:
npm run build && npx wrangler deploy --dry-run
To deploy from your own machine instead of via Git (requires
npx wrangler login once):
npm run deploy
The single-page fallback is provided by not_found_handling in
wrangler.jsonc. app/public/_headers exists because it does something
wrangler.jsonc doesn't: pin the manifest's Content-Type.
When generating the lockfile, do it clean: a partial
npm installon Windows only records that platform's native binaries, and the Linux build fails withCannot find module @rollup/rollup-linux-x64-gnu. Details and a one-line check in docs/findings.md §8.
Open the URL in Safari (not Chrome), Share → Add to Home Screen. It launches fullscreen, with no browser bar.
First, on the iPhone: Settings → Privacy & Security → Location Services → Safari → Precise Location on. Without it, the GPS returns a position with 3-9 km of error and only refreshes it every 15 minutes, with no error raised at all. The
DIAGpanel detects it and says so.
Worth reading in DIAG the first time:
| Reading | Good | Bad |
|---|---|---|
| Accuracy | ≤ 30 m | Kilometers → Precise Location disabled |
| Interval between fixes | ≤ 5 s | Minutes → same cause |
| Screen wake lock | NATIVE API or VIDEO | NOT ACTIVE |
| Compass | Tap ENABLE COMPASS; it then shows the live heading | PERMISSION DENIED |
| Voices (en / total) | ≥ 1 in English | 0 → the app won't be able to speak |
| Command | What it does |
|---|---|
npm run dev | Dev server with hot-reloading of the style |
npm test | Pure-logic tests |
npm run build | Typecheck and production build |
npm run style | Regenerates style/cyberpunk.json |
npm run sprite | Regenerates the POI sprite and the style |
npm run icons | Regenerates the PWA icons |
npm run deploy | Build and deploy with wrangler |