GitHunt
DE

deaneeth/furnish-view-hci-project

A Java Swing furniture room visualizer with 2D layout and 3D rendering for in-store design consultations - PUSL3122 Coursework 2025-26

FurnishView

Interactive 2D/3D Room Design & Furniture Visualisation Tool

Empowering furniture designers to create, visualise, and present room layouts โ€” from a quick 2D top-down canvas to an immersive, orbit-able 3D scene.


JavaScript ES6+ Three.js r160 HTML5 Canvas CSS3 MVC Architecture localStorage Zero Build Step PUSL3122 MIT License

๐Ÿš€ Live Demo ย ยทย  ๐ŸŽฌ Video Walkthrough ย ยทย  โšก Quick Start ย ยทย  ๐Ÿ—๏ธ Architecture


Preview


๐Ÿ“‹ Table of Contents (click to expand)

๐Ÿช‘ Overview

FurnishView is a web-based room design tool built for in-store furniture consultations. A designer logs in, inputs a customer's room specifications, places furniture on a 2D top-down canvas, then generates a full 3D walkthrough-ready scene โ€” all in the browser, with no installation required.

Built as coursework for PUSL3122 โ€” HCI & Computer Graphics (2025โ€“26), the project demonstrates layered MVC architecture, hand-coded 2D canvas algorithms, Three.js 3D rendering with proper lighting and shading, and a full user-centred design process backed by formative and summative usability studies.

Attribute Detail
Module PUSL3122 โ€” HCI & Computer Graphics
University Plymouth University Sri Lanka (PUSL)
Year 2025โ€“26
Tech JavaScript (ES6+) ยท HTML5 Canvas ยท Three.js r160 ยท CSS3
Run Open index.html in Chrome/Firefox โ€” no npm, no server, no setup

โœจ Key Features

๐Ÿ  Room Design

  • Rectangular & L-shaped room support
  • Real-world dimensions (meters) with pixel-accurate 2D scaling
  • Customisable wall & floor colours
  • One-click room preset templates (Studio, Living Room, Dining Room, Bedroom)

๐Ÿ–ฑ๏ธ 2D Canvas Engine

  • Drag-and-drop furniture placement
  • Hand-coded hit detection (point-in-rectangle)
  • Boundary clamping โ€” furniture stays inside walls
  • Drag-offset calculation for smooth, jump-free movement
  • Undo / redo for placement and removal
  • Keyboard shortcuts (Del, Ctrl+S, Ctrl+Z)

๐ŸŒ 3D Visualisation

  • Three.js scene with PerspectiveCamera + OrbitControls
  • Ambient + Directional lighting with cast shadows
  • MeshStandardMaterial for physically-based shading
  • Room exported as PNG from WebGL canvas

๐Ÿ“ Design Comparison (Innovation)

  • Side-by-side 3D render of two saved designs
  • Same room, different furniture configurations
  • Customer picks their preferred layout on the spot

๐Ÿค– Auto-Arrange (Innovation)

  • One-click furniture optimisation algorithm
  • Distributes pieces using spacing rules derived from interior design conventions

๐Ÿ›’ E-commerce Pipeline (Innovation)

  • Furniture catalogue with realistic item dimensions
  • Export design as PNG or PDF for customer take-home reference

๐Ÿ” Role-Based Auth

  • Designer login with session persistence via localStorage
  • Admin dashboard with system-wide design management (see Authentication)

๐Ÿ’พ Data Handling

  • Full CRUD on designs โ€” create, read, update, delete
  • JSON serialisation to localStorage, no backend needed
  • Sample data pre-loaded for demonstrations

๐Ÿ“ธ Screenshots & Demos

Landing Page
Landing Page โ€” clean, minimal entry point
Login / Auth Screen
Authentication โ€” role-based login (Designer / Admin)
2D Canvas Editor
2D Editor โ€” top-down drag-and-drop furniture layout
3D Visualisation
3D View โ€” orbit-able Three.js scene with shadows
Design Comparison
Comparison Mode โ€” two designs rendered side-by-side
Dashboard
Dashboard โ€” design portfolio with saved room cards

๐Ÿ—๏ธ Architecture

FurnishView enforces strict Modelโ€“Viewโ€“Controller separation. Each layer has a defined responsibility โ€” crossing boundaries is a code smell and is actively avoided.

