360° Panoramic Scenes Virtual Tour - JavaScript (Vanilla), HTML5, CSS3, Marzipano Viewer Library Fundamental Project 2 (Framework-free SPA)
A beginner-friendly, framework-free 360° virtual tour web app designed for learning modern frontend fundamentals while building something practical and interactive. It demonstrates how to combine panoramic scene rendering, reusable UI patterns, responsive design, and deployment-ready structure using only vanilla JavaScript, HTML, and CSS.
- Live Demo: https://360-panoramic-tour.vercel.app/
- Project Overview
- Key Features
- Tech Stack & Libraries
- Project Structure
- How the Project Works
- Environment Variables (.env)
- Installation & Local Run
- Linting & Build
- Deployment (Vercel)
- Detailed File Walkthrough
- Reusability Guide
- Extending the Project
- Beginner Learning Notes
- API / Backend Notes
- Keywords
- Conclusion
360-virtual-tour is a static Single Page Application (SPA) that lets users:
- explore multiple 360° panoramic scenes,
- switch scenes using sidebar navigation and hotspot links,
- use autorotate and fullscreen controls,
- interact with a modern educational UI shell (cards, tabs, table, FAQ, badges, gallery).
The app uses scene data from data.js and renders visuals from tiled panoramic assets stored under tiles/.
- Interactive 360° panorama viewer using Marzipano
- Scene-to-scene navigation via clickable hotspots
- Info hotspot modal support on mobile
- Scene list sidebar with current-scene highlight
- Fullscreen stage mode for immersive viewing
- Autorotate toggle
- Responsive layout (desktop + mobile)
- Reusable UI sections for educational showcase:
- feature cards
- tabs
- FAQ dropdowns
- badge stats
- dynamic gallery with offline fallback
- SEO metadata optimized for discoverability
- Vercel-ready static deployment pipeline (
dist/output)
- JavaScript (Vanilla): app logic, interactivity, rendering helpers
- HTML5: semantic structure
- CSS3: custom design system, animation, responsiveness
- Marzipano: renders and controls 360° panoramic scenes
- Screenfull: normalized fullscreen API behavior across browsers
- Bowser: browser capability detection/fallback handling
- Reset CSS (
vendor/reset.min.css): baseline style normalization
- ESLint: code quality checks
- Node scripts: static file build/copy for deployment
360-virtual-tour/
├── index.html # Main page structure + metadata
├── index.js # Viewer setup + reusable UI rendering logic
├── style.css # Full styling system and responsive rules
├── data.js # Scene graph, hotspots, initial camera params
├── tiles/ # Panorama tiles + preview assets per scene
├── public/
│ ├── favicon.svg # Favicon / logo
│ └── images/ # UI control icons
├── vendor/ # Third-party browser libraries
├── scripts/
│ └── copy-static.mjs # Build script to create dist/
├── docs/ # Project/deployment/styling notes
├── package.json # Scripts + dev dependencies
├── vercel.json # Build/output/SPA rewrite config
└── README.md # Project documentationDefines a global APP_DATA object with:
- scene ids and names,
- tile level sizes,
- initial yaw/pitch/fov,
- link hotspots (
targetscene), - info hotspots (title/text blocks),
- viewer settings.
- initializes Marzipano viewer,
- creates scene instances dynamically from
APP_DATA, - binds controls (up/down/left/right/zoom),
- handles sidebar switching,
- handles fullscreen/autorotate,
- renders additional educational UI modules.
- top navigation and hero section,
- embedded tour stage,
- reusable content sections (cards, tabs, gallery, table, FAQ),
- responsive behavior and transitions.
This project runs without any required .env file.
- None
If you later move to dynamic image APIs or analytics:
UNSPLASH_ACCESS_KEY(only if using official Unsplash API endpoints)VITE_ANALYTICS_IDor similar (if analytics integration is added in future)
For the current setup, image fallback works without keys, and deployment is purely static.
python3 -m http.server 8000Open: http://localhost:8000
npm install
npm run buildThen serve dist/ with any static server.
npm run lintnpm run buildBuild output goes to dist/ via scripts/copy-static.mjs.
This project is configured as a plain JS static app:
buildCommand:npm run buildoutputDirectory:dist- SPA rewrite to avoid refresh 404:
- all routes rewrite to
/index.html
- all routes rewrite to
See full deployment instructions in:
docs/VERCEL-PLAIN-JS-DEPLOY.md
- contains SEO metadata,
- loads styles/scripts/vendors,
- defines all layout sections and Marzipano control elements.
- reusable helper functions for element creation/rendering,
- scene creation and event wiring,
- hotspot creation logic,
- mobile/desktop mode handling,
- section rendering for gallery/cards/tabs/FAQ.
- color tokens and design variables,
- reusable classes (
max-w-9xl, cards, badges, tables), - scene control skinning,
- responsive breakpoints,
- reduced-motion accessibility handling.
- source of truth for all scenes/hotspots.
- copies runtime files and directories to
dist/, - cleans stale build output before each build.
You can reuse this project in other virtual tour apps by copying:
index.jsscene bootstrap + hotspot functionsstyle.csscontrol styles and section componentsscripts/copy-static.mjsstatic deployment build logic
function createElement(tag, className, text) {
const el = document.createElement(tag);
if (className) el.className = className;
if (typeof text === "string") el.textContent = text;
return el;
}This keeps rendering logic clean and beginner-friendly.
- Add scene tiles under
tiles/<scene-id>/ - Add scene object in
data.js - Add matching sidebar item in
index.html(or generate dynamically if you prefer)
Add to linkHotspots or infoHotspots in the target scene object in data.js.
- Create a container in
index.html - Add styles in
style.css - Render with a reusable
init...()function inindex.js
This project is useful to learn:
- DOM selection, events, and state-by-class toggles
- modular vanilla JS patterns without frameworks
- responsive CSS strategies
- progressive enhancement for fullscreen and touch behavior
- static deployment architecture (build + rewrite)
- SEO metadata fundamentals in pure HTML
- Backend: None
- Database: None
- External runtime API: None required
- Architecture type: fully static frontend SPA
All scene and navigation logic is client-side and data-driven from local files.
360° virtual tour, panoramic scenes, Marzipano, Vanilla JavaScript, HTML5, CSS3, SPA, hotspot navigation, fullscreen panorama, responsive UI, educational frontend project, static deployment, Vercel.
This project is a practical and educational foundation for anyone learning frontend fundamentals through an interactive real-world build. It is intentionally framework-free, easy to inspect, and simple to extend into real estate tours, campus walkthroughs, museums, hospitality previews, and more.
This project is licensed under the MIT License. Feel free to use, modify, and distribute the code as per the terms of the license.
This is an open-source project - feel free to use, enhance, and extend this project further!
If you have any questions or want to share your work, reach out via GitHub or my portfolio at https://www.arnobmahmud.com.
Enjoy building and learning! 🚀
Thank you! 😊





