Remote Control Vehicle Spec Sheet Generator
General Specifications
Chassis & Dimensions
Motor & ESC
Battery & Energy
Control System
Telemetry & Safety
What data is transmitted back (e.g., battery voltage, signal strength)?
How does the vehicle respond to signal loss?
Review the final calculated specifications for your RC vehicle.
Click "Next" or "Previous" to refresh this preview.
Dimensions: ${escapeHTML(data.length)} mm (L) x ${escapeHTML(data.width)} mm (W)
2. Powertrain
Motor Type: ${escapeHTML(data.motorType)}
Max Current: ${escapeHTML(data.maxCurrent)} A
ESC: ${escapeHTML(data.esc)}
Nominal Voltage: ${escapeHTML(data.voltage)} V
Capacity: ${escapeHTML(data.capacity)} mAh
Estimated Runtime: ${escapeHTML(data.runtime)} minutes
3. Control & Telemetry
Protocol/Freq: ${escapeHTML(data.protocol)}
Channels: ${escapeHTML(data.channels)}
Max Range: ${escapeHTML(data.range)} meters
Telemetry: ${escapeHTML(data.telemetry)}
Fail-Safe: ${escapeHTML(data.failsafe)}
`; }; const downloadTxt = () => { const data = getSpecData(); let content = `RC VEHICLE SPEC SHEET: ${data.name.toUpperCase()}\n`; content += "======================================================\n\n"; content += `SUMMARY METRICS:\n`; content += ` - Max Power: ${data.maxPower} W\n`; content += ` - Energy Capacity: ${data.energyCapacity} Wh\n`; content += ` - Power-to-Mass: ${data.powerToMassRatio} W/kg\n\n`; content += "1. GENERAL & CHASSIS\n"; content += "--------------------\n"; content += `Name: ${data.name}\n`; content += `Type: ${data.type}\n`; content += `Scale: ${data.scale}\n`; content += `Mass (RTR): ${data.mass} g\n`; content += `Material: ${data.material}\n`; content += `Dimensions: ${data.length}mm x ${data.width}mm\n\n`; content += "2. POWERTRAIN\n"; content += "-------------\n"; content += `Motor: ${data.motorType}\n`; content += `Max Current: ${data.maxCurrent} A\n`; content += `ESC: ${data.esc}\n`; content += `Voltage: ${data.voltage} V\n`; content += `Capacity: ${data.capacity} mAh\n`; content += `Runtime (Est.): ${data.runtime} min\n\n`; content += "3. CONTROL & TELEMETRY\n"; content += "----------------------\n"; content += `Protocol: ${data.protocol} (${data.channels} ch)\n`; content += `Max Range: ${data.range} m\n`; content += `Telemetry: ${data.telemetry}\n`; content += `Fail-Safe: ${data.failsafe}\n`; const blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = `${data.name.replace(/ /g, '_')}_SpecSheet.txt`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(a.href); }; const downloadPDF = () => { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('Error: jsPDF library not loaded.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); const data = getSpecData(); const margin = 20; const pageWidth = doc.internal.pageSize.getWidth(); const usableWidth = pageWidth - (margin * 2); let yPos = 20; const addWrappedText = (text, options = {}) => { const { size = 11, style = 'normal', color = [52, 73, 94], isHeading = false, label = '' } = options; doc.setFontSize(size); doc.setFont(undefined, style); doc.setTextColor(color[0], color[1], color[2]); let textToSplit = text; if (isHeading) { yPos += 5; doc.text(textToSplit, margin, yPos); doc.setDrawColor(224, 224, 224); doc.line(margin, yPos + 1, pageWidth - margin, yPos + 1); yPos += 8; return; } if (label) { doc.setFont(undefined, 'bold'); doc.text(`${label}:`, margin, yPos); doc.setFont(undefined, style); doc.text(textToSplit, margin + 30, yPos); yPos += 6; } else { const splitText = doc.splitTextToSize(textToSplit, usableWidth); doc.text(splitText, margin, yPos); yPos += (splitText.length * 6) + 4; } }; // --- Build PDF Document --- // Title doc.setFontSize(18); doc.setFont(undefined, 'bold'); doc.setTextColor(44, 62, 80); doc.text(`RC Vehicle Spec Sheet: ${data.name}`, pageWidth / 2, yPos, { align: 'center' }); yPos += 10; // Metrics Table const metricsHead = [['Metric', 'Value', 'Unit']]; const metricsBody = [ ['Max Power', data.maxPower, 'W'], ['Energy Capacity', data.energyCapacity, 'Wh'], ['Power/Mass Ratio', data.powerToMassRatio, 'W/kg'] ]; doc.autoTable({ startY: yPos, head: metricsHead, body: metricsBody, theme: 'striped', headStyles: { fillColor: [231, 76, 60], textColor: [255, 255, 255], fontSize: 10 }, styles: { fontSize: 9, cellPadding: 3 }, columnStyles: { 1: { fontStyle: 'bold' } }, margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous ? (doc.autoTable.previous.finalY + 10) : (yPos + 30); // 1. General & Chassis addWrappedText("1. General & Chassis", { size: 14, isHeading: true, color: [44, 62, 80] }); addWrappedText(data.type, { label: "Type" }); addWrappedText(data.scale, { label: "Scale" }); addWrappedText(`${data.mass} grams (${(parseFloat(data.mass) / 1000).toFixed(2)} kg)`, { label: "Mass (RTR)" }); addWrappedText(data.material, { label: "Material" }); addWrappedText(`${data.length} mm x ${data.width} mm`, { label: "Dimensions (L x W)" }); // 2. Powertrain addWrappedText("2. Powertrain", { size: 14, isHeading: true, color: [44, 62, 80] }); addWrappedText(data.motorType, { label: "Motor Type" }); addWrappedText(`${data.maxCurrent} A`, { label: "Max Current" }); addWrappedText(data.esc, { label: "ESC" }); addWrappedText(`${data.voltage} V`, { label: "Voltage" }); addWrappedText(`${data.capacity} mAh`, { label: "Capacity" }); addWrappedText(`${data.runtime} min`, { label: "Runtime (Est.)" }); // 3. Control & Telemetry addWrappedText("3. Control & Telemetry", { size: 14, isHeading: true, color: [44, 62, 80] }); addWrappedText(`${data.protocol} (${data.channels} ch)`, { label: "Protocol/Channels" }); addWrappedText(`${data.range} m`, { label: "Max Range" }); addWrappedText(data.telemetry, { label: "Telemetry" }); addWrappedText(data.failsafe, { label: "Fail-Safe" }); doc.save(`${data.name.replace(/ /g, '_')}_SpecSheet.pdf`); }; // --- Event Listeners --- // Tab Buttons tabButtons.forEach((btn, index) => { btn.addEventListener('click', () => showTab(index + 1)); }); // Next/Prev Navigation nextBtn.addEventListener('click', () => showTab(currentTab + 1)); prevBtn.addEventListener('click', () => showTab(currentTab - 1)); // Tab 4 Actions downloadPdfBtn.addEventListener('click', downloadPDF); downloadTxtBtn.addEventListener('click', downloadTxt); // --- Initialization --- showTab(1); });