Eagle Lake 360

2026
Full-Stack Dev., Game, UI/UX Design

Overview

Eagle Lake 360 began with a conversation on a golf cart.

Eagle Lake is a community in the Poconos, Pennsylvania, that I have visited since I was about four years old. It has always been an escape from the city—a place filled with nature, familiar roads, fishing docks, walking trails, and decades of memories.

One day, while driving around the community with a friend, he mentioned how well he knew every part of Eagle Lake. That sparked an idea: what if there were a GeoGuessr-style game built entirely around the community?

I went home that day and started researching how to make it possible.

What began as a niche guessing game eventually grew into something much larger: an interactive, Google Street View–style map containing more than 900 panoramic locations throughout Eagle Lake.

From an idea to over 900 panoramas

I had experience with traditional photography, but I had never worked with 360° imagery before. I started researching panoramic photography, equirectangular images, and what could be built with Three.js. Once I understood that a panorama could be projected onto the inside of a 3D sphere and explored from its center, the project suddenly felt achievable.

So I ordered a 360° camera and a tripod.

When they arrived, I strapped the camera to the top of my golf cart and began photographing the community. Over roughly one week, I covered around 40 miles of road, capturing a new panorama every few hundred feet on every street.

I also photographed places that could not be reached by golf cart. I walked the hiking trails, visited the pool and beach, photographed fishing docks and recreation areas, and even took the camera onto a paddleboard to capture locations from the middle of the lake.

I was very committed to the bit.

By the end of the process, I had captured more than 1,200 panoramas. After reviewing, processing, and organizing them, I narrowed the collection to roughly 923 locations for the initial release.

Building the experience

I built Eagle Lake 360 with Next.js, React, and TypeScript. The panoramic viewer uses Three.js and custom WebGL rendering to project high-resolution equirectangular photographs around the player.

The public map uses the Google Maps JavaScript API with satellite imagery, custom markers, clustering, geographic boundaries, search, and section-based filtering. Selecting a marker opens its panorama while preserving the map’s current position and filters, making it easy to move between the map and individual locations.

The backend uses Supabase for PostgreSQL data, authentication, player accounts, game history, favorites, reports, statistics, streaks, and leaderboards. Panorama files are stored in a private Cloudflare R2 bucket and delivered through signed URLs.

I also built a custom admin system for managing the entire collection. It includes:

  • Bulk panorama importing
  • EXIF and GPS metadata extraction
  • Automatic image compression with Sharp and MozJPEG
  • Panorama thumbnails
  • Map-based coordinate editing
  • Difficulty and section management
  • Draft and publishing workflows
  • Custom privacy-blur tools for faces, license plates, signs, and properties
  • Engagement analytics, reporting, and user moderation

The import workflow turned what could have been hundreds of repetitive manual uploads into a much more manageable process. Images could be compressed, uploaded, assigned their original GPS coordinates, and converted into draft locations in batches.

Account identity and moderation

Players can create accounts with a unique username, upload a profile photo, track their statistics, build streaks, save favorite locations, and compete on the leaderboards. Profile photos can be cropped, repositioned, zoomed, replaced, edited, or removed through a custom image editor.

Allowing user-generated names and images also introduced a moderation challenge. I wanted accounts to feel personal without creating an easy way to upload inappropriate photos, impersonate a URL, or place offensive language on a public leaderboard.

Every new profile photo is resized and converted into a consistent WebP format before being checked with Google Cloud Vision’s SafeSearch detection. Images identified as adult, racy, violent, or otherwise unsafe are rejected before they become visible. Uploads are also rate-limited to prevent the moderation endpoint from being abused.

Names and usernames pass through a separate text-moderation system. Inputs are Unicode-normalized, checked for URLs and contact information, and evaluated against an obscenity dataset that can recognize common attempts to disguise blocked language.

A particularly important consideration was the classic “Scunthorpe problem,” where an innocent word is rejected simply because it contains a shorter offensive substring. Rather than relying on one inflexible list and assuming every match is malicious, rejected values are recorded for administrative review. Legitimate false positives can be added to a precise allowlist, allowing the moderation system to improve without weakening its protection for everyone else.

From a game to a map

The original idea was only Eagle Lake Guessr. As the photography collection grew, though, it became clear that the images had value beyond a game.

That led to the public map: a way to freely explore Eagle Lake from anywhere. Someone planning a trip can look around before arriving. Someone who has not visited recently can return to a familiar street. Residents can explore areas of the community they may never have seen.

More importantly, Eagle Lake 360 can serve as a time capsule.

Communities change slowly enough that the differences can be difficult to notice. Cabins are remodeled, trees grow, buildings are replaced, and once-familiar places gradually take on a different appearance. I often wonder what it would be like to walk through Eagle Lake as it existed decades ago. We cannot recreate that version now, but this project can preserve what the community looked like in 2026 for people to revisit years from today.

Designing Eagle Lake Guessr

Eagle Lake Guessr turns the panorama collection into a five-round location game. Each round places the player inside a random panorama and asks them to determine where they are before time runs out.

The game includes multiple modes ranging from scenic, recognizable locations to extremely difficult rounds with limited viewing time and no ability to turn around. Scores are based on the real-world distance between the player’s guess and the correct coordinates, with each round worth up to 1,000 points.