flowchart TD
    subgraph Models["๐Ÿ“ฆ Models (js/models/)"]
        R[Room.js]
        F[FurnitureItem.js]
        D[Design.js]
    end

    subgraph Views["๐Ÿ–ผ๏ธ Views (js/views/)"]
        LV[LoginView.js]
        DV[DashboardView.js]
        EV[EditorView.js]
        subgraph Components["components/"]
            TB[Toolbar.js]
            SB[Sidebar.js]
            M[Modal.js]
            T[Toast.js]
        end
    end

    subgraph Controllers["๐ŸŽฎ Controllers (js/controllers/)"]
        DC[DesignController.js]
        CC[CanvasController.js]
    end

    subgraph Graphics["๐ŸŽจ Graphics (js/graphics/)"]
        R2D[Renderer2D.js]
        R3D[Renderer3D.js]
        CM[ColourManager.js]
    end

    subgraph Utils["๐Ÿ› ๏ธ Utils (js/utils/)"]
        ST[storage.js]
        SC[scaleCalculator.js]
        CN[constants.js]
    end

    app.js -->|initialises| Views
    Views -->|calls| Controllers
    Controllers -->|mutates| Models
    Controllers -->|triggers| Graphics
    Graphics -->|reads| Models
    Graphics -->|uses| Utils
    Controllers -->|uses| Utils
    Models -->|serialised by| ST

Separation of Concerns

Layer Responsibility What it never does
Models Pure data โ€” room/furniture/design state No DOM, no rendering, no events
Views Generate HTML, render to DOM, bind events Never access models directly for logic
Controllers Orchestrate views โ†” models, handle business logic No direct DOM manipulation, no raw canvas calls
Graphics All canvas and Three.js rendering Knows nothing about the DOM outside its canvas

Key Design Decisions

  • Zero build step โ€” no Webpack, Vite, or npm. Open index.html and it works. Assessed work must run offline.
  • Three.js r160 bundled locally in lib/ โ€” CDN failure cannot break submissions.
  • MeshStandardMaterial enforced โ€” no MeshBasicMaterial anywhere. All geometry responds to lighting for visible shading.
  • preserveDrawingBuffer: true on the WebGL renderer โ€” enables PNG export without a blank canvas bug.

๐Ÿ› ๏ธ Tech Stack

LayerTechnologyVersionWhy
Language JS ES2022 Module-leader approved, fastest iteration, native browser support
2D Rendering Canvas Native Hand-coded algorithms demonstrate computer graphics knowledge
3D Rendering Three.js r160 Industry-standard WebGL library; orbit controls, lighting, PBR materials
Styling CSS3 CSS3 Design tokens via CSS custom properties, no framework overhead
Storage localStorage Browser API No backend required; full CRUD on designs as serialised JSON
Build No build โ€” Zero setup for the marker. Clone โ†’ open โ†’ done.

โšก Quick Start

Prerequisites

  • A modern browser: Chrome 90+ or Firefox 88+ (WebGL and ES modules required)
  • For ES module support without a server: use VS Code Live Server extension

Option 1 โ€” Direct File Open (Simplest)

# Clone the repository
git clone https://github.com/deaneeth/furnish-view-hci-project.git
cd furnish-view-hci-project

# Open in your browser
# On Windows:
start index.html
# On macOS:
open index.html
# On Linux:
xdg-open index.html

โš ๏ธ Some browsers block ES module imports from file:// URLs. If the app shows a blank screen, use Option 2.

  1. Open the project folder in VS Code
  2. Install the Live Server extension if not already installed
  3. Right-click index.html โ†’ Open with Live Server
  4. App opens at http://127.0.0.1:5500

Option 3 โ€” Simple HTTP Server

# Python 3
python -m http.server 8080
# Then visit http://localhost:8080

# Node.js (npx, no install needed)
npx serve .
# Then visit http://localhost:3000

Test Credentials

Role Username Password
Designer designer1 password123
Designer designer2 password123
Admin admin admin123

๐Ÿ” Authentication

FurnishView uses a client-side, role-based authentication system backed entirely by localStorage.

furnishview_users    โ†’ Array of registered designer credentials
furnishview_session  โ†’ Currently active session (cleared on logout)
furnishview_designs  โ†’ All saved Design objects (filtered per designer on load)
Role Access
Designer Create, view, edit, and delete their own designs only
Admin View and manage all designs across all designers; system-level controls

