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); } 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> <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 Over-the-Toilet Shelf & Bathroom Details</h2> <p class="text-gray-500 mb-8 text-lg">Input shelf dimensions, toilet size, and wall space to check if the shelf fits above the toilet without interference.</p> <form id="shelfFitForm" class="space-y-8"> <div class="grid grid-cols-1 md:grid-cols-4 gap-6"> <div class="space-y-3"> <label for="shelfWidth" class="block text-sm font-medium text-gray-700">Shelf Width (ft)</label> <div class="relative flex items-center"> <i data-lucide="shelf" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="shelfWidth" 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="2.5" step="0.1" min="1" max="4" value="2.5" required> </div> <input type="range" id="shelfWidthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="1" max="4" step="0.1" value="2.5"> <p id="shelfWidthValue" class="text-sm text-gray-500">2.5 ft</p> </div> <div class="space-y-3"> <label for="shelfDepth" class="block text-sm font-medium text-gray-700">Shelf Depth (ft)</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="shelfDepth" 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.5" max="2" value="1.0" required> </div> <input type="range" id="shelfDepthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="0.5" max="2" step="0.1" value="1.0"> <p id="shelfDepthValue" class="text-sm text-gray-500">1.0 ft</p> </div> <div class="space-y-3"> <label for="shelfHeight" class="block text-sm font-medium text-gray-700">Shelf 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="shelfHeight" 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="2.5" step="0.1" min="1" max="4" value="2.5" required> </div> <input type="range" id="shelfHeightRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="1" max="4" step="0.1" value="2.5"> <p id="shelfHeightValue" class="text-sm text-gray-500">2.5 ft</p> </div> <div class="space-y-3"> <label for="toiletWidth" class="block text-sm font-medium text-gray-700">Toilet Width (ft)</label> <div class="relative flex items-center"> <i data-lucide="bath" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="toiletWidth" 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="2.0" step="0.1" min="1" max="3" value="2.0" required> </div> <input type="range" id="toiletWidthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="1" max="3" step="0.1" value="2.0"> <p id="toiletWidthValue" class="text-sm text-gray-500">2.0 ft</p> </div> </div> <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> <div class="space-y-3"> <label for="toiletDepth" class="block text-sm font-medium text-gray-700">Toilet Depth (ft)</label> <div class="relative flex items-center"> <i data-lucide="bath" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="toiletDepth" 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="2.5" step="0.1" min="1.5" max="3.5" value="2.5" required> </div> <input type="range" id="toiletDepthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="1.5" max="3.5" step="0.1" value="2.5"> <p id="toiletDepthValue" class="text-sm text-gray-500">2.5 ft</p> </div> <div class="space-y-3"> <label for="toiletHeight" class="block text-sm font-medium text-gray-700">Toilet Tank 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="toiletHeight" 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="2.5" step="0.1" min="1" max="3" value="2.5" required> </div> <input type="range" id="toiletHeightRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="1" max="3" step="0.1" value="2.5"> <p id="toiletHeightValue" class="text-sm text-gray-500">2.5 ft</p> </div> <div class="space-y-3"> <label for="wallWidth" class="block text-sm font-medium text-gray-700">Wall Width Above Toilet (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="3.0" step="0.1" min="1.5" max="5" value="3.0" required> </div> <input type="range" id="wallWidthRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="1.5" max="5" step="0.1" value="3.0"> <p id="wallWidthValue" class="text-sm text-gray-500">3.0 ft</p> </div> </div> <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="space-y-3"> <label for="lightingClearance" class="block text-sm font-medium text-gray-700">Lighting Clearance Above (ft)</label> <div class="relative flex items-center"> <i data-lucide="lightbulb" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="lightingClearance" 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="0.5" step="0.1" min="0.3" max="1" value="0.5" required> </div> <input type="range" id="lightingClearanceRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="0.3" max="1" step="0.1" value="0.5"> <p id="lightingClearanceValue" class="text-sm text-gray-500">0.5 ft</p> </div> <div class="space-y-3"> <label for="plumbingClearance" class="block text-sm font-medium text-gray-700">Plumbing Clearance Behind (ft)</label> <div class="relative flex items-center"> <i data-lucide="pipe" class="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i> <input type="number" id="plumbingClearance" 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="0.3" step="0.1" min="0.2" max="0.5" value="0.3" required> </div> <input type="range" id="plumbingClearanceRange" class="range-input w-full h-2 bg-gray-200 rounded-lg cursor-pointer" min="0.2" max="0.5" step="0.1" value="0.3"> <p id="plumbingClearanceValue" class="text-sm text-gray-500">0.3 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 Over-the-Toilet Shelf 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 Over-the-Toilet Shelf 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 standard bathroom dimensions and shelving installation guidelines.</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="shelf" class="mr-3 text-blue-500 h-6 w-6"></i> Interactive Over-the-Toilet Shelf Visualization </h3> <div class="relative w-full h-96 bg-gray-200 rounded-xl overflow-hidden shadow-lg"> <canvas id="shelfCanvas" class="w-full h-full"></canvas> </div> <p class="text-sm text-gray-600 mt-4">Visualization showing the shelf above the toilet with lighting and plumbing clearances.</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 Over-the-Toilet Shelf Installation </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> Ensure 0.3-1 ft above for lighting and 0.2-0.5 ft behind for plumbing.</span> </li> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Width:</strong> Shelf should be wider than the toilet but fit within the wall space.</span> </li> <li class="flex items-start"> <i data-lucide="check" class="mr-2 text-green-500 h-5 w-5"></i> <span><strong>Height:</strong> Position shelf to avoid headspace interference (≥6.5 ft above floor).</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 to wall studs or use appropriate anchors.</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> Ensure easy access to toilet tank for maintenance.</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('shelfWidth', 'shelfWidthRange', 'shelfWidthValue'); syncInputs('shelfDepth', 'shelfDepthRange', 'shelfDepthValue'); syncInputs('shelfHeight', 'shelfHeightRange', 'shelfHeightValue'); syncInputs('toiletWidth', 'toiletWidthRange', 'toiletWidthValue'); syncInputs('toiletDepth', 'toiletDepthRange', 'toiletDepthValue'); syncInputs('toiletHeight', 'toiletHeightRange', 'toiletHeightValue'); syncInputs('wallWidth', 'wallWidthRange', 'wallWidthValue'); syncInputs('lightingClearance', 'lightingClearanceRange', 'lightingClearanceValue'); syncInputs('plumbingClearance', 'plumbingClearanceRange', 'plumbingClearanceValue'); // Form Submission document.getElementById('shelfFitForm').addEventListener('submit', function (e) { e.preventDefault(); calculateShelfFit(); }); function calculateShelfFit() { const shelfWidth = parseFloat(document.getElementById('shelfWidth').value); const shelfDepth = parseFloat(document.getElementById('shelfDepth').value); const shelfHeight = parseFloat(document.getElementById('shelfHeight').value); const toiletWidth = parseFloat(document.getElementById('toiletWidth').value); const toiletDepth = parseFloat(document.getElementById('toiletDepth').value); const toiletHeight = parseFloat(document.getElementById('toiletHeight').value); const wallWidth = parseFloat(document.getElementById('wallWidth').value); const lightingClearance = parseFloat(document.getElementById('lightingClearance').value); const plumbingClearance = parseFloat(document.getElementById('plumbingClearance').value); if (!shelfWidth || !shelfDepth || !shelfHeight || !toiletWidth || !toiletDepth || !toiletHeight || !wallWidth || !lightingClearance || !plumbingClearance || shelfWidth < 1 || shelfDepth < 0.5 || shelfHeight < 1 || toiletWidth < 1 || toiletDepth < 1.5 || toiletHeight < 1 || wallWidth < 1.5 || lightingClearance < 0.3 || plumbingClearance < 0.2) { alert('Please enter valid values (Shelf Width ≥ 1 ft, Depth ≥ 0.5 ft, Height ≥ 1 ft, Toilet Width ≥ 1 ft, Depth ≥ 1.5 ft, Height ≥ 1 ft, Wall Width ≥ 1.5 ft, Lighting Clearance ≥ 0.3 ft, Plumbing Clearance ≥ 0.2 ft).'); return; } // Calculate fit const widthFit = shelfWidth >= toiletWidth && shelfWidth <= wallWidth; // Shelf wider than toilet, fits within wall const depthFit = shelfDepth + plumbingClearance <= toiletDepth + 0.5; // Depth + plumbing clearance fits within toilet depth + buffer const heightFit = (toiletHeight + shelfHeight + lightingClearance) <= 6.5; // Total height ≤ 6.5 ft (standard headspace) const overallFit = widthFit && depthFit && heightFit ? 'Yes' : 'No'; // Calculate clearances const widthClearance = wallWidth - shelfWidth; const depthClearance = (toiletDepth + 0.5) - (shelfDepth + plumbingClearance); const heightClearance = 6.5 - (toiletHeight + shelfHeight + lightingClearance); // 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">Shelf Dimensions</p> <p class="text-lg">${shelfWidth.toFixed(1)} x ${shelfDepth.toFixed(1)} x ${shelfHeight.toFixed(1)} ft</p> </div> <div> <p class="font-medium text-gray-700">Toilet Dimensions</p> <p class="text-lg">${toiletWidth.toFixed(1)} x ${toiletDepth.toFixed(1)} x ${toiletHeight.toFixed(1)} ft</p> </div> <div> <p class="font-medium text-gray-700">Wall Width Above Toilet</p> <p class="text-lg">${wallWidth.toFixed(1)} ft</p> </div> <div> <p class="font-medium text-gray-700">Clearances</p> <p class="text-lg">Lighting: ${lightingClearance.toFixed(1)} ft, Plumbing: ${plumbingClearance.toFixed(1)} ft</p> </div> <div> <p class="font-medium text-gray-700">Fit Assessment</p> <p class="text-lg ${overallFit === 'Yes' ? 'text-green-600' : 'text-red-600'} font-semibold"> ${overallFit === 'Yes' ? 'Perfect Fit' : 'May Not Fit Properly'} </p> <p class="text-sm text-gray-600">${ overallFit === 'Yes' ? `The shelf fits above the toilet with ${widthClearance.toFixed(1)} ft width clearance, ${depthClearance.toFixed(1)} ft depth clearance, and ${heightClearance.toFixed(1)} ft height clearance.` : `Issues: ${ !widthFit ? `Shelf width issue (need ≥${toiletWidth.toFixed(1)} ft and ≤${wallWidth.toFixed(1)} ft, have ${shelfWidth.toFixed(1)} ft). ` : '' }${ !depthFit ? `Insufficient depth clearance (need ≤${(toiletDepth + 0.5).toFixed(1)} ft, have ${shelfDepth + plumbingClearance.toFixed(1)} ft). ` : '' }${ !heightFit ? `Excessive height (total ≤6.5 ft, have ${(toiletHeight + shelfHeight + lightingClearance).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> Ensure the shelf is securely mounted and allows access to the toilet tank for maintenance.</p> </div> `; document.getElementById('resultOutput').innerHTML = output; document.getElementById('resultSection').classList.remove('hidden'); // Draw visualization drawVisualization(shelfWidth, shelfDepth, shelfHeight, toiletWidth, toiletDepth, toiletHeight, wallWidth, lightingClearance, plumbingClearance); // Setup PDF download setupPdfDownload(shelfWidth, shelfDepth, shelfHeight, toiletWidth, toiletDepth, toiletHeight, wallWidth, lightingClearance, plumbingClearance, overallFit, widthClearance, depthClearance, heightClearance); } function drawVisualization(shelfWidth, shelfDepth, shelfHeight, toiletWidth, toiletDepth, toiletHeight, wallWidth, lightingClearance, plumbingClearance) { const canvas = document.getElementById('shelfCanvas'); 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 = Math.min(canvas.width / (wallWidth * 1.5), canvas.height / 7); // Scale to fit 6.5 ft height const shelfW = shelfWidth * scale; const shelfD = shelfDepth * scale; const shelfH = shelfHeight * scale; const toiletW = toiletWidth * scale; const toiletD = toiletDepth * scale; const toiletH = toiletHeight * scale; const wallW = wallWidth * scale; const lightingC = lightingClearance * scale; const plumbingC = plumbingClearance * scale; // Draw background (bathroom wall) 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 floor ctx.fillStyle = 'rgba(120, 113, 108, 0.2)'; ctx.fillRect(0, canvas.height * 0.7, canvas.width, canvas.height * 0.3); // Draw toilet (side view) ctx.fillStyle = '#4b5563'; const toiletX = (canvas.width - toiletW) / 2; const toiletY = canvas.height - toiletH; ctx.fillRect(toiletX, toiletY, toiletW, toiletH); // Tank pipe ctx.fillStyle = '#6b7280'; ctx.fillRect(toiletX + toiletW * 0.7, toiletY - plumbingC, toiletW * 0.1, plumbingC); // Draw shelf (side view) ctx.shadowColor = 'rgba(0, 0, 0, 0.4)'; ctx.shadowBlur = 15; ctx.shadowOffsetX = 8; ctx.shadowOffsetY = 8; ctx.fillStyle = '#0284c7'; const shelfX = (canvas.width - shelfW) / 2; const shelfY = toiletY - shelfH - lightingC; ctx.fillRect(shelfX, shelfY, shelfW, shelfD); // Draw shelf texture const shelfGradient = ctx.createLinearGradient(shelfX, shelfY, shelfX + shelfW, shelfY + shelfD); shelfGradient.addColorStop(0, 'rgba(255, 255, 255, 0.15)'); shelfGradient.addColorStop(1, 'rgba(255, 255, 255, 0.05)'); ctx.fillStyle = shelfGradient; ctx.fillRect(shelfX + 5, shelfY + 5, shelfW - 10, shelfD - 10); // Draw lighting clearance ctx.fillStyle = 'rgba(34, 197, 94, 0.3)'; ctx.fillRect(shelfX, shelfY - lightingC, shelfW, lightingC); // Draw text ctx.shadowColor = 'transparent'; ctx.fillStyle = '#ffffff'; ctx.font = 'bold 18px Poppins'; ctx.textAlign = 'center'; ctx.fillText(`Shelf (${shelfWidth.toFixed(1)} x ${shelfHeight.toFixed(1)} ft)`, shelfX + shelfW / 2, shelfY + shelfD / 2); ctx.fillStyle = '#1e40af'; ctx.fillText(`Toilet (${toiletWidth.toFixed(1)} x ${toiletHeight.toFixed(1)} ft)`, toiletX + toiletW / 2, toiletY + toiletH / 2); ctx.font = '14px Poppins'; ctx.fillStyle = '#4b5563'; ctx.fillText(`Wall: ${wallWidth.toFixed(1)} ft, Lighting: ${lightingClearance.toFixed(1)} ft, Plumbing: ${plumbingClearance.toFixed(1)} ft`, canvas.width / 2, canvas.height - 30); } function setupPdfDownload(shelfWidth, shelfDepth, shelfHeight, toiletWidth, toiletDepth, toiletHeight, wallWidth, lightingClearance, plumbingClearance, overallFit, widthClearance, depthClearance, 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 - Over-the-Toilet Shelf Fit Assessment`, 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 Over-the-Toilet Shelf Fit Assessment`, 20, 40); doc.setFontSize(11); doc.text(`Shelf Dimensions: ${shelfWidth.toFixed(1)} x ${shelfDepth.toFixed(1)} x ${shelfHeight.toFixed(1)} ft`, 20, 50); doc.text(`Toilet Dimensions: ${toiletWidth.toFixed(1)} x ${toiletDepth.toFixed(1)} x ${toiletHeight.toFixed(1)} ft`, 20, 58); doc.text(`Wall Width Above Toilet: ${wallWidth.toFixed(1)} ft`, 20, 66); doc.text(`Clearances: Lighting: ${lightingClearance.toFixed(1)} ft, Plumbing: ${plumbingClearance.toFixed(1)} ft`, 20, 74); doc.text(`Fit Assessment: ${overallFit === 'Yes' ? 'Perfect Fit' : 'May Not Fit Properly'}`, 20, 82); doc.text(`Clearances: ${widthClearance.toFixed(1)} ft (width), ${depthClearance.toFixed(1)} ft (depth), ${heightClearance.toFixed(1)} ft (height)`, 20, 90); doc.text(`Recommendation: ${ overallFit === 'Yes' ? `The shelf fits well above the toilet without interference.` : `Consider a smaller shelf or adjust bathroom layout.` }`, 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: Ensure 0.3-1 ft above for lighting and 0.2-0.5 ft behind for plumbing.', 20, 118); doc.text('• Width: Shelf should be wider than the toilet but fit within the wall space.', 20, 126); doc.text('• Height: Position shelf to avoid headspace interference (≤6.5 ft total).', 20, 134); doc.text('• Stability: Secure to wall studs or use appropriate anchors.', 20, 142); doc.text('• Accessibility: Ensure easy access to toilet tank for maintenance.', 20, 150); doc.save(`HomeFit_Over_the_Toilet_Shelf_Fit_Assessment.pdf`); }; } </script>