Skip to content

Commit 83b7d9b

Browse files
committed
content(app): wallpaper engine V2
1 parent af3e936 commit 83b7d9b

File tree

1 file changed

+175
-2
lines changed

1 file changed

+175
-2
lines changed

src/pages/apps/WallpaperEnginePage.jsx

Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const COLOR_PRESETS = [
2222
{ label: 'Matrix', value: 'matrix', colors: ['#00ff41', '#008f11', '#003b00', '#0d0208'] },
2323
{ label: 'Deep Sea', value: 'ocean', colors: ['#0ea5e9', '#2dd4bf', '#1e1b4b', '#f0f9ff'] },
2424
{ label: 'Monochrome', value: 'mono', colors: ['#ffffff', '#a3a3a3', '#404040', '#000000'] },
25+
{ label: 'Pip-Boy Amber', value: 'pipboy_amber', colors: ['#ffb642', '#8a5d00', '#211500', '#050505'] },
26+
{ label: 'Pip-Boy Green', value: 'pipboy_green', colors: ['#18e73c', '#005c00', '#001a00', '#050505'] },
2527
{ label: 'Custom', value: 'custom', colors: [] },
2628
];
2729

@@ -39,6 +41,7 @@ const STYLES = [
3941
{ label: 'Isometric Grid', value: 'iso' },
4042
{ label: 'Organic Noise', value: 'noise' },
4143
{ label: 'Type Matrix', value: 'typematrix' },
44+
{ label: 'Pip-Boy Interface', value: 'pipboy' },
4245
];
4346