Session persists across browser refreshes until the user explicitly logs out. No cookies, no tokens, no network calls.


๐Ÿ”ฌ Feature Deep-Dive

๐Ÿ–ฑ๏ธ 2D Canvas Engine (Renderer2D.js)

The 2D canvas is a hand-coded computer graphics engine built on the raw HTML5 Canvas API. No canvas frameworks are used โ€” every algorithm is implemented from scratch.

Coordinate Scaling

scaleFactor = canvasWidth / roomWidthInMeters
pixelX = realWorldX ร— scaleFactor
pixelY = realWorldY ร— scaleFactor

All furniture positions are stored in real-world meters. On every render pass, they are scaled to canvas pixels using this factor.

Hit Detection
A classic point-in-axis-aligned-rectangle (AABB) test for click/select:

isHit = (clickX >= item.x) && (clickX <= item.x + item.width)
     && (clickY >= item.y) && (clickY <= item.y + item.depth)

Items are tested in reverse render order so the topmost rendered item gets selection priority.

Boundary Clamping
Furniture cannot be dragged outside the room boundary:

item.x = clamp(item.x, 0, room.width - item.width)
item.y = clamp(item.y, 0, room.depth - item.depth)

Drag Offset
On mousedown, the offset between the cursor and the item's top-left corner is captured:

offset.x = mouseX - item.x
offset.y = mouseY - item.y

During mousemove, position is updated as item.x = mouseX - offset.x โ€” the item follows the cursor without jumping.

Render Loop
clearRect() โ†’ draw room outline โ†’ draw grid (optional) โ†’ draw all furniture โ†’ highlight selected item. Runs on every mouse event during drag via requestAnimationFrame.

๐ŸŒ 3D Visualisation Engine (Renderer3D.js)

Built with Three.js r160. The scene is constructed entirely from primitives โ€” no external 3D model files.

Scene Setup

// Core pipeline
Scene โ†’ PerspectiveCamera โ†’ WebGLRenderer (preserveDrawingBuffer: true) โ†’ OrbitControls

// Lighting (critical for shading marks)
AmbientLight(0xffffff, 0.6)      // Base illumination
DirectionalLight(0xffffff, 0.8)  // Creates shadows + visible shading

Room Geometry

  • Floor โ€” PlaneGeometry, rotated โ€“90ยฐ on X axis, positioned at Y = 0
  • Walls โ€” Four thin BoxGeometry meshes positioned at room edges

Furniture Geometry

  • Each item โ†’ BoxGeometry(width, height, depth) with MeshStandardMaterial
  • Positioned by mapping 2D canvas coordinates โ†’ 3D world space:
    3D.x = (2D.x / scaleFactor) - (roomWidth / 2)
    3D.z = (2D.y / scaleFactor) - (roomDepth / 2)
    3D.y = furnitureHeight / 2   // sits on the floor
    

Colour Synchronisation
ColourManager.js maps hex colour strings from the model to Three.js Color objects, keeping 2D and 3D appearances identical.

Export

const dataURL = renderer.domElement.toDataURL('image/png')
// Works because preserveDrawingBuffer: true was set on construction
๐Ÿค– Auto-Arrange Algorithm (Innovation)

The auto-arrange feature distributes furniture items within the room using a rule-based spatial algorithm:

  1. Calculate the room's usable area (accounting for wall clearance โ€” typically 0.5m from each wall)
  2. Group furniture by type (seating, tables, storage)
  3. Place tables first at functional positions (dining table centred, bedside tables flanking bed)
  4. Distribute seating around tables using angular offsets
  5. Fill remaining space with storage units along walls
  6. Run boundary clamp on all positions to guarantee no overlaps with walls

The algorithm respects standard interior design clearance rules (e.g., 0.9m aisle width around dining tables) derived from BS 8300 accessibility guidelines.

๐Ÿ“ Design Comparison Mode (Innovation)

Renders two saved designs simultaneously in a split-screen layout:

  • Two independent Three.js WebGLRenderer instances, each targeting a separate <canvas> element
  • Both share the same lighting parameters for fair visual comparison
  • OrbitControls attached to each canvas independently โ€” rotating one view does not affect the other
  • The designer selects two designs from the dashboard; the comparison view loads them in parallel

