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);display: none; } select { appearance: none; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"><path fill="%234b5563" d="M7 10l5 5 5-5H7z"/></svg>'); background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 12px; } </style> <!-- Input Form --> <div class="input-containerx mb-12"> <h2 class="text-3xl font-semibold text-gray-800 mb-6">Enter Your Closet & Organizer Details</h2> <p class="text-gray-500 mb-8 text-lg">Input your closet and storage organizer (shelves or racks) dimensions to check if it fits comfortably.</p> <form id="closetFitForm" class="space-y-8"> <div class="grid grid-cols-1 md:grid-cols-4 gap-6"> <div class="space-y-3"> <label for="closetWidth" class="block text-sm font-medium text-gray-700">Closet Width (in)</label> <div class="relative flex items-center"> <i data-lucide="maximize" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="closetWidth" 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="72.0" step="0.1" min="24" max="120" value="72.0" required> </div> <input type="range" id="closetWidthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="24" max="120" step="0.1" value="72"> <p id="closetWidthValue" class="text-sm text-gray-500">72.0 in</p> </div> <div class="space-y-3"> <label for="closetDepth" class="block text-sm font-medium text-gray-700">Closet Depth (in)</label> <div class="relative flex items-center"> <i data-lucide="expand" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="closetDepth" 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="24.0" step="0.1" min="12" max="48" value="24.0" required> </div> <input type="range" id="closetDepthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="12" max="48" step="0.1" value="24"> <p id="closetDepthValue" class="text-sm text-gray-500">24.0 in</p> </div> <div class="space-y-3"> <label for="closetHeight" class="block text-sm font-medium text-gray-700">Closet Height (in)</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="closetHeight" 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="84.0" step="0.1" min="48" max="120" value="84.0" required> </div> <input type="range" id="closetHeightRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="48" max="120" step="0.1" value="84"> <p id="closetHeightValue" class="text-sm text-gray-500">84.0 in</p> </div> <div class="space-y-3"> <label for="organizerType" class="block text-sm font-medium text-gray-700">Organizer Type</label> <div class="relative flex items-center"> <i data-lucide="archive" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <select id="organizerType" class="pl-12 pr-10 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" required> <option value="Shelves" selected>Shelves</option> <option value="Racks">Racks</option> </select> </div> </div> </div> <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> <div class="space-y-3"> <label for="organizerWidth" class="block text-sm font-medium text-gray-700">Organizer Width (in)</label> <div class="relative flex items-center"> <i data-lucide="maximize" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="organizerWidth" 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="68.0" step="0.1" min="12" max="100" value="68.0" required> </div> <input type="range" id="organizerWidthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="12" max="100" step="0.1" value="68"> <p id="organizerWidthValue" class="text-sm text-gray-500">68.0 in</p> </div> <div class="space-y-3"> <label for="organizerDepth" class="block text-sm font-medium text-gray-700">Organizer Depth (in)</label> <div class="relative flex items-center"> <i data-lucide="expand" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="organizerDepth" 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="16.0" step="0.1" min="8" max="40" value="16.0" required> </div> <input type="range" id="organizerDepthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="8" max="40" step="0.1" value="16"> <p id="organizerDepthValue" class="text-sm text-gray-500">16.0 in</p> </div> <div class="space-y-3"> <label for="organizerHeight" class="block text-sm font-medium text-gray-700">Organizer Height (in)</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="organizerHeight" 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="80.0" step="0.1" min="24" max="100" value="80.0" required> </div> <input type="range" id="organizerHeightRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="24" max="100" step="0.1" value="80"> <p id="organizerHeightValue" class="text-sm text-gray-500">80.0 in</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 Organizer Fit </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 Closet Organizer Fit 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 interior design and storage planning 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="archive" class="mr-3 text-blue-500 h-6 w-6"></i> Interactive Closet & Organizer Visualization </h3> <div class="relative w-full h-96 bg-gray-200 rounded-xl overflow-hidden shadow-lg"> <canvas id="closetCanvas" class="w-full h-full"></canvas> </div> <p class="text-sm text-gray-600 mt-4">Visualization showing the organizer scaled to your closet width.</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 Closet Organization </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 2 in on sides and top for easy installation and 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>Depth Planning:</strong> Ensure shelves/racks are shallow enough for closet door clearance.</span> </li> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Accessibility:</strong> Keep frequently used items at eye level for convenience.</span> </li> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Modularity:</strong> Choose adjustable shelves or racks for flexible storage.</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> Add LED strips or motion-sensor lights to improve visibility.</span> </li> </ul> </div> </div> <script> // Initialize Lucid Icons lucide.createIcons(); // Sync range and number inputs function syncInputs(numberId, rangeId, valueId) { 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)} in`; }); rangeInput.addEventListener('input', () => { numberInput.value = rangeInput.value; valueDisplay.textContent = `${parseFloat(rangeInput.value).toFixed(1)} in`; }); } syncInputs('closetWidth', 'closetWidthRange', 'closetWidthValue'); syncInputs('closetDepth', 'closetDepthRange', 'closetDepthValue'); syncInputs('closetHeight', 'closetHeightRange', 'closetHeightValue'); syncInputs('organizerWidth', 'organizerWidthRange', 'organizerWidthValue'); syncInputs('organizerDepth', 'organizerDepthRange', 'organizerDepthValue'); syncInputs('organizerHeight', 'organizerHeightRange', 'organizerHeightValue'); // Form Submission document.getElementById('closetFitForm').addEventListener('submit', function (e) { e.preventDefault(); calculateClosetFit(); }); function calculateClosetFit() { const closetWidth = parseFloat(document.getElementById('closetWidth').value); const closetDepth = parseFloat(document.getElementById('closetDepth').value); const closetHeight = parseFloat(document.getElementById('closetHeight').value); const organizerType = document.getElementById('organizerType').value; const organizerWidth = parseFloat(document.getElementById('organizerWidth').value); const organizerDepth = parseFloat(document.getElementById('organizerDepth').value); const organizerHeight = parseFloat(document.getElementById('organizerHeight').value); if (!closetWidth || !closetDepth || !closetHeight || !organizerWidth || !organizerDepth || !organizerHeight || closetWidth < 24 || closetDepth < 12 || closetHeight < 48 || organizerWidth < 12 || organizerDepth < 8 || organizerHeight < 24) { alert('Please enter valid values (Closet Width ≥ 24 in, Depth ≥ 12 in, Height ≥ 48 in; Organizer Width ≥ 12 in, Depth ≥ 8 in, Height ≥ 24 in).'); return; } // Check fit with clearance (2 in on each side, 2 in on top) const widthClearance = closetWidth - organizerWidth >= 4; // 2 in each side const depthClearance = closetDepth - organizerDepth >= 2; // 2 in for door clearance const heightClearance = closetHeight - organizerHeight >= 2; // 2 in above const organizerFit = widthClearance && depthClearance && heightClearance ? 'Yes' : 'No'; // Calculate clearance/overages const widthClearanceIn = closetWidth - organizerWidth; const depthClearanceIn = closetDepth - organizerDepth; const heightClearanceIn = closetHeight - organizerHeight; // 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">Organizer Type</p> <p class="text-lg">${organizerType}</p> </div> <div> <p class="font-medium text-gray-700">Organizer Dimensions</p> <p class="text-xl text-blue-600 font-semibold">${organizerWidth.toFixed(1)} x ${organizerDepth.toFixed(1)} x ${organizerHeight.toFixed(1)} in</p> </div> <div> <p class="font-medium text-gray-700">Closet Dimensions</p> <p class="text-lg">${closetWidth.toFixed(1)} x ${closetDepth.toFixed(1)} x ${closetHeight.toFixed(1)} in</p> </div> <div> <p class="font-medium text-gray-700">Fit Assessment</p> <p class="text-lg ${organizerFit === 'Yes' ? 'text-green-600' : 'text-red-600'} font-semibold"> ${organizerFit === 'Yes' ? 'Perfect Fit' : 'May Not Fit Comfortably'} </p> <p class="text-sm text-gray-600">${ organizerFit === 'Yes' ? `The organizer fits with ${widthClearanceIn.toFixed(1)} in width clearance, ${depthClearanceIn.toFixed(1)} in depth clearance, and ${heightClearanceIn.toFixed(1)} in height clearance.` : `Issues: ${ !widthClearance ? `Insufficient width clearance (need ≥2 in each side, have ${widthClearanceIn.toFixed(1)} in). ` : '' }${ !depthClearance ? `Insufficient depth clearance (need ≥2 in, have ${depthClearanceIn.toFixed(1)} in). ` : '' }${ !heightClearance ? `Insufficient height clearance (need ≥2 in, have ${heightClearanceIn.toFixed(1)} in).` : '' }` }</p> </div> </div> <div class="bg-blue-50 p-4 rounded-lg"> <p class="text-sm"><span class="font-medium">Tip:</span> Measure your closet carefully, including any obstructions like baseboards or light fixtures.</p> </div> `; document.getElementById('resultOutput').innerHTML = output; document.getElementById('resultSection').classList.remove('hidden'); // Draw visualization drawVisualization(organizerWidth, organizerDepth, closetWidth, organizerType); // Setup PDF download setupPdfDownload(organizerType, organizerWidth, organizerDepth, organizerHeight, closetWidth, closetDepth, closetHeight, organizerFit, widthClearanceIn, depthClearanceIn, heightClearanceIn); } function drawVisualization(organizerWidth, organizerDepth, closetWidth, organizerType) { const canvas = document.getElementById('closetCanvas'); 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 / (closetWidth * 1.5); // Scale to fit canvas const organizerW = organizerWidth * scale; const organizerH = organizerDepth * scale; const closetW = closetWidth * scale; // Draw background with closet texture 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 closet floor ctx.fillStyle = 'rgba(120, 113, 108, 0.2)'; ctx.fillRect(0, canvas.height * 0.7, canvas.width, canvas.height * 0.3); // Draw closet outline (dashed) ctx.strokeStyle = '#1e40af'; ctx.lineWidth = 2; ctx.setLineDash([5, 5]); ctx.strokeRect(canvas.width * 0.55, canvas.height * 0.2, closetW, organizerH + 20); ctx.fillStyle = '#bfdbfe'; ctx.globalAlpha = 0.3; ctx.fillRect(canvas.width * 0.55, canvas.height * 0.2, closetW, organizerH + 20); ctx.globalAlpha = 1.0; ctx.setLineDash([]); // Draw organizer with realistic effects ctx.shadowColor = 'rgba(0, 0, 0, 0.4)'; ctx.shadowBlur = 15; ctx.shadowOffsetX = 8; ctx.shadowOffsetY = 8; ctx.fillStyle = '#4b5563'; const organizerX = canvas.width * 0.15; const organizerY = canvas.height * 0.2; ctx.fillRect(organizerX, organizerY, organizerW, organizerH); // Draw organizer texture const organizerGradient = ctx.createLinearGradient(organizerX, organizerY, organizerX + organizerW, organizerY + organizerH); organizerGradient.addColorStop(0, 'rgba(255, 255, 255, 0.15)'); organizerGradient.addColorStop(1, 'rgba(255, 255, 255, 0.05)'); ctx.fillStyle = organizerGradient; ctx.fillRect(organizerX + 5, organizerY + 5, organizerW - 10, organizerH - 10); // Draw text ctx.shadowColor = 'transparent'; ctx.fillStyle = '#ffffff'; ctx.font = 'bold 18px Poppins'; ctx.textAlign = 'center'; ctx.fillText(`${organizerType} (${organizerWidth.toFixed(1)} x ${organizerDepth.toFixed(1)} in)`, organizerX + organizerW / 2, organizerY + organizerH / 2); ctx.fillStyle = '#1e40af'; ctx.fillText(`Closet (${closetWidth.toFixed(1)} in)`, canvas.width * 0.55 + closetW / 2, canvas.height * 0.2 + (organizerH + 20) / 2); ctx.font = '14px Poppins'; ctx.fillStyle = '#4b5563'; ctx.fillText(`${organizerType} vs. Closet Width`, canvas.width / 2, canvas.height - 30); } function setupPdfDownload(organizerType, organizerWidth, organizerDepth, organizerHeight, closetWidth, closetDepth, closetHeight, organizerFit, widthClearanceIn, depthClearanceIn, heightClearanceIn) { 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 - Closet Organizer Fit 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 Closet Organizer Fit Assessment', 20, 40); doc.setFontSize(11); doc.text(`Organizer Type: ${organizerType}`, 20, 50); doc.text(`Organizer Dimensions: ${organizerWidth.toFixed(1)} x ${organizerDepth.toFixed(1)} x ${organizerHeight.toFixed(1)} in`, 20, 58); doc.text(`Closet Dimensions: ${closetWidth.toFixed(1)} x ${closetDepth.toFixed(1)} x ${closetHeight.toFixed(1)} in`, 20, 66); doc.text(`Fit Assessment: ${organizerFit === 'Yes' ? 'Perfect Fit' : 'May Not Fit Comfortably'}`, 20, 74); doc.text(`Clearance: ${widthClearanceIn.toFixed(1)} in (width), ${depthClearanceIn.toFixed(1)} in (depth), ${heightClearanceIn.toFixed(1)} in (height)`, 20, 82); doc.text(`Recommendation: ${ organizerFit === 'Yes' ? 'The organizer is suitable for your closet.' : 'Consider a smaller organizer or adjust closet layout.' }`, 20, 90); // Expert Insights doc.setFont('helvetica', 'bold'); doc.setFontSize(12); doc.text('Expert Insights', 20, 102); doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.text('• Clearance: Allow 2 in on sides and top for easy installation.', 20, 110); doc.text('• Depth Planning: Ensure shelves/racks fit with door clearance.', 20, 118); doc.text('• Accessibility: Keep frequent items at eye level.', 20, 126); doc.text('• Modularity: Choose adjustable shelves for flexibility.', 20, 134); doc.text('• Lighting: Add LED lights for better visibility.', 20, 142); doc.save('HomeFit_Closet_Organizer_Fit_Assessment.pdf'); }; } </script>