JavaScript · 2673 bytes Raw Blame History
1 // dougk - a cozy pond simulator featuring Doug the duck
2 // Supports both 2D (p5.js) and 3D (Three.js) rendering modes
3
4 import * as p5Renderer from './renderers/p5/index.js'
5 import * as threeRenderer from './renderers/three/index.js'
6
7 const renderers = {
8 '2d': p5Renderer,
9 '3d': threeRenderer
10 }
11
12 let currentMode = localStorage.getItem('dougk-mode') || '3d'
13 let container = null
14
15 // Create the container
16 function createContainer() {
17 container = document.createElement('div')
18 container.id = 'dougk-container'
19 container.style.cssText = 'position: fixed; inset: 0; z-index: 0;'
20 document.body.appendChild(container)
21 }
22
23 // Create the toggle UI
24 function createToggleUI() {
25 const toggle = document.createElement('div')
26 toggle.id = 'mode-toggle'
27 toggle.style.cssText = `
28 position: fixed;
29 top: 20px;
30 right: 20px;
31 z-index: 1000;
32 display: flex;
33 gap: 0;
34 font-family: system-ui, -apple-system, sans-serif;
35 font-size: 14px;
36 font-weight: 600;
37 border-radius: 8px;
38 overflow: hidden;
39 box-shadow: 0 2px 8px rgba(0,0,0,0.2);
40 border: 2px solid #191410;
41 `
42
43 const btn2d = createToggleButton('2D', '2d')
44 const btn3d = createToggleButton('3D', '3d')
45
46 toggle.appendChild(btn2d)
47 toggle.appendChild(btn3d)
48 document.body.appendChild(toggle)
49
50 updateToggleUI()
51 }
52
53 function createToggleButton(label, mode) {
54 const btn = document.createElement('button')
55 btn.textContent = label
56 btn.dataset.mode = mode
57 btn.style.cssText = `
58 padding: 10px 20px;
59 border: none;
60 cursor: pointer;
61 transition: all 0.2s ease;
62 font-weight: 600;
63 font-size: 14px;
64 `
65 btn.addEventListener('click', () => switchMode(mode))
66 return btn
67 }
68
69 function updateToggleUI() {
70 const buttons = document.querySelectorAll('#mode-toggle button')
71 buttons.forEach(btn => {
72 const isActive = btn.dataset.mode === currentMode
73 btn.style.background = isActive ? '#ffdc50' : '#ffffff'
74 btn.style.color = '#191410'
75 })
76 }
77
78 function switchMode(newMode) {
79 if (newMode === currentMode) return
80
81 // Stop current renderer
82 renderers[currentMode].stop()
83
84 // Clear container
85 container.innerHTML = ''
86
87 // Switch mode
88 currentMode = newMode
89 localStorage.setItem('dougk-mode', currentMode)
90
91 // Start new renderer
92 renderers[currentMode].start(container)
93
94 updateToggleUI()
95 }
96
97 // Initialize
98 createContainer()
99 createToggleUI()
100 renderers[currentMode].start(container)
101
102 // Keyboard shortcut: press 'T' to toggle
103 document.addEventListener('keydown', (e) => {
104 if (e.key.toLowerCase() === 't' && !e.ctrlKey && !e.metaKey && !e.altKey) {
105 const newMode = currentMode === '2d' ? '3d' : '2d'
106 switchMode(newMode)
107 }
108 })