This reuses 100% of the existing Renderer3D class โ€” the comparison view is essentially two editor panels with their sidebars hidden.

๐Ÿ›’ E-commerce Pipeline (Innovation)

After finalising a design, the designer can generate a customer take-home document:

  1. PNG Export โ€” canvas.toDataURL('image/png') for the 2D view; renderer.domElement.toDataURL() for 3D
  2. PDF Export โ€” Uses jsPDF (loaded from lib/) to compose a document containing:
    • Design name and date
    • 2D layout screenshot
    • 3D render screenshot
    • Bill of materials โ€” furniture items with type, colour, and catalogue dimensions

The generated PDF is downloaded directly in the browser โ€” no server upload required.

๐Ÿ  Room Preset Templates (Innovation)

Defined in js/data/roomPresets.js, each preset auto-populates the room setup form:

Preset Width Depth Height Default Wall Default Floor
Studio Apartment 6m 5m 2.8m #F5F0EB #C8B89A
Living Room 5m 4m 2.8m #E8E0D4 #8B7355
Dining Room 4.5m 3.5m 2.6m #EDE8E0 #6B5344
Bedroom 4m 3.5m 2.7m #F0EBE5 #A0896C

Selecting a preset fires a single event that populates all six form fields instantly, supporting Heuristic #7 โ€” Flexibility and Efficiency of Use (Nielsen, 1994).


๐Ÿ“ Project Structure

furnish-view-hci-project/
โ”œโ”€โ”€ index.html                    # Entry point โ€” loads js/app.js as ES module
โ”‚
โ”œโ”€โ”€ css/
โ”‚   โ”œโ”€โ”€ main.css                  # Global styles, CSS custom properties, layout
โ”‚   โ”œโ”€โ”€ components.css            # Toolbar, Sidebar, Modal, Toast styles
โ”‚   โ””โ”€โ”€ canvas.css                # 2D/3D canvas container sizing
โ”‚
โ”œโ”€โ”€ js/
โ”‚   โ”œโ”€โ”€ app.js                    # Initialisation, view routing (login โ†’ dashboard โ†’ editor)
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ auth/
โ”‚   โ”‚   โ””โ”€โ”€ auth.js               # Login validation, session management
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ models/                   # โ”€โ”€ Pure data objects, zero DOM/rendering โ”€โ”€
โ”‚   โ”‚   โ”œโ”€โ”€ Room.js               # Dimensions, shape, wall/floor colour
โ”‚   โ”‚   โ”œโ”€โ”€ FurnitureItem.js      # Type, position, dimensions, colour, rotation
โ”‚   โ”‚   โ””โ”€โ”€ Design.js             # One Room + FurnitureItem[] + metadata
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ views/                    # โ”€โ”€ DOM rendering, HTML generation โ”€โ”€
โ”‚   โ”‚   โ”œโ”€โ”€ LoginView.js
โ”‚   โ”‚   โ”œโ”€โ”€ DashboardView.js
โ”‚   โ”‚   โ”œโ”€โ”€ EditorView.js
โ”‚   โ”‚   โ””โ”€โ”€ components/
โ”‚   โ”‚       โ”œโ”€โ”€ Toolbar.js        # Furniture catalogue + action buttons
โ”‚   โ”‚       โ”œโ”€โ”€ Sidebar.js        # Room & furniture property panels
โ”‚   โ”‚       โ”œโ”€โ”€ Modal.js          # Reusable confirmation / wizard modals
โ”‚   โ”‚       โ””โ”€โ”€ Toast.js          # Non-blocking action notifications
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ controllers/              # โ”€โ”€ Event handling, logic orchestration โ”€โ”€
โ”‚   โ”‚   โ”œโ”€โ”€ DesignController.js   # CRUD design workflow
โ”‚   โ”‚   โ””โ”€โ”€ CanvasController.js   # Mouse/touch events on 2D canvas
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ graphics/                 # โ”€โ”€ All rendering logic โ”€โ”€
โ”‚   โ”‚   โ”œโ”€โ”€ Renderer2D.js         # HTML5 Canvas 2D engine (hand-coded algorithms)
โ”‚   โ”‚   โ”œโ”€โ”€ Renderer3D.js         # Three.js scene manager
โ”‚   โ”‚   โ””โ”€โ”€ ColourManager.js      # Colour sync across 2D + 3D views
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ utils/
โ”‚   โ”‚   โ”œโ”€โ”€ storage.js            # localStorage CRUD wrapper
โ”‚   โ”‚   โ”œโ”€โ”€ scaleCalculator.js    # Real-world โ†” pixel/unit conversions
โ”‚   โ”‚   โ””โ”€โ”€ constants.js          # App-wide constants, default values
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ data/
โ”‚       โ”œโ”€โ”€ furnitureCatalogue.js # Furniture type definitions + default dimensions
โ”‚       โ””โ”€โ”€ roomPresets.js        # Pre-built room templates (innovation feature)
โ”‚
โ”œโ”€โ”€ lib/                          # Three.js r160 โ€” committed, works offline
โ”‚   โ”œโ”€โ”€ three.module.js
โ”‚   โ”œโ”€โ”€ three.min.js
โ”‚   โ””โ”€โ”€ OrbitControls.js
โ”‚
โ”œโ”€โ”€ assets/
โ”‚   โ”œโ”€โ”€ screenshots/              # App screenshots for README and report
โ”‚   โ”œโ”€โ”€ textures/                 # Optional floor/wall texture maps
โ”‚   โ””โ”€โ”€ sample-data/              # Pre-loaded designs for demo (video)
โ”‚
โ”œโ”€โ”€ formative-docs/               # Formative usability study documentation
โ”‚   โ”œโ”€โ”€ P1.md / P2.md             # Raw observer session notes
โ”‚   โ”œโ”€โ”€ participant-P1.md         # Structured observation sheet โ€” P1
โ”‚   โ”œโ”€โ”€ participant-P2.md         # Structured observation sheet โ€” P2
โ”‚   โ”œโ”€โ”€ observer-sheet.md         # Study summary and findings
โ”‚   โ””โ”€โ”€ observation-sheet-RESEARCHER-USE.md  # Filled researcher log
โ”‚
โ””โ”€โ”€ requirements/
    โ”œโ”€โ”€ PROJECT OVERVIEW.md       # Full project blueprint and architecture spec
    โ”œโ”€โ”€ End-to-End-Project-Roadmap.md  # Phase-by-phase implementation roadmap
    โ””โ”€โ”€ REPO_WORKFLOW.md          # Branch, commit, and PR conventions