Building the game involved more than randomly selecting five photographs. I created selection rules to avoid repeating exact locations, street labels, landmarks, and sections too frequently. The system also tracks which locations a player has already encountered so the full library can be explored before unnecessary repeats occur.

Other features include:

  • Multiple difficulty modes
  • Weekly and all-time leaderboards
  • Player statistics and game history
  • Daily account streaks
  • Location favorites
  • Timed rounds and countdown warnings
  • Custom game settings
  • Responsive guess and answer maps
  • Distance display in imperial or metric units
  • Sound effects and per-round background music
  • A guided first-game tutorial

The tutorial was particularly important. Many community members had never played GeoGuessr or interacted with a 360° panorama before. On their first game, players are shown how to look around, zoom, open the map, place a pin, and submit a guess. It can be skipped or replayed later.

Making mobile a first-class experience

I expected most people to discover the project through the Eagle Lake community’s Facebook group, which meant many of them would open it directly on their phones.

A good mobile experience was therefore not optional.

The gameplay interface was redesigned around touch controls, including swipe-based panorama movement, pinch-to-zoom, a collapsible map, landscape-specific layouts, and controls that remain reachable on smaller screens. The answer screen was also adapted so players could inspect both the correct location and their guess without the result interface blocking the map.

Testing on physical phones revealed issues that browser emulation did not, particularly around touch gestures, mobile Safari audio, viewport sizing, and browser navigation. Solving those problems took considerable iteration, but the result feels like a mobile game rather than a desktop website squeezed onto a phone.

Sound and atmosphere

I wanted the game to feel playful and distinctly separate from the more exploratory public map. I sourced music loops and sound effects from Freesound, then edited and normalized them so that clips from different creators felt consistent when played together.

Audio is preloaded to reduce latency, and each round receives a different music loop without repeating during the same game. Separate sounds accompany placing a pin, submitting a strong or weak guess, counting down the final seconds, and revealing the final score.

Audio controls, including separate music and effects volume settings, are available without interrupting the round.

This was my first time working seriously with audio normalization and seamless loops. It was a relatively small part of the interface, but it made a surprisingly large difference to the personality of the finished game.

Challenges and decisions

High-resolution imagery

A single panorama can be thousands of pixels wide, and loading an unoptimized original every round would be impractical. I tested several resolutions and compression levels before settling on high-resolution images compressed with MozJPEG.

The final workflow uses Sharp to process uploads automatically, preserving enough detail for players to zoom into a panorama without requiring the browser to download the much larger camera originals.

Storage and egress

I initially stored both the application data and panorama files in Supabase. With hundreds of large images being viewed repeatedly, storage egress increased much faster than expected.

Rather than replacing the entire backend, I separated the responsibilities. Supabase remained the database and authentication provider, while the panorama files were migrated to Cloudflare R2. The existing location records were updated to reference the migrated objects, so none of the images needed to be relinked manually.

This significantly reduced the cost of delivering imagery while allowing the rest of the application architecture to remain intact.

Privacy

Publishing a photographic record of a residential community required careful privacy controls. Faces and license plates are blurred throughout the public experience, and the admin editor allows blur regions to be positioned directly on either the flat panorama or inside the 360° viewer.

Each blur area is stored as normalized metadata rather than permanently modifying the source image. This made it possible to support different categories and selectively render certain blurs depending on context while always protecting people and license plates.

The walkable-map experiment

At one point, I prototyped a system that connected nearby panoramas with directional arrows, allowing users to travel from one point to another like Google Street View.

Technically, it worked. Each location could connect to multiple others, arrows could be positioned inside the panorama, and neighboring images could be preloaded to improve transitions.

However, making it feel genuinely smooth would have required carefully building and maintaining a directional graph across hundreds of locations. Small differences in camera orientation, positioning, and lighting also made transitions feel more jarring than I wanted.

I ultimately removed the feature. It was a useful reminder that proving something is technically possible does not always mean it belongs in the final product.

Releasing it to the community

When the project was ready, I shared it with the Eagle Lake community through its Facebook group.

People began exploring familiar streets, comparing scores, building streaks, and competing on the leaderboards. Some recognized locations immediately; others discovered parts of Eagle Lake they had never visited despite spending years in the community.

Seeing people engage with something so specific to a place we shared made the long photography sessions, image processing, mobile debugging, and countless small interface refinements worthwhile.

What I learned

Eagle Lake 360 brought together photography, geospatial data, 3D rendering, game design, responsive interaction, backend architecture, storage optimization, privacy tooling, and community feedback.

It also reinforced several lessons:

  • Test important interactions on real devices, not only browser emulators.
  • High-resolution media requires infrastructure decisions early.
  • Tools built for internal use can become some of the most important parts of a project.
  • A feature can work technically and still be wrong for the experience.
  • Small details—sound timing, map movement, loading states, and touch sensitivity—have an outsized effect on how polished a product feels.
  • The best version of an idea may be larger than the idea that started it.

What began as a joke between two friends on a golf cart became a complete photographic map of a community, a competitive game, and a record that can become more meaningful as time passes.

That evolution is what makes Eagle Lake 360 one of my favorite projects.

Built With

  • Next.js
  • Three.js
  • WebGL
  • React
  • TypeScript
  • Google Maps API
  • Google Cloud Vision
  • Supabase
  • PostgreSQL
  • Cloudflare R2
  • Sharp
  • MozJPEG