4447
const RESOLUTIONS = [
@@ -446,9 +449,179 @@ const WallpaperEnginePage = () => {
446449
ctx.strokeRect(x - 5, y - fontSize, ctx.measureText(text).width + 10, fontSize + 5);
447450
}
448451
}
449-
}
452+
} else if (style === 'pipboy') {
453+
const mainColor = colors[0];
454+
const bgColor = colors[colors.length - 1];
455+
456+
// 1. CRT Background & Scanlines
457+
ctx.fillStyle = bgColor;
458+
ctx.fillRect(0, 0, canvas.width, canvas.height);
459+
460+
ctx.strokeStyle = mainColor;
461+
ctx.lineWidth = 0.5;
462+
ctx.globalAlpha = 0.1;
463+
for (let y = 0; y < canvas.height; y += 4) {
464+
ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(canvas.width, y); ctx.stroke();
465+
}
466+
467+
// 2. Fixed Header UI
468+
ctx.globalAlpha = 1.0;
469+
ctx.fillStyle = mainColor;
470+
ctx.font = `bold ${Math.floor(24 * (canvas.width/1920))}px monospace`;
471+
const tabs = ['STAT', 'INV', 'DATA', 'MAP', 'RADIO'];
472+
tabs.forEach((tab, i) => {
473+
const x = 100 + i * (canvas.width / 6);
474+
ctx.fillText(tab, x, 80);
475+
if (tab === 'DATA') { // Active tab indicator
476+
ctx.fillRect(x - 10, 90, ctx.measureText(tab).width + 20, 4);
477+
}
478+
});
479+
ctx.fillRect(50, 100, canvas.width - 100, 2);
480+
481+
// 3. Central Radar / Map Element
482+
const centerX = canvas.width * 0.75;
483+
const centerY = canvas.height * 0.5;
484+
const radius = 200 * (canvas.width / 1920);
485+
486+
ctx.strokeStyle = mainColor;
487+
ctx.lineWidth = 2;
488+
ctx.beginPath();
489+
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
490+
ctx.stroke();
491+
492+
ctx.globalAlpha = 0.3;
493+
for (let r = 1; r < 4; r++) {
494+
ctx.beginPath();
495+
ctx.arc(centerX, centerY, (radius / 4) * r, 0, Math.PI * 2);
496+
ctx.stroke();
497+
}
498+
499+
// Blips
500+
ctx.globalAlpha = 0.8;
501+
for (let i = 0; i < 5; i++) {
502+
const bx = centerX + (nextRand() - 0.5) * radius * 1.5;
503+
const by = centerY + (nextRand() - 0.5) * radius * 1.5;
504+
ctx.fillRect(bx, by, 8, 8);
505+
}
506+
507+
// 4. Data Listing
508+
ctx.font = `${Math.floor(18 * (canvas.width/1920))}px monospace`;
509+
const entries = [
510+
'FEZ_CODEX_OS v4.0.2',
511+
'MEMORY_BANK: OK',
512+
'RAD_LEVEL: 0.02 mSv',
513+
'LOCATION: NEW_VEGAS_STRIP',
514+
'SIGNAL: INTERCEPTED',
515+
'ENCRYPTION: ACTIVE',
516+
'USER: COURIER_SIX'
517+
];
518+
519+
entries.forEach((text, i) => {
520+
ctx.globalAlpha = 0.9;
521+
ctx.fillText(`> ${text}`, 100, 250 + i * 50);
522+
523+
// Progress Bars
524+
ctx.globalAlpha = 0.2;
525+
ctx.fillRect(100, 260 + i * 50, 300, 10);
526+
ctx.globalAlpha = 0.7;
527+
ctx.fillRect(100, 260 + i * 50, nextRand() * 300, 10);
528+
});
529+
530+
// 5. Vertical Scan Bar
531+
const scanY = (Date.now() / 20) % canvas.height;
532+
const grad = ctx.createLinearGradient(0, scanY - 50, 0, scanY);
533+
grad.addColorStop(0, 'transparent');
534+
grad.addColorStop(1, mainColor);
535+
ctx.fillStyle = grad;
536+
ctx.globalAlpha = 0.15;
537+
ctx.fillRect(0, scanY - 100, canvas.width, 100);
538+
539+
// 6. Corner Accents
540+
541+
ctx.globalAlpha = 1.0;
542+
543+
ctx.lineWidth = 4;
544+
545+
const cp = 40;
546+
547+
// Top Left
548+
549+
ctx.beginPath(); ctx.moveTo(cp, cp+50); ctx.lineTo(cp, cp); ctx.lineTo(cp+50, cp); ctx.stroke();
550+
551+
// Bottom Right
552+
553+
ctx.beginPath(); ctx.moveTo(canvas.width-cp, canvas.height-cp-50); ctx.lineTo(canvas.width-cp, canvas.height-cp); ctx.lineTo(canvas.width-cp-50, canvas.height-cp); ctx.stroke();
554+
555+
// 7. Horizontal Compass (Bottom)
556+
557+
const compassY = canvas.height - 150;
558+
559+
ctx.globalAlpha = 0.6;
560+
561+
ctx.fillRect(100, compassY, canvas.width - 200, 2);
562+
563+
ctx.font = `${Math.floor(14 * (canvas.width/1920))}px monospace`;
564+
565+
for(let i = 0; i <= 20; i++) {
566+
const x = 100 + i * ((canvas.width - 200) / 20);
567+
568+
const h = i % 5 === 0 ? 15 : 8;
569+
570+
ctx.fillRect(x, compassY - h, 2, h);
571+
572+
if (i % 5 === 0) {
573+
const dir = ['W', 'NW', 'N', 'NE', 'E'][i / 5];
574+
575+
if(dir) ctx.fillText(dir, x - 5, compassY - 25);
576+
}
577+
}
578+
579+
// 8. Condition Monitor (Bottom Left Area)
580+
581+
const vbX = 100;
582+
583+
const vbY = 650;
584+
585+
ctx.globalAlpha = 1.0;
586+
587+
ctx.strokeRect(vbX, vbY, 200, 200);
588+
589+
ctx.font = `bold ${Math.floor(12 * (canvas.width/1920))}px monospace`;
590+
591+
ctx.fillText("F.C.D.X. STATUS", vbX, vbY - 10);
592+
593+
// Simple procedural "Vault Boy" wireframe head
594+
595+
ctx.beginPath();
596+
597+
ctx.arc(vbX + 100, vbY + 80, 40, 0, Math.PI * 2); // Head
598+
599+
ctx.moveTo(vbX + 100, vbY + 120); ctx.lineTo(vbX + 100, vbY + 180); // Body
600+
601+
ctx.moveTo(vbX + 100, vbY + 140); ctx.lineTo(vbX + 60, vbY + 110); // Arm L
602+
603+
ctx.moveTo(vbX + 100, vbY + 140); ctx.lineTo(vbX + 140, vbY + 110); // Arm R
604+
605+
ctx.stroke();
606+
607+
ctx.fillText("DISCONN", vbX + 50, vbY + 195);
608+
609+
// 9. Micro Metadata
610+
611+
ctx.font = `${Math.floor(10 * (canvas.width/1920))}px monospace`;
612+
613+
ctx.globalAlpha = 0.4;
614+
615+
ctx.fillText("AP: 85/85", canvas.width - 200, canvas.height - 80);
616+
617+
ctx.fillText("HP: 240/240", canvas.width - 200, canvas.height - 60);
618+
619+
ctx.fillText("VOLTAGE: 1.2V", 100, canvas.height - 80);
620+
621+
ctx.fillText("OS_BUILD: 0.8.7", 100, canvas.height - 60);
622+
}
450623

451-
// Noise/Grain
624+
// Noise/Grain
452625
if (noise > 0) {
453626
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
454627
const data = imageData.data;

0 commit comments

Comments
 (0)