๐Ÿงช Testing & Evaluation

FurnishView underwent a two-phase HCI evaluation following the think-aloud protocol and System Usability Scale (SUS) methodology.

Formative Study (Pre-Implementation)

Attribute Detail
When After lo-fi prototypes, before hi-fi design
Method Think-Aloud Protocol
Participants P1, P2 (anonymised adults, target user profile)
Tasks 5 realistic in-store consultation tasks
Artefacts Test plan ยท Consent forms ยท Observation sheets ยท Session notes

Key findings that shaped the hi-fi design:

  • The "3D View" toggle was labelled "Visualise" in the lo-fi prototype โ€” participants did not associate it with 3D. โ†’ Renamed to "3D View" in hi-fi.
  • The undo button was missing from the lo-fi toolbar โ€” P1 accidentally deleted furniture and could not recover. โ†’ Undo added as a persistent toolbar action.
  • Toolbar icons were considered too small on a tablet-sized display. โ†’ Icons enlarged to 32 ร— 32px minimum in hi-fi.
  • P2 expected clicking a furniture item to open its properties automatically. โ†’ Sidebar refreshes on item selection in implementation.

Summative Study (Post-Implementation)

Attribute Detail
When After working app was complete
Method Think-Aloud Protocol + SUS Questionnaire
Participants P3, P4 (anonymised adults)
SUS Score 78.75 / 100 โ€” "Good" usability band (Bangor et al., 2009)
Task Completion 100% across all 5 tasks for both participants

Key SUS interpretation: Score 78.75 places FurnishView in the "Good" tier (above the industry average of 68), indicating the interface is learnable, efficient, and satisfying for the target user demographic.

Areas for further improvement identified:

  • 3D scene takes slightly longer to load for rooms with many items (optimisation opportunity)
  • Rotation handle for furniture on the 2D canvas was not immediately discoverable (discoverability improvement needed)

