Create New Item
×
Item Type
File
Folder
Item Name
×
Search file in folder and subfolders...
File Manager
/
tools
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php include "../autoload.php"; ?> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> <style> @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap'); .gradient-bg { background: linear-gradient(135deg, #1e40af 0%, #60a5fa 100%); } .result-card { background: linear-gradient(145deg, #ffffff, #f0f7ff); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15); transition: transform 0.3s ease, opacity 0.3s ease; } .result-card.hidden { transform: translateY(20px); opacity: 0; } .result-card:not(.hidden) { transform: translateY(0); opacity: 1; } .input-container { background: linear-gradient(145deg, #ffffff, #f9fafb); transition: all 0.3s ease; } .input-container:hover { transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1); } .range-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; background: #1e40af; border-radius: 50%; cursor: pointer; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); } .range-input::-moz-range-thumb { width: 20px; height: 20px; background: #1e40af; border-radius: 50%; cursor: pointer; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); } .btn-primary { transition: all 0.3s ease; } .btn-primary:hover { transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2); } .visual-container { background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect fill="%23f3f4f6" width="100" height="100"/><circle cx="50" cy="50" r="30" fill="%23dbeafe" opacity="0.5"/></svg>') repeat; border-radius: 12px; box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.05); } </style> <div class="x"> <div class="x"> <!-- Input Form --> <div class="mb-12"> <h2 class="text-3xl font-semibold text-gray-800 mb-6">Enter Your Bookshelf & Wall Space Details</h2> <p class="text-gray-500 mb-8 text-lg">Input dimensions to check if your bookshelf fits and avoids obstructing outlets or switches.</p> <form id="bookshelfClearanceForm" class="space-y-8"> <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> <div class="space-y-3"> <label for="bookshelfWidth" class="block text-sm font-medium text-gray-700">Bookshelf Width (ft)</label> <div class="relative flex items-center"> <i data-lucide="book-open" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="bookshelfWidth" class="pl-12 pr-4 py-3 block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-600 focus:ring focus:ring-blue-600 focus:ring-opacity-50 text-lg" placeholder="4.0" step="0.1" min="2" max="8" value="4.0" required> </div> <input type="range" id="bookshelfWidthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="2" max="8" step="0.1" value="4"> <p id="bookshelfWidthValue" class="text-sm text-gray-500">4.0 ft</p> </div> <div class="space-y-3"> <label for="bookshelfHeight" class="block text-sm font-medium text-gray-700">Bookshelf Height (ft)</label> <div class="relative flex items-center"> <i data-lucide="ruler" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="bookshelfHeight" class="pl-12 pr-4 py-3 block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-600 focus:ring focus:ring-blue-600 focus:ring-opacity-50 text-lg" placeholder="6.0" step="0.1" min="3" max="10" value="6.0" required> </div> <input type="range" id="bookshelfHeightRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="3" max="10" step="0.1" value="6"> <p id="bookshelfHeightValue" class="text-sm text-gray-500">6.0 ft</p> </div> <div class="space-y-3"> <label for="wallWidth" class="block text-sm font-medium text-gray-700">Wall Width (ft)</label> <div class="relative flex items-center"> <i data-lucide="wall" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="wallWidth" class="pl-12 pr-4 py-3 block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-600 focus:ring focus:ring-blue-600 focus:ring-opacity-50 text-lg" placeholder="6.0" step="0.1" min="3" max="12" value="6.0" required> </div> <input type="range" id="wallWidthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="3" max="12" step="0.1" value="6"> <p id="wallWidthValue" class="text-sm text-gray-500">6.0 ft</p> </div> </div> <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> <div class="space-y-3"> <label for="wallHeight" class="block text-sm font-medium text-gray-700">Wall Height (ft)</label> <div class="relative flex items-center"> <i data-lucide="ruler" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="wallHeight" class="pl-12 pr-4 py-3 block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-600 focus:ring focus:ring-blue-600 focus:ring-opacity-50 text-lg" placeholder="8.0" step="0.1" min="5" max="12" value="8.0" required> </div> <input type="range" id="wallHeightRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="5" max="12" step="0.1" value="8"> <p id="wallHeightValue" class="text-sm text-gray-500">8.0 ft</p> </div> <div class="space-y-3"> <label for="outletPositionX" class="block text-sm font-medium text-gray-700">Outlet/Switch X Position (ft)</label> <div class="relative flex items-center"> <i data-lucide="plug" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="outletPositionX" class="pl-12 pr-4 py-3 block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-600 focus:ring focus:ring-blue-600 focus:ring-opacity-50 text-lg" placeholder="5.0" step="0.1" min="0" max="12" value="5.0" required> </div> <input type="range" id="outletPositionXRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="0" max="12" step="0.1" value="5"> <p id="outletPositionXValue" class="text-sm text-gray-500">5.0 ft</p> </div> <div class="space-y-3"> <label for="outletPositionY" class="block text-sm font-medium text-gray-700">Outlet/Switch Y Position (ft)</label> <div class="relative flex items-center"> <i data-lucide="plug" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="outletPositionY" class="pl-12 pr-4 py-3 block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-600 focus:ring focus:ring-blue-600 focus:ring-opacity-50 text-lg" placeholder="1.0" step="0.1" min="0" max="12" value="1.0" required> </div> <input type="range" id="outletPositionYRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="0" max="12" step="0.1" value="1"> <p id="outletPositionYValue" class="text-sm text-gray-500">1.0 ft</p> </div> </div> <button type="submit" class="btn-primary w-full bg-blue-600 text-white py-4 px-8 rounded-xl hover:bg-blue-700 flex items-center justify-center text-lg"> <i data-lucide="search" class="mr-3 h-5 w-5"></i> Check Bookshelf Clearance </button> </form> </div> <!-- Result Section --> <div id="resultSection" class="result-card rounded-2xl p-10 hidden"> <h2 class="text-3xl font-semibold text-gray-800 mb-6 flex items-center"> <i data-lucide="check-circle-2" class="mr-3 text-green-500 h-7 w-7"></i> Your Bookshelf Clearance Assessment </h2> <div id="resultOutput" class="text-gray-700 space-y-6 text-base"> <!-- Results will be dynamically inserted here --> </div> <div class="mt-10 flex flex-col md:flex-row justify-between items-center gap-6"> <div class="flex items-center text-blue-600"> <i data-lucide="info" class="mr-2 h-5 w-5"></i> <p class="text-sm font-medium">Based on standard furniture and electrical layout standards.</p> </div> <button id="downloadPdf" class="btn-primary bg-green-600 text-white py-3 px-8 rounded-xl hover:bg-green-700 flex items-center text-base"> <i data-lucide="download" class="mr-2 h-5 w-5"></i> Download PDF Report </button> </div> <!-- Visual Representation --> <div class="mt-10 visual-container p-8"> <h3 class="text-xl font-medium text-gray-800 mb-4 flex items-center"> <i data-lucide="book-open" class="mr-3 text-blue-500 h-6 w-6"></i> Interactive Bookshelf & Wall Visualization </h3> <div class="relative w-full h-96 bg-gray-200 rounded-xl overflow-hidden shadow-lg"> <canvas id="bookshelfCanvas" class="w-full h-full"></canvas> </div> <p class="text-sm text-gray-600 mt-4">Visualization showing the bookshelf and outlet/switch position scaled to the wall space.</p> </div> <!-- Expert Insights --> <div class="mt-10 bg-blue-50 p-8 rounded-xl shadow-sm"> <h3 class="text-xl font-medium text-gray-800 mb-4 flex items-center"> <i data-lucide="lightbulb" class="mr-3 text-yellow-500 h-6 w-6"></i> Expert Insights for Bookshelf Placement </h3> <ul class="list-none space-y-4 text-gray-700 text-sm"> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Clearance:</strong> Allow 0.5 ft clearance around outlets/switches for access.</span> </li> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Positioning:</strong> Center bookshelf on wall for aesthetic balance.</span> </li> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Stability:</strong> Secure bookshelf to wall to prevent tipping.</span> </li> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Lighting:</strong> Ensure bookshelf placement allows adequate room lighting.</span> </li> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Access:</strong> Avoid blocking pathways or doorways with the bookshelf.</span> </li> </ul> </div> </div> </div> </div> <script> // Initialize Lucid Icons lucide.createIcons(); // Sync range and number inputs function syncInputs(numberId, rangeId, valueId, unit = 'ft') { const numberInput = document.getElementById(numberId); const rangeInput = document.getElementById(rangeId); const valueDisplay = document.getElementById(valueId); numberInput.addEventListener('input', () => { rangeInput.value = numberInput.value; valueDisplay.textContent = `${parseFloat(numberInput.value).toFixed(1)} ${unit}`; }); rangeInput.addEventListener('input', () => { numberInput.value = rangeInput.value; valueDisplay.textContent = `${parseFloat(rangeInput.value).toFixed(1)} ${unit}`; }); } syncInputs('bookshelfWidth', 'bookshelfWidthRange', 'bookshelfWidthValue'); syncInputs('bookshelfHeight', 'bookshelfHeightRange', 'bookshelfHeightValue'); syncInputs('wallWidth', 'wallWidthRange', 'wallWidthValue'); syncInputs('wallHeight', 'wallHeightRange', 'wallHeightValue'); syncInputs('outletPositionX', 'outletPositionXRange', 'outletPositionXValue'); syncInputs('outletPositionY', 'outletPositionYRange', 'outletPositionYValue'); // Form Submission document.getElementById('bookshelfClearanceForm').addEventListener('submit', function (e) { e.preventDefault(); calculateBookshelfClearance(); }); function calculateBookshelfClearance() { const bookshelfWidth = parseFloat(document.getElementById('bookshelfWidth').value); const bookshelfHeight = parseFloat(document.getElementById('bookshelfHeight').value); const wallWidth = parseFloat(document.getElementById('wallWidth').value); const wallHeight = parseFloat(document.getElementById('wallHeight').value); const outletPositionX = parseFloat(document.getElementById('outletPositionX').value); const outletPositionY = parseFloat(document.getElementById('outletPositionY').value); if (!bookshelfWidth || !bookshelfHeight || !wallWidth || !wallHeight || outletPositionX < 0 || outletPositionY < 0 || bookshelfWidth < 2 || bookshelfHeight < 3 || wallWidth < 3 || wallHeight < 5 || outletPositionX > wallWidth || outletPositionY > wallHeight) { alert('Please enter valid values (Bookshelf Width ≥ 2 ft, Height ≥ 3 ft, Wall Width ≥ 3 ft, Height ≥ 5 ft, Outlet X/Y within wall dimensions).'); return; } // Calculate fit: Bookshelf centered on wall const widthFit = bookshelfWidth + 0.5 <= wallWidth; // 0.25 ft clearance each side const heightFit = bookshelfHeight + 0.5 <= wallHeight; // 0.5 ft clearance top const overallFit = widthFit && heightFit ? 'Yes' : 'No'; // Check outlet/switch obstruction (0.5 ft x 0.5 ft area around outlet) const bookshelfLeft = (wallWidth - bookshelfWidth) / 2; const bookshelfRight = bookshelfLeft + bookshelfWidth; const bookshelfTop = 0; const bookshelfBottom = bookshelfHeight; const outletLeft = outletPositionX - 0.25; const outletRight = outletPositionX + 0.25; const outletTop = outletPositionY - 0.25; const outletBottom = outletPositionY + 0.25; const obstructsOutlet = !( outletRight < bookshelfLeft || outletLeft > bookshelfRight || outletBottom < bookshelfTop || outletTop > bookshelfBottom ); const clearanceStatus = obstructsOutlet ? 'Obstructs Outlet/Switch' : 'Clear of Outlet/Switch'; // Calculate clearances const widthClearance = wallWidth - bookshelfWidth - 0.5; const heightClearance = wallHeight - bookshelfHeight - 0.5; // Generate output const output = ` <div class="grid grid-cols-1 md:grid-cols-2 gap-6 bg-white p-6 rounded-xl shadow-sm"> <div> <p class="font-medium text-gray-700">Bookshelf Dimensions</p> <p class="text-xl text-blue-600 font-semibold">${bookshelfWidth.toFixed(1)} x ${bookshelfHeight.toFixed(1)} ft</p> </div> <div> <p class="font-medium text-gray-700">Wall Space Dimensions</p> <p class="text-lg">${wallWidth.toFixed(1)} x ${wallHeight.toFixed(1)} ft</p> </div> <div> <p class="font-medium text-gray-700">Outlet/Switch Position</p> <p class="text-lg">X: ${outletPositionX.toFixed(1)} ft, Y: ${outletPositionY.toFixed(1)} ft</p> </div> <div> <p class="font-medium text-gray-700">Fit Assessment</p> <p class="text-lg ${overallFit === 'Yes' && !obstructsOutlet ? 'text-green-600' : 'text-red-600'} font-semibold"> ${overallFit === 'Yes' && !obstructsOutlet ? 'Perfect Fit' : 'May Not Fit Comfortably'} </p> <p class="text-sm text-gray-600">${ overallFit === 'Yes' && !obstructsOutlet ? `The bookshelf fits with ${widthClearance.toFixed(1)} ft width clearance and ${heightClearance.toFixed(1)} ft height clearance, clear of outlet/switch.` : `Issues: ${ !widthFit ? `Insufficient width clearance (need ≥${(bookshelfWidth + 0.5).toFixed(1)} ft, have ${wallWidth.toFixed(1)} ft). ` : '' }${ !heightFit ? `Insufficient height clearance (need ≥${(bookshelfHeight + 0.5).toFixed(1)} ft, have ${wallHeight.toFixed(1)} ft). ` : '' }${ obstructsOutlet ? `Bookshelf obstructs outlet/switch at (${outletPositionX.toFixed(1)}, ${outletPositionY.toFixed(1)} ft).` : '' }` }</p> </div> </div> <div class="bg-blue-50 p-4 rounded-lg"> <p class="text-sm"><span class="font-medium">Tip:</span> Measure outlet/switch positions from the bottom-left corner of the wall and ensure clearance for access.</p> </div> `; document.getElementById('resultOutput').innerHTML = output; document.getElementById('resultSection').classList.remove('hidden'); // Draw visualization drawVisualization(bookshelfWidth, bookshelfHeight, wallWidth, wallHeight, outletPositionX, outletPositionY, obstructsOutlet); // Setup PDF download setupPdfDownload(bookshelfWidth, bookshelfHeight, wallWidth, wallHeight, outletPositionX, outletPositionY, overallFit, clearanceStatus, widthClearance, heightClearance); } function drawVisualization(bookshelfWidth, bookshelfHeight, wallWidth, wallHeight, outletPositionX, outletPositionY, obstructsOutlet) { const canvas = document.getElementById('bookshelfCanvas'); const ctx = canvas.getContext('2d'); canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; // Clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Scale factors const scale = canvas.width / (wallWidth * 1.5); // Scale to fit canvas const bookshelfW = bookshelfWidth * scale; const bookshelfH = bookshelfHeight * scale; const wallW = wallWidth * scale; const wallH = wallHeight * scale; const outletW = 0.5 * scale; // Outlet/switch size const outletH = 0.5 * scale; const outletX = outletPositionX * scale; const outletY = (wallHeight - outletPositionY - 0.25) * scale; // Y from bottom // Draw background const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height); gradient.addColorStop(0, '#e5e7eb'); gradient.addColorStop(1, '#d1d5db'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw wall outline (dashed) ctx.strokeStyle = '#1e40af'; ctx.lineWidth = 2; ctx.setLineDash([5, 5]); ctx.strokeRect(canvas.width * 0.55, canvas.height * 0.2, wallW, wallH); ctx.fillStyle = '#bfdbfe'; ctx.globalAlpha = 0.3; ctx.fillRect(canvas.width * 0.55, canvas.height * 0.2, wallW, wallH); ctx.globalAlpha = 1.0; ctx.setLineDash([]); // Draw bookshelf with realistic effects ctx.shadowColor = 'rgba(0, 0, 0, 0.4)'; ctx.shadowBlur = 15; ctx.shadowOffsetX = 8; ctx.shadowOffsetY = 8; ctx.fillStyle = '#4b5563'; const bookshelfX = canvas.width * 0.15 + (wallW - bookshelfW) / 2; const bookshelfY = canvas.height * 0.2 + (wallH - bookshelfH); ctx.fillRect(bookshelfX, bookshelfY, bookshelfW, bookshelfH); // Draw bookshelf texture const bookshelfGradient = ctx.createLinearGradient(bookshelfX, bookshelfY, bookshelfX + bookshelfW, bookshelfY + bookshelfH); bookshelfGradient.addColorStop(0, 'rgba(255, 255, 255, 0.15)'); bookshelfGradient.addColorStop(1, 'rgba(255, 255, 255, 0.05)'); ctx.fillStyle = bookshelfGradient; ctx.fillRect(bookshelfX + 5, bookshelfY + 5, bookshelfW - 10, bookshelfH - 10); // Draw outlet/switch ctx.fillStyle = obstructsOutlet ? '#dc2626' : '#2d3748'; ctx.fillRect(canvas.width * 0.55 + outletX, canvas.height * 0.2 + outletY, outletW, outletH); // Draw text ctx.shadowColor = 'transparent'; ctx.fillStyle = '#ffffff'; ctx.font = 'bold 18px Poppins'; ctx.textAlign = 'center'; ctx.fillText(`Bookshelf (${bookshelfWidth.toFixed(1)} x ${bookshelfHeight.toFixed(1)} ft)`, bookshelfX + bookshelfW / 2, bookshelfY + bookshelfH / 2); ctx.fillStyle = '#1e40af'; ctx.fillText(`Wall (${wallWidth.toFixed(1)} x ${wallHeight.toFixed(1)} ft)`, canvas.width * 0.55 + wallW / 2, canvas.height * 0.2 + wallH / 2); ctx.fillStyle = obstructsOutlet ? '#dc2626' : '#2d3748'; ctx.font = '14px Poppins'; ctx.fillText(`Outlet/Switch (${outletPositionX.toFixed(1)}, ${outletPositionY.toFixed(1)} ft)`, canvas.width * 0.55 + outletX + outletW / 2, canvas.height * 0.2 + outletY + outletH / 2); ctx.fillStyle = '#4b5563'; ctx.fillText(`Bookshelf vs. Wall Space`, canvas.width / 2, canvas.height - 30); } function setupPdfDownload(bookshelfWidth, bookshelfHeight, wallWidth, wallHeight, outletPositionX, outletPositionY, overallFit, clearanceStatus, widthClearance, heightClearance) { document.getElementById('downloadPdf').onclick = function () { const { jsPDF } = window.jspdf; const doc = new jsPDF(); // Header doc.setFont('helvetica', 'bold'); doc.setFontSize(20); doc.setTextColor(31, 64, 175); doc.text('HomeFit Tools - Bookshelf Clearance Assessment Report', 20, 20); doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.setTextColor(100, 100, 100); doc.text(`Generated on: ${new Date().toLocaleString()}`, 20, 28); // Results doc.setFontSize(14); doc.setTextColor(0, 0, 0); doc.text('Your Bookshelf Clearance Assessment', 20, 40); doc.setFontSize(11); doc.text(`Bookshelf Dimensions: ${bookshelfWidth.toFixed(1)} x ${bookshelfHeight.toFixed(1)} ft`, 20, 50); doc.text(`Wall Space Dimensions: ${wallWidth.toFixed(1)} x ${wallHeight.toFixed(1)} ft`, 20, 58); doc.text(`Outlet/Switch Position: X: ${outletPositionX.toFixed(1)} ft, Y: ${outletPositionY.toFixed(1)} ft`, 20, 66); doc.text(`Fit Assessment: ${overallFit === 'Yes' && clearanceStatus === 'Clear of Outlet/Switch' ? 'Perfect Fit' : 'May Not Fit Comfortably'}`, 20, 74); doc.text(`Clearance Status: ${clearanceStatus}`, 20, 82); doc.text(`Clearances: ${widthClearance.toFixed(1)} ft (width), ${heightClearance.toFixed(1)} ft (height)`, 20, 90); doc.text(`Recommendation: ${ overallFit === 'Yes' && clearanceStatus === 'Clear of Outlet/Switch' ? 'The bookshelf fits well and avoids obstructions.' : 'Adjust bookshelf size or position to avoid outlet/switch or fit wall.' }`, 20, 98); // Expert Insights doc.setFont('helvetica', 'bold'); doc.setFontSize(12); doc.text('Expert Insights', 20, 110); doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.text('• Clearance: Allow 0.5 ft around outlets/switches for access.', 20, 118); doc.text('• Positioning: Center bookshelf for aesthetic balance.', 20, 126); doc.text('• Stability: Secure bookshelf to wall to prevent tipping.', 20, 134); doc.text('• Lighting: Ensure placement allows adequate room lighting.', 20, 142); doc.text('• Access: Avoid blocking pathways or doorways.', 20, 150); doc.save('HomeFit_Bookshelf_Clearance_Assessment.pdf'); }; } </script>