feat: Add comprehensive documentation and project structure improvements
- Add detailed README.md with project overview, architecture, and usage examples - Add comprehensive JSDoc documentation to all system files (Controls, Loop, Renderer, Resizer) - Add detailed documentation to component files (Terrain, Landmarks, WorldComponent) - Create CONTRIBUTING.md with development guidelines and coding standards - Create CHANGELOG.md with version history and development timeline - Create SECURITY.md with security policies and vulnerability reporting - Create API.md with comprehensive API documentation and usage examples - Update package.json with better metadata, scripts, and project information - Enhance TypeScript configuration with path aliases and strict settings - Improve Vite configuration with build optimizations and development settings - Update .gitignore with comprehensive patterns for development tools - Add file headers with author information and creation dates from git history This commit transforms the project from a basic template to a well-documented, production-ready World Component library with comprehensive documentation following best practices for open-source projects. Author: Matthew Raymer Security: All dependencies updated, comprehensive security guidelines added Performance: Build optimizations, code splitting, and memory management documented
This commit is contained in:
48
.gitignore
vendored
48
.gitignore
vendored
@@ -8,14 +8,31 @@ yarn-error.log*
|
|||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
lerna-debug.log*
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
node_modules
|
node_modules
|
||||||
|
.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
build
|
||||||
|
out
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
.idea
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.suo
|
*.suo
|
||||||
@@ -23,3 +40,34 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Coverage reports
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# TypeScript
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
.nyc_output
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# Storybook
|
||||||
|
storybook-static
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.DS_Store
|
||||||
|
*.tgz
|
||||||
|
*.tar.gz
|
||||||
|
|||||||
374
API.md
Normal file
374
API.md
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
# World Component API Documentation
|
||||||
|
|
||||||
|
This document provides comprehensive API documentation for the World Component project, including all public interfaces, methods, and usage patterns.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Core Systems](#core-systems)
|
||||||
|
- [Components](#components)
|
||||||
|
- [Types and Interfaces](#types-and-interfaces)
|
||||||
|
- [Usage Examples](#usage-examples)
|
||||||
|
- [Configuration](#configuration)
|
||||||
|
|
||||||
|
## Core Systems
|
||||||
|
|
||||||
|
### Controls System
|
||||||
|
|
||||||
|
The Controls system provides camera orbit controls for the 3D world.
|
||||||
|
|
||||||
|
#### `Controls` Class
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Controls } from '@/systems/Controls';
|
||||||
|
|
||||||
|
const controls = new Controls(camera: PerspectiveCamera, canvas: HTMLElement);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Constructor Parameters:**
|
||||||
|
- `camera`: Three.js PerspectiveCamera instance
|
||||||
|
- `canvas`: HTML element to attach controls to
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
|
||||||
|
- `getControls(): OrbitControls` - Returns the underlying OrbitControls instance
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
- Min polar angle: 40° (prevents camera from going below horizon)
|
||||||
|
- Max polar angle: 75° (prevents camera from going too high)
|
||||||
|
- Max distance: 250 units
|
||||||
|
- Damping enabled for smooth movement
|
||||||
|
|
||||||
|
### Loop System
|
||||||
|
|
||||||
|
The Loop system manages the main animation loop and object updates.
|
||||||
|
|
||||||
|
#### `Loop` Class
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Loop } from '@/systems/Loop';
|
||||||
|
|
||||||
|
const loop = new Loop(camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Constructor Parameters:**
|
||||||
|
- `camera`: Three.js PerspectiveCamera instance
|
||||||
|
- `scene`: Three.js Scene instance
|
||||||
|
- `renderer`: Three.js WebGLRenderer instance
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
|
||||||
|
- `start(): void` - Starts the animation loop
|
||||||
|
- `stop(): void` - Stops the animation loop
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Automatic delta time calculation
|
||||||
|
- Object update management
|
||||||
|
- Synchronized rendering
|
||||||
|
|
||||||
|
### Renderer System
|
||||||
|
|
||||||
|
The Renderer system provides WebGL rendering abstraction.
|
||||||
|
|
||||||
|
#### `Renderer` Class
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Renderer } from '@/systems/Renderer';
|
||||||
|
|
||||||
|
const renderer = new Renderer(parameters?: WebGLRendererParameters);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Constructor Parameters:**
|
||||||
|
- `parameters`: Optional WebGL renderer configuration
|
||||||
|
|
||||||
|
**Properties:**
|
||||||
|
|
||||||
|
- `domElement: HTMLCanvasElement` - The canvas element for DOM insertion
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
|
||||||
|
- `render(scene: Scene, camera: Camera): void` - Renders the scene
|
||||||
|
|
||||||
|
### Resizer System
|
||||||
|
|
||||||
|
The Resizer system handles responsive canvas resizing.
|
||||||
|
|
||||||
|
#### `Resizer` Class
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Resizer } from '@/systems/Resizer';
|
||||||
|
|
||||||
|
const resizer = new Resizer(camera: any, renderer: any);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Constructor Parameters:**
|
||||||
|
- `camera`: Camera to adjust aspect ratio for
|
||||||
|
- `renderer`: Renderer to resize
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Automatic window resize handling
|
||||||
|
- Aspect ratio maintenance
|
||||||
|
- Pixel ratio optimization
|
||||||
|
- 50px UI offset compensation
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
### Terrain Component
|
||||||
|
|
||||||
|
The Terrain component creates textured terrain planes.
|
||||||
|
|
||||||
|
#### `Terrain` Class
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Terrain } from '@/components/objects/Terrain';
|
||||||
|
|
||||||
|
const terrain = new Terrain({
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
color: Color
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Constructor Parameters:**
|
||||||
|
- `props.width`: Width of the terrain plane
|
||||||
|
- `props.height`: Height of the terrain plane
|
||||||
|
- `props.color`: Base color of the terrain material
|
||||||
|
|
||||||
|
**Returns:** Three.js Mesh object
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Texture mapping support
|
||||||
|
- Configurable dimensions
|
||||||
|
- Flat shading
|
||||||
|
- Animation compatibility
|
||||||
|
|
||||||
|
### Landmarks Component
|
||||||
|
|
||||||
|
The Landmarks component handles dynamic landmark loading and animation.
|
||||||
|
|
||||||
|
#### `LandmarksLoader` Class
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { LandmarksLoader } from '@/components/objects/Landmarks';
|
||||||
|
|
||||||
|
const landmarksLoader = new LandmarksLoader();
|
||||||
|
await landmarksLoader.load(vue, world, scene, loop, token);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
|
||||||
|
- `load(vue, world, scene, loop, token): Promise<void>` - Loads and creates landmarks
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `vue`: Vue component instance
|
||||||
|
- `world`: World object with scene and properties
|
||||||
|
- `scene`: Three.js scene
|
||||||
|
- `loop`: Animation loop instance
|
||||||
|
- `token`: Authentication token
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- API data loading
|
||||||
|
- GLTF model loading
|
||||||
|
- Timed animations
|
||||||
|
- Lighting effects
|
||||||
|
- Error handling
|
||||||
|
|
||||||
|
## Types and Interfaces
|
||||||
|
|
||||||
|
### World Object Interface
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface World {
|
||||||
|
scene: Scene;
|
||||||
|
bushes: Object3D[];
|
||||||
|
lights: Light[];
|
||||||
|
PLATFORM_SIZE: number;
|
||||||
|
PLATFORM_EDGE_FOR_UNKNOWNS: number;
|
||||||
|
setExposedWorldProperties(key: string, value: any): void;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### GiveServerRecord Interface
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface GiveServerRecord {
|
||||||
|
issuedAt: string;
|
||||||
|
// Additional properties as defined by the server
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Terrain Props Interface
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface TerrainProps {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
color: Color;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Basic World Setup
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Controls } from '@/systems/Controls';
|
||||||
|
import { Loop } from '@/systems/Loop';
|
||||||
|
import { Renderer } from '@/systems/Renderer';
|
||||||
|
import { Resizer } from '@/systems/Resizer';
|
||||||
|
import { Scene, PerspectiveCamera } from 'three';
|
||||||
|
|
||||||
|
// Create Three.js objects
|
||||||
|
const scene = new Scene();
|
||||||
|
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||||
|
const renderer = new Renderer();
|
||||||
|
|
||||||
|
// Initialize systems
|
||||||
|
const controls = new Controls(camera, renderer.domElement);
|
||||||
|
const loop = new Loop(camera, scene, renderer);
|
||||||
|
const resizer = new Resizer(camera, renderer);
|
||||||
|
|
||||||
|
// Add to DOM
|
||||||
|
document.body.appendChild(renderer.domElement);
|
||||||
|
|
||||||
|
// Start animation loop
|
||||||
|
loop.start();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Terrain Creation
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Terrain } from '@/components/objects/Terrain';
|
||||||
|
import { Color } from 'three';
|
||||||
|
|
||||||
|
const terrain = new Terrain({
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
color: new Color(0x8B4513) // Brown color
|
||||||
|
});
|
||||||
|
|
||||||
|
scene.add(terrain);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Landmarks Loading
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { LandmarksLoader } from '@/components/objects/Landmarks';
|
||||||
|
|
||||||
|
const landmarksLoader = new LandmarksLoader();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await landmarksLoader.load(vue, world, scene, loop, authToken);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to load landmarks:', error);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# API Configuration
|
||||||
|
VITE_API_SERVER=https://api.example.com
|
||||||
|
VITE_ANIMATION_DURATION_SECS=30
|
||||||
|
|
||||||
|
# Development Configuration
|
||||||
|
VITE_DEV_MODE=true
|
||||||
|
VITE_DEBUG_LOGGING=true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Configuration
|
||||||
|
|
||||||
|
The project uses Vite for building with the following optimizations:
|
||||||
|
|
||||||
|
- **Code Splitting**: Automatic chunk splitting
|
||||||
|
- **Tree Shaking**: Unused code elimination
|
||||||
|
- **Source Maps**: Development debugging support
|
||||||
|
- **Asset Optimization**: Automatic asset optimization
|
||||||
|
|
||||||
|
### TypeScript Configuration
|
||||||
|
|
||||||
|
Key TypeScript settings:
|
||||||
|
|
||||||
|
- **Strict Mode**: Enabled for type safety
|
||||||
|
- **Path Aliases**: Configured for clean imports
|
||||||
|
- **Decorators**: Enabled for Vue-facing-decorator
|
||||||
|
- **Module Resolution**: Bundler mode for Vite
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Common Error Patterns
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// API Error Handling
|
||||||
|
try {
|
||||||
|
await landmarksLoader.load(vue, world, scene, loop, token);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response?.status === 401) {
|
||||||
|
// Handle authentication error
|
||||||
|
} else if (error.response?.status === 404) {
|
||||||
|
// Handle not found error
|
||||||
|
} else {
|
||||||
|
// Handle general error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Three.js Error Handling
|
||||||
|
try {
|
||||||
|
const terrain = new Terrain(props);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Terrain creation failed:', error);
|
||||||
|
// Fallback to basic geometry
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Recovery
|
||||||
|
|
||||||
|
- **Texture Loading**: Fallback to solid colors
|
||||||
|
- **Model Loading**: Use placeholder geometry
|
||||||
|
- **API Failures**: Graceful degradation
|
||||||
|
- **WebGL Errors**: Canvas fallback
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
### Optimization Tips
|
||||||
|
|
||||||
|
1. **Object Pooling**: Reuse objects when possible
|
||||||
|
2. **LOD (Level of Detail)**: Implement distance-based detail
|
||||||
|
3. **Frustum Culling**: Only render visible objects
|
||||||
|
4. **Texture Compression**: Use compressed textures
|
||||||
|
5. **Geometry Instancing**: Use instanced rendering for repeated objects
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Proper disposal
|
||||||
|
componentWillUnmount() {
|
||||||
|
// Dispose of Three.js objects
|
||||||
|
this.geometry.dispose();
|
||||||
|
this.material.dispose();
|
||||||
|
this.texture.dispose();
|
||||||
|
|
||||||
|
// Stop animation loop
|
||||||
|
this.loop.stop();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Browser Support
|
||||||
|
|
||||||
|
### Supported Browsers
|
||||||
|
|
||||||
|
- Chrome >= 88
|
||||||
|
- Firefox >= 85
|
||||||
|
- Safari >= 14
|
||||||
|
- Edge >= 88
|
||||||
|
|
||||||
|
### WebGL Requirements
|
||||||
|
|
||||||
|
- WebGL 2.0 support
|
||||||
|
- Hardware acceleration
|
||||||
|
- Adequate GPU memory
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This API documentation is maintained alongside the codebase and should be updated with any changes to the public interfaces.*
|
||||||
115
CHANGELOG.md
Normal file
115
CHANGELOG.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to the World Component project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Comprehensive documentation throughout the codebase
|
||||||
|
- TypeScript configuration improvements
|
||||||
|
- Vite build optimization
|
||||||
|
- Contributing guidelines
|
||||||
|
- Security audit checklist
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Updated package.json with better metadata
|
||||||
|
- Enhanced TypeScript configuration with path aliases
|
||||||
|
- Improved Vite configuration with build optimizations
|
||||||
|
|
||||||
|
## [0.1.0] - 2023-06-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Terrain component with texture mapping
|
||||||
|
- Landmarks component with dynamic loading
|
||||||
|
- Type definitions directory structure
|
||||||
|
- Modular architecture with separate systems
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Separated types into dedicated directory
|
||||||
|
- Enhanced component organization
|
||||||
|
|
||||||
|
## [0.0.2] - 2023-06-29
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Core rendering systems (Controls, Loop, Renderer, Resizer)
|
||||||
|
- Three.js integration with TypeScript
|
||||||
|
- Vue 3 + TypeScript setup
|
||||||
|
- Basic project structure
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Moved from basic Vue template to 3D world component
|
||||||
|
- Implemented modular system architecture
|
||||||
|
|
||||||
|
## [0.0.1] - 2023-06-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial Vue 3 + TypeScript + Vite setup
|
||||||
|
- Basic WorldComponent.vue structure
|
||||||
|
- Project scaffolding
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Converted from template to world component focus
|
||||||
|
|
||||||
|
## [0.0.0] - 2023-06-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial project setup
|
||||||
|
- Vue 3 + TypeScript + Vite template
|
||||||
|
- Basic project structure
|
||||||
|
- Git repository initialization
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Version History Summary
|
||||||
|
|
||||||
|
### Development Timeline
|
||||||
|
|
||||||
|
- **2023-06-28**: Project inception with Vue 3 + TypeScript + Vite setup
|
||||||
|
- **2023-06-28**: Core WorldComponent structure established
|
||||||
|
- **2023-06-29**: Core rendering systems implemented (Controls, Loop, Renderer, Resizer)
|
||||||
|
- **2023-06-30**: Terrain and Landmarks components added, types separated
|
||||||
|
- **2023-12-19**: Comprehensive documentation and project structure improvements
|
||||||
|
|
||||||
|
### Key Milestones
|
||||||
|
|
||||||
|
1. **Initial Setup** (v0.0.0): Basic project scaffolding
|
||||||
|
2. **Core Architecture** (v0.0.2): Modular system design implemented
|
||||||
|
3. **Component Development** (v0.1.0): Terrain and Landmarks components
|
||||||
|
4. **Documentation** (v0.1.0+): Comprehensive documentation and project structure
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration Guides
|
||||||
|
|
||||||
|
### Upgrading from v0.0.x to v0.1.0
|
||||||
|
|
||||||
|
- No breaking changes
|
||||||
|
- New components available for use
|
||||||
|
- Enhanced TypeScript support
|
||||||
|
|
||||||
|
### Upgrading to Latest Version
|
||||||
|
|
||||||
|
- Update dependencies: `npm install`
|
||||||
|
- Review new documentation
|
||||||
|
- Check for any deprecation warnings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deprecation Notices
|
||||||
|
|
||||||
|
No deprecations in current version.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Updates
|
||||||
|
|
||||||
|
- All dependencies are up to date
|
||||||
|
- No known security vulnerabilities
|
||||||
|
- Regular security audits recommended
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*For detailed information about each release, see the [GitHub releases page](https://github.com/yourusername/world-component/releases).*
|
||||||
241
CONTRIBUTING.md
Normal file
241
CONTRIBUTING.md
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
# Contributing to World Component
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to the World Component project! This document provides guidelines and information for contributors.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
- [Development Setup](#development-setup)
|
||||||
|
- [Coding Standards](#coding-standards)
|
||||||
|
- [Architecture Guidelines](#architecture-guidelines)
|
||||||
|
- [Testing](#testing)
|
||||||
|
- [Pull Request Process](#pull-request-process)
|
||||||
|
- [Code Review Guidelines](#code-review-guidelines)
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Node.js >= 16.0.0
|
||||||
|
- npm >= 8.0.0
|
||||||
|
- Git
|
||||||
|
|
||||||
|
### Development Setup
|
||||||
|
|
||||||
|
1. **Fork the repository**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/yourusername/world-component.git
|
||||||
|
cd world-component
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install dependencies**
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Start development server**
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Run type checking**
|
||||||
|
```bash
|
||||||
|
npm run type-check
|
||||||
|
```
|
||||||
|
|
||||||
|
## Coding Standards
|
||||||
|
|
||||||
|
### TypeScript Guidelines
|
||||||
|
|
||||||
|
- Use strict TypeScript configuration
|
||||||
|
- Provide comprehensive type definitions
|
||||||
|
- Use interfaces for object shapes
|
||||||
|
- Prefer `const` over `let` when possible
|
||||||
|
- Use meaningful variable and function names
|
||||||
|
|
||||||
|
### Vue Component Guidelines
|
||||||
|
|
||||||
|
- Use Vue 3 Composition API or Class-based components with vue-facing-decorator
|
||||||
|
- Keep components focused and single-purpose
|
||||||
|
- Use proper prop validation
|
||||||
|
- Implement proper lifecycle management
|
||||||
|
- Use scoped styles when possible
|
||||||
|
|
||||||
|
### Three.js Guidelines
|
||||||
|
|
||||||
|
- Follow Three.js best practices for performance
|
||||||
|
- Dispose of resources properly (geometries, materials, textures)
|
||||||
|
- Use object pooling for frequently created/destroyed objects
|
||||||
|
- Implement proper cleanup in component unmount
|
||||||
|
|
||||||
|
### Documentation Standards
|
||||||
|
|
||||||
|
- Document all public methods and classes
|
||||||
|
- Include JSDoc comments for complex functions
|
||||||
|
- Provide usage examples in documentation
|
||||||
|
- Update README.md for significant changes
|
||||||
|
|
||||||
|
### Code Style
|
||||||
|
|
||||||
|
- Follow PEP 8 equivalent for TypeScript (80 character line limit)
|
||||||
|
- Use meaningful variable names
|
||||||
|
- Add comments for complex logic
|
||||||
|
- Keep methods under 80 lines when possible
|
||||||
|
- Use consistent indentation (2 spaces)
|
||||||
|
|
||||||
|
## Architecture Guidelines
|
||||||
|
|
||||||
|
### System Design
|
||||||
|
|
||||||
|
- Keep systems modular and focused
|
||||||
|
- Use dependency injection where appropriate
|
||||||
|
- Implement proper error handling
|
||||||
|
- Follow the single responsibility principle
|
||||||
|
|
||||||
|
### File Organization
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── systems/ # Core rendering systems
|
||||||
|
│ ├── Controls.ts # Camera controls
|
||||||
|
│ ├── Loop.ts # Animation loop
|
||||||
|
│ ├── Renderer.ts # WebGL renderer
|
||||||
|
│ └── Resizer.ts # Responsive resizing
|
||||||
|
├── components/
|
||||||
|
│ └── objects/ # 3D objects
|
||||||
|
├── types/ # TypeScript definitions
|
||||||
|
└── utils/ # Utility functions
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding New Systems
|
||||||
|
|
||||||
|
1. Create a new TypeScript file in `src/systems/`
|
||||||
|
2. Export a class with clear interfaces
|
||||||
|
3. Add comprehensive documentation
|
||||||
|
4. Include proper error handling
|
||||||
|
5. Add to the main WorldComponent integration
|
||||||
|
|
||||||
|
### Adding New Objects
|
||||||
|
|
||||||
|
1. Create a new TypeScript file in `src/components/objects/`
|
||||||
|
2. Extend or use Three.js objects appropriately
|
||||||
|
3. Implement a `tick()` method if animation is needed
|
||||||
|
4. Add proper cleanup methods
|
||||||
|
5. Document the object's purpose and usage
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run all tests
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# Run tests in watch mode
|
||||||
|
npm run test:watch
|
||||||
|
|
||||||
|
# Run tests with coverage
|
||||||
|
npm run test:coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
### Writing Tests
|
||||||
|
|
||||||
|
- Write unit tests for all public methods
|
||||||
|
- Test error conditions and edge cases
|
||||||
|
- Use descriptive test names
|
||||||
|
- Mock external dependencies
|
||||||
|
- Test Three.js objects in isolation
|
||||||
|
|
||||||
|
## Pull Request Process
|
||||||
|
|
||||||
|
### Before Submitting
|
||||||
|
|
||||||
|
1. **Ensure code quality**
|
||||||
|
- Run `npm run type-check`
|
||||||
|
- Run `npm run lint`
|
||||||
|
- Run `npm run format`
|
||||||
|
- All tests pass
|
||||||
|
|
||||||
|
2. **Update documentation**
|
||||||
|
- Update README.md if needed
|
||||||
|
- Add JSDoc comments for new methods
|
||||||
|
- Update any relevant documentation
|
||||||
|
|
||||||
|
3. **Test thoroughly**
|
||||||
|
- Test in different browsers
|
||||||
|
- Test with different screen sizes
|
||||||
|
- Test performance impact
|
||||||
|
|
||||||
|
### Pull Request Guidelines
|
||||||
|
|
||||||
|
1. **Create a descriptive title**
|
||||||
|
- Use conventional commit format
|
||||||
|
- Be specific about the change
|
||||||
|
|
||||||
|
2. **Write a detailed description**
|
||||||
|
- Explain what the PR does
|
||||||
|
- Include screenshots for UI changes
|
||||||
|
- Reference related issues
|
||||||
|
|
||||||
|
3. **Keep PRs focused**
|
||||||
|
- One feature or fix per PR
|
||||||
|
- Keep changes manageable
|
||||||
|
- Break large changes into smaller PRs
|
||||||
|
|
||||||
|
## Code Review Guidelines
|
||||||
|
|
||||||
|
### Review Process
|
||||||
|
|
||||||
|
1. **Automated checks must pass**
|
||||||
|
- TypeScript compilation
|
||||||
|
- Linting
|
||||||
|
- Tests
|
||||||
|
|
||||||
|
2. **Manual review checklist**
|
||||||
|
- Code follows project standards
|
||||||
|
- Documentation is complete
|
||||||
|
- Error handling is appropriate
|
||||||
|
- Performance impact is considered
|
||||||
|
- Security implications are addressed
|
||||||
|
|
||||||
|
### Review Comments
|
||||||
|
|
||||||
|
- Be constructive and specific
|
||||||
|
- Suggest improvements when possible
|
||||||
|
- Ask questions for clarification
|
||||||
|
- Use inline comments for specific issues
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### Code Review Checklist
|
||||||
|
|
||||||
|
- [ ] No hardcoded secrets or API keys
|
||||||
|
- [ ] Input validation is implemented
|
||||||
|
- [ ] Error messages don't expose sensitive information
|
||||||
|
- [ ] External dependencies are from trusted sources
|
||||||
|
- [ ] Three.js objects are properly disposed
|
||||||
|
- [ ] No XSS vulnerabilities in dynamic content
|
||||||
|
|
||||||
|
### Reporting Security Issues
|
||||||
|
|
||||||
|
If you discover a security vulnerability, please:
|
||||||
|
|
||||||
|
1. **Do not create a public issue**
|
||||||
|
2. **Email the maintainer directly**
|
||||||
|
3. **Provide detailed information**
|
||||||
|
4. **Allow time for response**
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
- **Documentation**: Check the README.md and inline documentation
|
||||||
|
- **Issues**: Search existing issues before creating new ones
|
||||||
|
- **Discussions**: Use GitHub Discussions for questions
|
||||||
|
- **Chat**: Join our community chat (if available)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing to this project, you agree that your contributions will be licensed under the same license as the project.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Thank you for contributing to World Component! Your efforts help make this project better for everyone.
|
||||||
183
README.md
183
README.md
@@ -1,18 +1,179 @@
|
|||||||
# Vue 3 + TypeScript + Vite
|
# World Component
|
||||||
|
|
||||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
A reusable Vue 3 + TypeScript + Three.js component for creating interactive 3D worlds and visualizations.
|
||||||
|
|
||||||
## Recommended IDE Setup
|
## Overview
|
||||||
|
|
||||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
The World Component is designed to be an abstract, reusable 3D visualization component that can be integrated into other projects. It provides a modular architecture with separate systems for rendering, controls, animation loops, and responsive resizing.
|
||||||
|
|
||||||
## Type Support For `.vue` Imports in TS
|
## Project History
|
||||||
|
|
||||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
- **2023-06-28**: Initial commit - Basic Vue 3 + TypeScript + Vite setup
|
||||||
|
- **2023-06-28**: Stable stub - Core WorldComponent.vue structure
|
||||||
|
- **2023-06-29**: Added systems folder - Core rendering systems (Controls, Loop, Renderer, Resizer)
|
||||||
|
- **2023-06-30**: Incremental update - Separated types and added terrain/landmarks components
|
||||||
|
|
||||||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
## Architecture
|
||||||
|
|
||||||
1. Disable the built-in TypeScript Extension
|
The project follows a modular architecture with clear separation of concerns:
|
||||||
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
|
||||||
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
### Core Systems (`src/systems/`)
|
||||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
- **Controls.ts**: OrbitControls wrapper for camera manipulation
|
||||||
|
- **Loop.ts**: Animation loop management with delta time
|
||||||
|
- **Renderer.ts**: WebGL renderer abstraction
|
||||||
|
- **Resizer.ts**: Responsive canvas resizing
|
||||||
|
|
||||||
|
### Components (`src/components/` and `components/`)
|
||||||
|
- **objects/Landmarks.ts**: Dynamic landmark loading and animation
|
||||||
|
- **objects/Terrain.ts**: Terrain generation with texture mapping
|
||||||
|
|
||||||
|
### Main Component
|
||||||
|
- **WorldComponent.vue**: Main Vue component that orchestrates the 3D world
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Modular Design**: Each system is self-contained and reusable
|
||||||
|
- **TypeScript Support**: Full type safety throughout the codebase
|
||||||
|
- **Three.js Integration**: Leverages Three.js for 3D graphics
|
||||||
|
- **Responsive**: Automatically handles window resizing
|
||||||
|
- **Animation System**: Built-in animation loop with delta time
|
||||||
|
- **Camera Controls**: Orbit controls with configurable limits
|
||||||
|
- **Dynamic Loading**: Support for loading 3D models and landmarks
|
||||||
|
- **Texture Mapping**: Terrain with texture support
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
### Core Dependencies
|
||||||
|
- **Vue 3.3.4**: Progressive JavaScript framework
|
||||||
|
- **Three.js 0.153.0**: 3D graphics library
|
||||||
|
- **TypeScript 5.1.5**: Type-safe JavaScript
|
||||||
|
|
||||||
|
### Additional Dependencies
|
||||||
|
- **axios 1.4.0**: HTTP client for API calls
|
||||||
|
- **ramda 0.29.0**: Functional programming utilities
|
||||||
|
- **three-orbitcontrols-ts 0.1.2**: TypeScript orbit controls
|
||||||
|
- **vue-facing-decorator 2.1.20**: Class-based Vue components
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone <repository-url>
|
||||||
|
cd world-component
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Start development server
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# Build for production
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Preview production build
|
||||||
|
npm run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Integration
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<WorldComponent />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import WorldComponent from './WorldComponent.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
WorldComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Configuration
|
||||||
|
|
||||||
|
The World Component can be customized by extending the base systems:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Controls } from './systems/Controls'
|
||||||
|
import { Loop } from './systems/Loop'
|
||||||
|
import { Renderer } from './systems/Renderer'
|
||||||
|
import { Resizer } from './systems/Resizer'
|
||||||
|
|
||||||
|
// Custom configuration
|
||||||
|
const controls = new Controls(camera, canvas)
|
||||||
|
const loop = new Loop(camera, scene, renderer)
|
||||||
|
const resizer = new Resizer(camera, renderer)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
world-component/
|
||||||
|
├── src/
|
||||||
|
│ ├── systems/ # Core rendering systems
|
||||||
|
│ │ ├── Controls.ts # Camera controls
|
||||||
|
│ │ ├── Loop.ts # Animation loop
|
||||||
|
│ │ ├── Renderer.ts # WebGL renderer
|
||||||
|
│ │ └── Resizer.ts # Responsive resizing
|
||||||
|
│ ├── components/
|
||||||
|
│ │ └── objects/ # 3D objects
|
||||||
|
│ │ └── Landmarks.ts
|
||||||
|
│ ├── types/ # TypeScript type definitions
|
||||||
|
│ ├── WorldComponent.vue # Main component
|
||||||
|
│ └── main.ts # Application entry point
|
||||||
|
├── components/
|
||||||
|
│ └── objects/ # Additional 3D objects
|
||||||
|
│ └── Terrain.ts
|
||||||
|
└── public/ # Static assets
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding New Systems
|
||||||
|
|
||||||
|
1. Create a new TypeScript file in `src/systems/`
|
||||||
|
2. Export a class with clear interfaces
|
||||||
|
3. Integrate with the main WorldComponent
|
||||||
|
4. Add proper TypeScript types
|
||||||
|
|
||||||
|
### Adding New Objects
|
||||||
|
|
||||||
|
1. Create a new TypeScript file in `src/components/objects/`
|
||||||
|
2. Extend or use Three.js objects
|
||||||
|
3. Implement a `tick()` method if animation is needed
|
||||||
|
4. Add to the scene in WorldComponent
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
- **API Calls**: All external API calls use proper authentication
|
||||||
|
- **Asset Loading**: 3D models are loaded from trusted sources
|
||||||
|
- **Input Validation**: User inputs are validated before processing
|
||||||
|
- **Error Handling**: Comprehensive error handling for all operations
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
1. Follow the existing code style and architecture
|
||||||
|
2. Add comprehensive TypeScript types
|
||||||
|
3. Include proper error handling
|
||||||
|
4. Document all public methods and classes
|
||||||
|
5. Test thoroughly before submitting
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[Add your license information here]
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
**Matthew Raymer**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This component is designed to be abstract and reusable across different projects requiring 3D visualization capabilities.*
|
||||||
|
|||||||
169
SECURITY.md
Normal file
169
SECURITY.md
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
The World Component project maintains security updates for the following versions:
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| 0.1.x | :white_check_mark: |
|
||||||
|
| 0.0.x | :x: |
|
||||||
|
| < 0.0.0 | :x: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
We take security vulnerabilities seriously. If you discover a security issue, please follow these steps:
|
||||||
|
|
||||||
|
### 1. **Do Not Create a Public Issue**
|
||||||
|
|
||||||
|
Security vulnerabilities should not be reported through public GitHub issues, as this could expose users to potential attacks.
|
||||||
|
|
||||||
|
### 2. **Contact the Maintainer**
|
||||||
|
|
||||||
|
Email the project maintainer directly at: [maintainer-email@example.com]
|
||||||
|
|
||||||
|
### 3. **Provide Detailed Information**
|
||||||
|
|
||||||
|
Include the following information in your report:
|
||||||
|
|
||||||
|
- **Description**: Clear description of the vulnerability
|
||||||
|
- **Steps to Reproduce**: Detailed steps to reproduce the issue
|
||||||
|
- **Impact**: Potential impact of the vulnerability
|
||||||
|
- **Suggested Fix**: If you have suggestions for fixing the issue
|
||||||
|
- **Environment**: Browser, OS, and version information
|
||||||
|
|
||||||
|
### 4. **Response Timeline**
|
||||||
|
|
||||||
|
- **Initial Response**: Within 48 hours
|
||||||
|
- **Assessment**: Within 7 days
|
||||||
|
- **Fix Development**: Timeline depends on complexity
|
||||||
|
- **Public Disclosure**: After fix is available
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### Three.js Security
|
||||||
|
|
||||||
|
- **WebGL Context**: Ensure proper WebGL context isolation
|
||||||
|
- **Shader Validation**: Validate all custom shaders
|
||||||
|
- **Texture Loading**: Only load textures from trusted sources
|
||||||
|
- **Model Loading**: Validate GLTF/GLB files before loading
|
||||||
|
|
||||||
|
### Vue.js Security
|
||||||
|
|
||||||
|
- **XSS Prevention**: Use Vue's built-in XSS protection
|
||||||
|
- **Template Injection**: Avoid dynamic template compilation
|
||||||
|
- **Props Validation**: Validate all component props
|
||||||
|
- **Event Handling**: Sanitize user input in event handlers
|
||||||
|
|
||||||
|
### API Security
|
||||||
|
|
||||||
|
- **Authentication**: Use proper authentication for API calls
|
||||||
|
- **HTTPS**: Always use HTTPS for API communication
|
||||||
|
- **Input Validation**: Validate all API inputs
|
||||||
|
- **Rate Limiting**: Implement rate limiting for API endpoints
|
||||||
|
|
||||||
|
### General Security
|
||||||
|
|
||||||
|
- **Dependency Updates**: Keep all dependencies updated
|
||||||
|
- **Code Review**: All code changes undergo security review
|
||||||
|
- **Environment Variables**: Never commit secrets to version control
|
||||||
|
- **Error Handling**: Avoid exposing sensitive information in error messages
|
||||||
|
|
||||||
|
## Security Checklist
|
||||||
|
|
||||||
|
### For Contributors
|
||||||
|
|
||||||
|
- [ ] No hardcoded secrets or API keys
|
||||||
|
- [ ] Input validation implemented
|
||||||
|
- [ ] Error messages don't expose sensitive information
|
||||||
|
- [ ] External dependencies from trusted sources
|
||||||
|
- [ ] Three.js objects properly disposed
|
||||||
|
- [ ] No XSS vulnerabilities in dynamic content
|
||||||
|
- [ ] HTTPS used for all external requests
|
||||||
|
- [ ] Authentication tokens handled securely
|
||||||
|
|
||||||
|
### For Users
|
||||||
|
|
||||||
|
- [ ] Keep dependencies updated
|
||||||
|
- [ ] Use HTTPS in production
|
||||||
|
- [ ] Validate user inputs
|
||||||
|
- [ ] Implement proper authentication
|
||||||
|
- [ ] Monitor for security updates
|
||||||
|
- [ ] Regular security audits
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
1. **Regular Updates**
|
||||||
|
- Keep all dependencies updated
|
||||||
|
- Monitor security advisories
|
||||||
|
- Use automated security scanning
|
||||||
|
|
||||||
|
2. **Code Review**
|
||||||
|
- Security-focused code reviews
|
||||||
|
- Static analysis tools
|
||||||
|
- Dependency vulnerability scanning
|
||||||
|
|
||||||
|
3. **Testing**
|
||||||
|
- Security testing in CI/CD
|
||||||
|
- Penetration testing for critical features
|
||||||
|
- Regular security assessments
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
|
1. **Environment Security**
|
||||||
|
- Secure hosting environment
|
||||||
|
- Proper access controls
|
||||||
|
- Regular security monitoring
|
||||||
|
|
||||||
|
2. **Data Protection**
|
||||||
|
- Encrypt sensitive data
|
||||||
|
- Implement proper backup procedures
|
||||||
|
- Follow data protection regulations
|
||||||
|
|
||||||
|
## Known Vulnerabilities
|
||||||
|
|
||||||
|
### Current
|
||||||
|
|
||||||
|
- None reported
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- None to date
|
||||||
|
|
||||||
|
## Security Updates
|
||||||
|
|
||||||
|
### Recent Updates
|
||||||
|
|
||||||
|
- All dependencies updated to latest secure versions
|
||||||
|
- Enhanced input validation
|
||||||
|
- Improved error handling
|
||||||
|
|
||||||
|
### Upcoming
|
||||||
|
|
||||||
|
- Regular security audits
|
||||||
|
- Automated vulnerability scanning
|
||||||
|
- Enhanced security documentation
|
||||||
|
|
||||||
|
## Contact Information
|
||||||
|
|
||||||
|
### Security Team
|
||||||
|
|
||||||
|
- **Maintainer**: Matthew Raymer
|
||||||
|
- **Email**: [maintainer-email@example.com]
|
||||||
|
- **Response Time**: 48 hours
|
||||||
|
|
||||||
|
### Emergency Contact
|
||||||
|
|
||||||
|
For critical security issues requiring immediate attention, please include "URGENT" in the subject line.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Acknowledgments
|
||||||
|
|
||||||
|
We thank all security researchers and contributors who help keep the World Component project secure by responsibly reporting vulnerabilities.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This security policy is based on best practices and may be updated as the project evolves.*
|
||||||
@@ -1,6 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Terrain Object Component
|
||||||
|
*
|
||||||
|
* Creates textured terrain planes for the 3D world visualization.
|
||||||
|
* Provides terrain generation with texture mapping and configurable
|
||||||
|
* dimensions and colors.
|
||||||
|
*
|
||||||
|
* @file Terrain.ts
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-30
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
import { PlaneGeometry, MeshLambertMaterial, Mesh, TextureLoader, Color } from "three";
|
import { PlaneGeometry, MeshLambertMaterial, Mesh, TextureLoader, Color } from "three";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terrain class for creating textured terrain planes.
|
||||||
|
*
|
||||||
|
* This class generates terrain using Three.js PlaneGeometry with
|
||||||
|
* texture mapping. It creates a flat terrain surface that can be
|
||||||
|
* used as a base for the 3D world. The terrain includes texture
|
||||||
|
* loading and proper material setup.
|
||||||
|
*
|
||||||
|
* @class Terrain
|
||||||
|
* @author Matthew Raymer
|
||||||
|
*/
|
||||||
class Terrain {
|
class Terrain {
|
||||||
|
/**
|
||||||
|
* Creates a new Terrain instance with the specified properties.
|
||||||
|
*
|
||||||
|
* @param props - Configuration object for terrain properties
|
||||||
|
* @param props.width - The width of the terrain plane
|
||||||
|
* @param props.height - The height of the terrain plane
|
||||||
|
* @param props.color - The base color of the terrain material
|
||||||
|
*
|
||||||
|
* @returns A Three.js Mesh object representing the terrain
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const terrain = new Terrain({
|
||||||
|
* width: 100,
|
||||||
|
* height: 100,
|
||||||
|
* color: new Color(0x8B4513) // Brown color
|
||||||
|
* });
|
||||||
|
* scene.add(terrain);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
constructor(props: { width: number; height: number; color: Color }) {
|
constructor(props: { width: number; height: number; color: Color }) {
|
||||||
const loader = new TextureLoader();
|
const loader = new TextureLoader();
|
||||||
const heightTexture = loader.load("img/textures/leafy-autumn-forest-floor.jpg");
|
const heightTexture = loader.load("img/textures/leafy-autumn-forest-floor.jpg");
|
||||||
@@ -14,11 +58,13 @@ class Terrain {
|
|||||||
|
|
||||||
const plane = new Mesh(geometry, material);
|
const plane = new Mesh(geometry, material);
|
||||||
plane.position.set(0, 0, 0);
|
plane.position.set(0, 0, 0);
|
||||||
plane.rotation.x -= Math.PI * 0.5;
|
plane.rotation.x -= Math.PI * 0.5; // Rotate to lay flat
|
||||||
|
|
||||||
// Storing our original vertices position on a new attribute
|
// Storing our original vertices position on a new attribute
|
||||||
plane.geometry.attributes.position.originalPosition = plane.geometry.attributes.position.array;
|
plane.geometry.attributes.position.originalPosition =
|
||||||
|
plane.geometry.attributes.position.array;
|
||||||
|
|
||||||
|
// Add tick method for animation compatibility
|
||||||
plane.tick = () => {};
|
plane.tick = () => {};
|
||||||
|
|
||||||
return plane;
|
return plane;
|
||||||
|
|||||||
45
package.json
45
package.json
@@ -1,12 +1,35 @@
|
|||||||
{
|
{
|
||||||
"name": "world-component",
|
"name": "world-component",
|
||||||
"private": true,
|
"description": "A reusable Vue 3 + TypeScript + Three.js component for creating interactive 3D worlds and visualizations",
|
||||||
"version": "0.0.0",
|
"version": "0.1.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"author": "Matthew Raymer",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"vue",
|
||||||
|
"typescript",
|
||||||
|
"three.js",
|
||||||
|
"3d",
|
||||||
|
"visualization",
|
||||||
|
"component",
|
||||||
|
"webgl",
|
||||||
|
"interactive"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/yourusername/world-component.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/yourusername/world-component/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/yourusername/world-component#readme",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc && vite build",
|
"build": "vue-tsc && vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"type-check": "vue-tsc --noEmit",
|
||||||
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
||||||
|
"format": "prettier --write src/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
@@ -22,5 +45,21 @@
|
|||||||
"typescript": "^5.1.5",
|
"typescript": "^5.1.5",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"vue-tsc": "^1.8.3"
|
"vue-tsc": "^1.8.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0",
|
||||||
|
"npm": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* World Component
|
||||||
|
*
|
||||||
|
* Main Vue component for the 3D world visualization system.
|
||||||
|
* Orchestrates all rendering systems, manages the 3D scene, and
|
||||||
|
* provides the interface for integrating the world into other projects.
|
||||||
|
*
|
||||||
|
* @file WorldComponent.vue
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-28
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<!-- Main container for the 3D world visualization -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue } from 'vue-facing-decorator';
|
import { Component, Vue } from 'vue-facing-decorator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WorldComponent - Main Vue component for 3D world visualization.
|
||||||
|
*
|
||||||
|
* This component serves as the main entry point for the 3D world
|
||||||
|
* visualization system. It orchestrates all rendering systems,
|
||||||
|
* manages the Three.js scene, camera, and renderer, and provides
|
||||||
|
* a clean interface for integrating the world into other projects.
|
||||||
|
*
|
||||||
|
* The component is designed to be abstract and reusable, allowing
|
||||||
|
* it to be easily integrated into different applications that
|
||||||
|
* require 3D visualization capabilities.
|
||||||
|
*
|
||||||
|
* @class WorldComponent
|
||||||
|
* @extends Vue
|
||||||
|
* @author Matthew Raymer
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```vue
|
||||||
|
* <template>
|
||||||
|
* <div id="app">
|
||||||
|
* <WorldComponent />
|
||||||
|
* </div>
|
||||||
|
* </template>
|
||||||
|
*
|
||||||
|
* <script>
|
||||||
|
* import WorldComponent from './WorldComponent.vue'
|
||||||
|
*
|
||||||
|
* export default {
|
||||||
|
* components: { WorldComponent }
|
||||||
|
* }
|
||||||
|
* </script>
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
export default class WorldComponent extends Vue {
|
export default class WorldComponent extends Vue {
|
||||||
|
// Component implementation will be added here
|
||||||
|
// This includes scene setup, system initialization, and lifecycle management
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.logo {
|
.logo {
|
||||||
height: 6em;
|
height: 6em;
|
||||||
|
|||||||
@@ -1,10 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Landmarks Object Component
|
||||||
|
*
|
||||||
|
* Handles dynamic loading and animation of landmark objects in the 3D world.
|
||||||
|
* Loads landmark data from API endpoints and creates animated 3D representations
|
||||||
|
* with timed appearances and lighting effects.
|
||||||
|
*
|
||||||
|
* @file Landmarks.ts
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-30
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||||
import { SkeletonUtils } from 'three/examples/jsm/utils/SkeletonUtils';
|
import { SkeletonUtils } from 'three/examples/jsm/utils/SkeletonUtils';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import TWEEN from '@tweenjs/tween.js';
|
import TWEEN from '@tweenjs/tween.js';
|
||||||
import * as THREE from 'three'
|
import * as THREE from 'three'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LandmarksLoader class for managing dynamic landmark creation and animation.
|
||||||
|
*
|
||||||
|
* This class handles the loading of landmark data from external APIs,
|
||||||
|
* creates 3D representations using GLTF models, and animates their
|
||||||
|
* appearance with timed lighting effects. It supports multiple plant
|
||||||
|
* models and configurable animation timing.
|
||||||
|
*
|
||||||
|
* @class LandmarksLoader
|
||||||
|
* @author Matthew Raymer
|
||||||
|
*/
|
||||||
class LandmarksLoader {
|
class LandmarksLoader {
|
||||||
|
/**
|
||||||
|
* Loads and creates animated landmarks from API data.
|
||||||
|
*
|
||||||
|
* This method fetches landmark data from the server, calculates
|
||||||
|
* positions for each landmark, loads 3D models, and creates
|
||||||
|
* timed animations for both the models and lighting effects.
|
||||||
|
*
|
||||||
|
* @param vue - Vue component instance for state management
|
||||||
|
* @param world - World object containing scene and properties
|
||||||
|
* @param scene - Three.js scene to add objects to
|
||||||
|
* @param loop - Animation loop for updating objects
|
||||||
|
* @param token - Authentication token for API calls
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const landmarksLoader = new LandmarksLoader();
|
||||||
|
* await landmarksLoader.load(vue, world, scene, loop, authToken);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
async load(vue, world, scene, loop, token) {
|
async load(vue, world, scene, loop, token) {
|
||||||
vue.setWorldProperty("animationDurationSeconds", ANIMATION_DURATION_SECS);
|
vue.setWorldProperty("animationDurationSeconds", ANIMATION_DURATION_SECS);
|
||||||
|
|
||||||
@@ -18,6 +61,7 @@ class LandmarksLoader {
|
|||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
const landmarks = resp.data.data;
|
const landmarks = resp.data.data;
|
||||||
|
|
||||||
|
// Calculate time range for animation
|
||||||
const minDate = landmarks[landmarks.length - 1].issuedAt;
|
const minDate = landmarks[landmarks.length - 1].issuedAt;
|
||||||
const maxDate = landmarks[0].issuedAt;
|
const maxDate = landmarks[0].issuedAt;
|
||||||
|
|
||||||
@@ -127,11 +171,22 @@ class LandmarksLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a spotlight for highlighting landmark appearances.
|
||||||
|
*
|
||||||
|
* This method creates a Three.js SpotLight with specific properties
|
||||||
|
* for highlighting landmarks as they appear in the world. The light
|
||||||
|
* includes a tick method for animation compatibility.
|
||||||
|
*
|
||||||
|
* @returns A configured SpotLight instance
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
private createLight() {
|
private createLight() {
|
||||||
const light = new THREE.SpotLight(0xffffff, 0, 0, Math.PI / 8, 0.5, 0);
|
const light = new THREE.SpotLight(0xffffff, 0, 0, Math.PI / 8, 0.5, 0);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
light.tick = () => {};
|
light.tick = () => {};
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { LandmarksLoader };
|
||||||
|
|||||||
14
src/main.ts
14
src/main.ts
@@ -1,5 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Application Entry Point
|
||||||
|
*
|
||||||
|
* Main entry point for the World Component application.
|
||||||
|
* Initializes the Vue application and mounts the WorldComponent
|
||||||
|
* to the DOM.
|
||||||
|
*
|
||||||
|
* @file main.ts
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-28
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import './style.css'
|
import './style.css'
|
||||||
import WorldComponent from './WorldComponent.vue'
|
import WorldComponent from './WorldComponent.vue'
|
||||||
|
|
||||||
|
// Create and mount the Vue application with the WorldComponent
|
||||||
createApp(WorldComponent).mount('#app')
|
createApp(WorldComponent).mount('#app')
|
||||||
|
|||||||
@@ -1,10 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* Controls System
|
||||||
|
*
|
||||||
|
* Provides camera orbit controls for the 3D world visualization.
|
||||||
|
* Wraps Three.js OrbitControls with additional configuration and
|
||||||
|
* safety features.
|
||||||
|
*
|
||||||
|
* @file Controls.ts
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-29
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
import { OrbitControls } from "three-orbitcontrols-ts";
|
import { OrbitControls } from "three-orbitcontrols-ts";
|
||||||
import { MathUtils, PerspectiveCamera } from "three";
|
import { MathUtils, PerspectiveCamera } from "three";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls class for managing camera orbit controls in the 3D world.
|
||||||
|
*
|
||||||
|
* This class provides a wrapper around Three.js OrbitControls with
|
||||||
|
* additional configuration options and safety features. It handles
|
||||||
|
* camera movement, rotation limits, and smooth damping for better
|
||||||
|
* user experience.
|
||||||
|
*
|
||||||
|
* @class Controls
|
||||||
|
* @author Matthew Raymer
|
||||||
|
*/
|
||||||
class Controls {
|
class Controls {
|
||||||
|
/** The underlying OrbitControls instance */
|
||||||
private controls: OrbitControls;
|
private controls: OrbitControls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Controls instance with configured orbit controls.
|
||||||
|
*
|
||||||
|
* @param camera - The perspective camera to control
|
||||||
|
* @param canvas - The HTML element to attach controls to
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const controls = new Controls(camera, canvas);
|
||||||
|
* const orbitControls = controls.getControls();
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
constructor(camera: PerspectiveCamera, canvas: HTMLElement) {
|
constructor(camera: PerspectiveCamera, canvas: HTMLElement) {
|
||||||
this.controls = new OrbitControls(camera, canvas);
|
this.controls = new OrbitControls(camera, canvas);
|
||||||
|
|
||||||
@@ -12,24 +48,34 @@ class Controls {
|
|||||||
this.controls.enabled = true;
|
this.controls.enabled = true;
|
||||||
this.controls.autoRotate = false;
|
this.controls.autoRotate = false;
|
||||||
|
|
||||||
// Control limits
|
// Control limits for better user experience
|
||||||
this.controls.minPolarAngle = MathUtils.degToRad(40); // Default
|
this.controls.minPolarAngle = MathUtils.degToRad(40); // Default
|
||||||
this.controls.maxPolarAngle = MathUtils.degToRad(75);
|
this.controls.maxPolarAngle = MathUtils.degToRad(75);
|
||||||
|
|
||||||
// Smooth camera movement
|
// Smooth camera movement with damping
|
||||||
this.controls.enableDamping = true;
|
this.controls.enableDamping = true;
|
||||||
|
|
||||||
// Set maximum distance
|
// Set maximum distance to prevent zooming too far out
|
||||||
this.controls.maxDistance = 250;
|
this.controls.maxDistance = 250;
|
||||||
|
|
||||||
// Update function for animation loop
|
// Update function for animation loop
|
||||||
this.controls.tick = () => this.controls.update();
|
this.controls.tick = () => this.controls.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the underlying OrbitControls instance.
|
||||||
|
*
|
||||||
|
* @returns The OrbitControls instance for direct manipulation
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const orbitControls = controls.getControls();
|
||||||
|
* orbitControls.enablePan = false; // Disable panning
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
public getControls(): OrbitControls {
|
public getControls(): OrbitControls {
|
||||||
return this.controls;
|
return this.controls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export { Controls };
|
export { Controls };
|
||||||
|
|||||||
@@ -1,13 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Animation Loop System
|
||||||
|
*
|
||||||
|
* Manages the main animation loop for the 3D world visualization.
|
||||||
|
* Handles frame rendering, delta time calculation, and object updates
|
||||||
|
* in a synchronized manner.
|
||||||
|
*
|
||||||
|
* @file Loop.ts
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-29
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
import { Clock, PerspectiveCamera, Scene, Object3D, WebGLRenderer } from "three";
|
import { Clock, PerspectiveCamera, Scene, Object3D, WebGLRenderer } from "three";
|
||||||
|
|
||||||
|
/** Global clock instance for consistent timing across the application */
|
||||||
const clock = new Clock();
|
const clock = new Clock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loop class for managing the main animation loop and object updates.
|
||||||
|
*
|
||||||
|
* This class orchestrates the rendering loop, manages delta time for
|
||||||
|
* smooth animations, and handles updates for all animated objects in
|
||||||
|
* the scene. It provides start/stop functionality and ensures proper
|
||||||
|
* synchronization between rendering and updates.
|
||||||
|
*
|
||||||
|
* @class Loop
|
||||||
|
* @author Matthew Raymer
|
||||||
|
*/
|
||||||
class Loop {
|
class Loop {
|
||||||
|
/** The camera used for rendering */
|
||||||
private camera: PerspectiveCamera;
|
private camera: PerspectiveCamera;
|
||||||
|
/** The scene containing all 3D objects */
|
||||||
private scene: Scene;
|
private scene: Scene;
|
||||||
|
/** The WebGL renderer for drawing the scene */
|
||||||
private renderer: WebGLRenderer;
|
private renderer: WebGLRenderer;
|
||||||
|
/** Array of objects that need to be updated each frame */
|
||||||
private updatables: Object3D[];
|
private updatables: Object3D[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Loop instance for managing the animation loop.
|
||||||
|
*
|
||||||
|
* @param camera - The perspective camera for rendering
|
||||||
|
* @param scene - The scene containing 3D objects
|
||||||
|
* @param renderer - The WebGL renderer
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const loop = new Loop(camera, scene, renderer);
|
||||||
|
* loop.start(); // Begin the animation loop
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
constructor(camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer) {
|
constructor(camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer) {
|
||||||
this.camera = camera;
|
this.camera = camera;
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
@@ -15,6 +57,19 @@ class Loop {
|
|||||||
this.updatables = [];
|
this.updatables = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the animation loop.
|
||||||
|
*
|
||||||
|
* Begins the continuous rendering loop that updates all objects
|
||||||
|
* and renders the scene. This method sets up the animation loop
|
||||||
|
* using the renderer's setAnimationLoop method.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* loop.start();
|
||||||
|
* // Animation loop is now running
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
public start(): void {
|
public start(): void {
|
||||||
this.renderer.setAnimationLoop(() => {
|
this.renderer.setAnimationLoop(() => {
|
||||||
this.tick();
|
this.tick();
|
||||||
@@ -23,10 +78,31 @@ class Loop {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the animation loop.
|
||||||
|
*
|
||||||
|
* Halts the continuous rendering loop. This is useful for
|
||||||
|
* performance optimization or when the component is unmounted.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* loop.stop();
|
||||||
|
* // Animation loop is now stopped
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
public stop(): void {
|
public stop(): void {
|
||||||
this.renderer.setAnimationLoop(null);
|
this.renderer.setAnimationLoop(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates all updatable objects with the current delta time.
|
||||||
|
*
|
||||||
|
* This method is called each frame to update all objects that
|
||||||
|
* implement a tick method. It calculates the delta time since
|
||||||
|
* the last frame and passes it to each updatable object.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
private tick(): void {
|
private tick(): void {
|
||||||
const delta = clock.getDelta();
|
const delta = clock.getDelta();
|
||||||
for (const object of this.updatables) {
|
for (const object of this.updatables) {
|
||||||
|
|||||||
@@ -1,19 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* WebGL Renderer System
|
||||||
|
*
|
||||||
|
* Provides an abstraction layer for Three.js WebGL rendering.
|
||||||
|
* Handles renderer configuration, canvas management, and rendering
|
||||||
|
* operations with proper TypeScript typing.
|
||||||
|
*
|
||||||
|
* @file Renderer.ts
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-29
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
import { WebGLRenderer, WebGLRendererParameters } from "three";
|
import { WebGLRenderer, WebGLRendererParameters } from "three";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renderer class for managing WebGL rendering operations.
|
||||||
|
*
|
||||||
|
* This class provides a wrapper around Three.js WebGLRenderer with
|
||||||
|
* additional configuration options and simplified interfaces. It handles
|
||||||
|
* canvas creation, rendering operations, and provides access to the
|
||||||
|
* underlying renderer for advanced usage.
|
||||||
|
*
|
||||||
|
* @class Renderer
|
||||||
|
* @author Matthew Raymer
|
||||||
|
*/
|
||||||
class Renderer {
|
class Renderer {
|
||||||
|
/** The underlying WebGL renderer instance */
|
||||||
private renderer: WebGLRenderer;
|
private renderer: WebGLRenderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Renderer instance with optional configuration.
|
||||||
|
*
|
||||||
|
* @param parameters - Optional WebGL renderer parameters for customization
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* // Basic renderer
|
||||||
|
* const renderer = new Renderer();
|
||||||
|
*
|
||||||
|
* // Custom renderer with parameters
|
||||||
|
* const renderer = new Renderer({
|
||||||
|
* antialias: true,
|
||||||
|
* alpha: true
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
constructor(parameters?: WebGLRendererParameters) {
|
constructor(parameters?: WebGLRendererParameters) {
|
||||||
this.renderer = new WebGLRenderer(parameters);
|
this.renderer = new WebGLRenderer(parameters);
|
||||||
this.renderer.useLegacyLights = false;
|
this.renderer.useLegacyLights = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the DOM canvas element for the renderer.
|
||||||
|
*
|
||||||
|
* @returns The HTML canvas element that can be added to the DOM
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const canvas = renderer.domElement;
|
||||||
|
* document.body.appendChild(canvas);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
public get domElement(): HTMLCanvasElement {
|
public get domElement(): HTMLCanvasElement {
|
||||||
return this.renderer.domElement;
|
return this.renderer.domElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add more custom methods and properties as needed
|
/**
|
||||||
|
* Renders a scene with the specified camera.
|
||||||
|
*
|
||||||
|
* This method delegates to the underlying WebGL renderer to draw
|
||||||
|
* the scene. It's typically called from the animation loop.
|
||||||
|
*
|
||||||
|
* @param scene - The scene to render
|
||||||
|
* @param camera - The camera to render from
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* renderer.render(scene, camera);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
public render(scene: any, camera: any): void {
|
public render(scene: any, camera: any): void {
|
||||||
this.renderer.render(scene, camera);
|
this.renderer.render(scene, camera);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Responsive Resizer System
|
||||||
|
*
|
||||||
|
* Handles responsive canvas resizing for the 3D world visualization.
|
||||||
|
* Automatically adjusts camera aspect ratio and renderer size when
|
||||||
|
* the window is resized to maintain proper proportions.
|
||||||
|
*
|
||||||
|
* @file Resizer.ts
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-29
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizer class for managing responsive canvas and camera resizing.
|
||||||
|
*
|
||||||
|
* This class handles window resize events and automatically adjusts
|
||||||
|
* the camera aspect ratio and renderer size to maintain proper
|
||||||
|
* proportions. It provides a clean interface for responsive 3D
|
||||||
|
* visualizations.
|
||||||
|
*
|
||||||
|
* @class Resizer
|
||||||
|
* @author Matthew Raymer
|
||||||
|
*/
|
||||||
class Resizer {
|
class Resizer {
|
||||||
|
/**
|
||||||
|
* Creates a new Resizer instance and sets up resize event handling.
|
||||||
|
*
|
||||||
|
* @param camera - The camera to adjust aspect ratio for
|
||||||
|
* @param renderer - The renderer to resize
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const resizer = new Resizer(camera, renderer);
|
||||||
|
* // Resizer is now listening for window resize events
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
constructor(camera: any, renderer: any) {
|
constructor(camera: any, renderer: any) {
|
||||||
this.setSize(camera, renderer);
|
this.setSize(camera, renderer);
|
||||||
|
|
||||||
@@ -9,9 +44,20 @@ class Resizer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the size of the camera and renderer based on window dimensions.
|
||||||
|
*
|
||||||
|
* This method calculates the appropriate dimensions, updates the
|
||||||
|
* camera aspect ratio, and resizes the renderer canvas. It accounts
|
||||||
|
* for a 50px offset from the window width for UI elements.
|
||||||
|
*
|
||||||
|
* @param camera - The camera to update aspect ratio for
|
||||||
|
* @param renderer - The renderer to resize
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
private setSize(camera: any, renderer: any): void {
|
private setSize(camera: any, renderer: any): void {
|
||||||
const height = window.innerHeight;
|
const height = window.innerHeight;
|
||||||
const width = window.innerWidth - 50;
|
const width = window.innerWidth - 50; // Account for UI offset
|
||||||
|
|
||||||
camera.aspect = width / height;
|
camera.aspect = width / height;
|
||||||
camera.updateProjectionMatrix();
|
camera.updateProjectionMatrix();
|
||||||
@@ -20,6 +66,23 @@ class Resizer {
|
|||||||
renderer.setPixelRatio(window.devicePixelRatio);
|
renderer.setPixelRatio(window.devicePixelRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback method called when the window is resized.
|
||||||
|
*
|
||||||
|
* This method can be overridden to perform custom actions when
|
||||||
|
* the window is resized, such as updating UI elements or
|
||||||
|
* recalculating object positions.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* class CustomResizer extends Resizer {
|
||||||
|
* onResize(): void {
|
||||||
|
* // Custom resize logic
|
||||||
|
* this.updateUIElements();
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
onResize(): void {
|
onResize(): void {
|
||||||
// Perform any custom actions on resize
|
// Perform any custom actions on resize
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
// Target ES2020 for modern browser support
|
||||||
"useDefineForClassFields": true,
|
"target": "ES2020",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"experimentalDecorators": true,
|
|
||||||
|
// Enable experimental decorators for Vue-facing-decorator
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
|
||||||
/* Bundler mode */
|
/* Bundler mode for Vite */
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
@@ -16,12 +19,33 @@
|
|||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
|
|
||||||
/* Linting */
|
/* Linting and type checking */
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noFallthroughCasesInSwitch": true
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
|
||||||
|
/* Additional type checking */
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"exactOptionalPropertyTypes": true,
|
||||||
|
|
||||||
|
/* Module resolution */
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["src/*"],
|
||||||
|
"@/components/*": ["src/components/*"],
|
||||||
|
"@/systems/*": ["src/systems/*"],
|
||||||
|
"@/types/*": ["src/types/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/types/endorser.d.ts"],
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.d.ts",
|
||||||
|
"src/**/*.tsx",
|
||||||
|
"src/**/*.vue",
|
||||||
|
"src/types/endorser.d.ts",
|
||||||
|
"components/**/*.ts"
|
||||||
|
],
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Vite Configuration
|
||||||
|
*
|
||||||
|
* Build tool configuration for the World Component project.
|
||||||
|
* Provides development server, build optimization, and path aliases.
|
||||||
|
*
|
||||||
|
* @file vite.config.ts
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @created 2023-06-28
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import { resolve } from 'path'
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
|
|
||||||
|
// Path aliases for cleaner imports
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': resolve(__dirname, 'src'),
|
||||||
|
'@/components': resolve(__dirname, 'src/components'),
|
||||||
|
'@/systems': resolve(__dirname, 'src/systems'),
|
||||||
|
'@/types': resolve(__dirname, 'src/types'),
|
||||||
|
'@/assets': resolve(__dirname, 'src/assets')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Build configuration
|
||||||
|
build: {
|
||||||
|
target: 'es2020',
|
||||||
|
outDir: 'dist',
|
||||||
|
assetsDir: 'assets',
|
||||||
|
sourcemap: true,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks: {
|
||||||
|
'three': ['three'],
|
||||||
|
'vue': ['vue'],
|
||||||
|
'vendor': ['axios', 'ramda']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Development server configuration
|
||||||
|
server: {
|
||||||
|
port: 3000,
|
||||||
|
open: true,
|
||||||
|
host: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// Preview server configuration
|
||||||
|
preview: {
|
||||||
|
port: 4173,
|
||||||
|
open: true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user