๐ŸŽฏ HCI Framework Alignment

Nielsen's 10 Usability Heuristics (Nielsen, 1994)

# Heuristic FurnishView Implementation
1 Visibility of System Status Toast notifications on every action; selected furniture highlighted; loading indicator during 3D build
2 Match System and Real World Dimensions in metres; furniture named "Dining Table" not "Item_003"; spatial layout mirrors a physical room
3 User Control and Freedom Undo button for placement/removal; cancel on all dialogs; back navigation from editor to dashboard
4 Consistency and Standards Single colour picker component reused everywhere; Ctrl+S saves in all views; consistent button hierarchy
5 Error Prevention Confirmation modal before delete; room dimension validation (no negative/zero values); boundary clamping
6 Recognition Rather Than Recall Furniture shown as visual thumbnails; saved designs as named cards; recent colours visible in picker
7 Flexibility and Efficiency of Use Drag-and-drop; Del key removes selection; room presets reduce setup from 6 fields to 1 click
8 Aesthetic and Minimalist Design Clean layout โ€” only relevant controls visible per mode; whitespace used intentionally
9 Help Users Recover from Errors Descriptive validation messages; undo for accidental changes; non-destructive colour edits
10 Help and Documentation Tooltips on all toolbar buttons; placeholder text in all form fields

Norman's Design Principles (Norman, 1988)

Principle FurnishView Application
Visibility Toolbar always visible; active tool highlighted; selected item shows handles
Feedback Toast on every action; canvas redraws instantly on drag; 3D updates on colour change
Constraints Boundary clamping; form validation; radio buttons for room shape (not free text)
Consistency Same colour picker for walls, floor, and furniture; Ctrl+S always saves
Affordance Furniture thumbnails invite dragging (cursor changes on hover); colour swatches look selectable

๐Ÿค Contributing

This is academic coursework โ€” external PRs are not expected, but team contributions are tracked via Git.

For team members:

  1. Branch from dev โ€” never commit directly to main
    git checkout dev
    git pull origin dev
    git checkout -b feature/your-feature-name
  2. Follow the commit convention from requirements/REPO_WORKFLOW.md:
    feat(canvas): implement drag-and-drop furniture placement
    fix(3d): resolve shadow rendering on wall geometry
    docs(eval): add summative study observation notes
    
  3. Open a PR to dev with a description that references the relevant task from the roadmap
  4. Get at least one review before merging
  5. Never merge broken code โ€” verify index.html opens without console errors first

๐Ÿ‘ฅ Team

Dineth Hettiarachchi
Dineth Hettiarachchi

Lead Developer
Architecture ยท 2D Engine ยท 3D Scene ยท Innovation Features
Member 2
Lakindu Pahesara

Design Lead
Personas ยท Storyboards ยท Lo-Fi / Hi-Fi Prototypes ยท Report
Member 3
Thanuji Kalanika

Evaluation Lead
Test Plans ยท User Studies ยท SUS Scoring ยท Consent Forms

๐Ÿ“œ License & Credits

License

This project is submitted as academic coursework for PUSL3122 at Plymouth University Sri Lanka. All original source code is available under the MIT License for reference purposes.

MIT License โ€” Copyright (c) 2026 Dineth Hettiarachchi and contributors

Third-Party Credits

Library Version License Source
Three.js r160 MIT threejs.org
OrbitControls.js r160 MIT three/examples
jsPDF 2.x MIT parallax/jsPDF

Key References

  • Nielsen, J. (1994). 10 Usability Heuristics for User Interface Design. NN/g.
  • Norman, D. (1988). The Design of Everyday Things. Basic Books.
  • Preece, J., Sharp, H. & Rogers, Y. (2019). Interaction Design. 5th ed. Wiley.
  • Brooke, J. (1996). SUS: A Quick and Dirty Usability Scale.
  • Dirksen, J. (2018). Learn Three.js. 3rd ed. Packt.
  • Angel, E. & Shreiner, D. (2014). Interactive Computer Graphics. 7th ed. Pearson.
  • MDN Web Docs โ€” Canvas API
  • Three.js Documentation โ€” threejs.org/docs

Made with โค๏ธ
PUSL3122

FurnishView โ€” Bringing furniture consultations to life, one canvas at a time.