test1 / index.html
MarkTheArtist's picture
Add 3 files
118d76c verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Laser Cut Box Designer</title>
<style>
body { font-family: sans-serif; margin: 20px; }
.controls { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; max-width: 600px; margin-bottom: 20px; }
.controls label { display: block; margin-bottom: 5px; }
.controls input { width: 100%; padding: 8px; box-sizing: border-box; }
#preview-container { border: 1px solid #ccc; width: 100%; max-width: 800px; height: 500px; margin-top: 20px; overflow: auto; }
#preview-svg { width: 100%; height: 100%; }
button { padding: 10px 15px; margin-right: 10px; cursor: pointer; }
</style>
</head>
<body>
<h1>Laser Cut Box Designer</h1>
<div class="controls">
<div>
<label for="width">Width (in):</label>
<input type="number" id="width" value="4" step="0.1">
</div>
<div>
<label for="depth">Depth (in):</label>
<input type="number" id="depth" value="3" step="0.1">
</div>
<div>
<label for="height">Height (in):</label>
<input type="number" id="height" value="2" step="0.1">
</div>
<div>
<label for="materialThickness">Material Thickness (in):</label>
<input type="number" id="materialThickness" value="0.125" step="0.001">
</div>
<div>
<label for="kerf">Kerf (in, optional):</label>
<input type="number" id="kerf" value="0.005" step="0.001">
</div>
<div>
<label for="boxType">Box Type:</label>
<input type="radio" id="closedBox" name="boxType" value="closed" checked> <label for="closedBox">Closed Box</label><br>
<input type="radio" id="openBox" name="boxType" value="open"> <label for="openBox">Open Box</label>
</div>
<h3>Face Spacing (0 for standard wall, >0 for gap/offset)</h3>
<div>
<label for="spacingTop">Top Face Spacing (in):</label>
<input type="number" id="spacingTop" value="0" step="0.1">
</div>
<div>
<label for="spacingBottom">Bottom Face Spacing (in):</label>
<input type="number" id="spacingBottom" value="0" step="0.1">
</div>
<div>
<label for="spacingFront">Front Face Spacing (in):</label>
<input type="number" id="spacingFront" value="0" step="0.1">
</div>
<div>
<label for="spacingBack">Back Face Spacing (in):</label>
<input type="number" id="spacingBack" value="0" step="0.1">
</div>
<div>
<label for="spacingLeft">Left Face Spacing (in):</label>
<input type="number" id="spacingLeft" value="0" step="0.1">
</div>
<div>
<label for="spacingRight">Right Face Spacing (in):</label>
<input type="number" id="spacingRight" value="0" step="0.1">
</div>
</div>
<button id="calculateBtn">Calculate & Preview Design</button>
<button id="exportSvgBtn">Export as SVG</button>
<button id="exportPdfBtn">Export as PDF</button>
<h2>Design Preview:</h2>
<div id="preview-container">
<svg id="preview-svg" viewBox="0 0 800 500"></svg>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script>
// Placeholder for box generation logic (this is the complex part)
function generateBoxSVG(width, depth, height, materialThickness, kerf, boxType, spacing) {
let svgContent = '';
const fingerLength = materialThickness * 2; // Example finger length
const numFingers = 5; // Example number of fingers (you'd calculate this dynamically)
// For simplicity, let's just draw rectangles representing the faces
// In a real application, you'd calculate precise finger joint paths
// Front face (example)
svgContent += `<rect x="0" y="0" width="${width}" height="${height}" fill="lightblue" stroke="black" stroke-width="0.01"/>`;
// Add finger joints here based on calculations
// Top face (example - adjusted for spacing if applicable)
let topY = height + 1; // Some spacing for layout
if (boxType === 'closed' || spacing.top === 0) {
// For a closed box, draw the top. If spacingTop is 0, draw it.
svgContent += `<rect x="0" y="${topY}" width="${width}" height="${depth}" fill="lightgreen" stroke="black" stroke-width="0.01"/>`;
} else if (spacing.top > 0) {
// If there's spacing, you might draw a visual indicator or just omit the piece
// For this example, we'll just omit it if spacing is greater than 0 for "open"
// In a real design, spacing might affect how joints are cut or if a face is present.
}
// ... repeat for other faces (back, left, right, bottom)
// The "spacing" input would modify *how* each face is drawn or if it's drawn at all.
// For example, if spacingTop is > 0 and it's an "open" box, you might completely omit the top face.
// If it's a closed box and spacingTop is > 0, it means there's a gap between the top and the walls.
// This is the most complex part of the user's request and requires careful geometric calculation for each joint.
return svgContent;
}
function calculateAndPreview() {
const width = parseFloat(document.getElementById('width').value);
const depth = parseFloat(document.getElementById('depth').value);
const height = parseFloat(document.getElementById('height').value);
const materialThickness = parseFloat(document.getElementById('materialThickness').value);
const kerf = parseFloat(document.getElementById('kerf').value);
const boxType = document.querySelector('input[name="boxType"]:checked').value;
const spacing = {
top: parseFloat(document.getElementById('spacingTop').value),
bottom: parseFloat(document.getElementById('spacingBottom').value),
front: parseFloat(document.getElementById('spacingFront').value),
back: parseFloat(document.getElementById('spacingBack').value),
left: parseFloat(document.getElementById('spacingLeft').value),
right: parseFloat(document.getElementById('spacingRight').value),
};
if (isNaN(width) || isNaN(depth) || isNaN(height) || isNaN(materialThickness) || isNaN(kerf)) {
alert("Please enter valid numeric dimensions.");
return;
}
const svgElement = document.getElementById('preview-svg');
// Clear previous design
svgElement.innerHTML = '';
const generatedSVG = generateBoxSVG(width, depth, height, materialThickness, kerf, boxType, spacing);
svgElement.innerHTML = generatedSVG; // This is a simplified example
// For a real application, you'd use a dedicated SVG library
// For example, with Maker.js:
/*
const makerjs = require('makerjs'); // if using Node.js or a bundler
// Or if directly in browser: makerjs.models.something...
const boxModel = new makerjs.models.Bolt(width, depth, height, materialThickness); // (example)
const svgOutput = makerjs.exporter.toSVG(boxModel);
svgElement.innerHTML = svgOutput;
*/
}
function exportSVG() {
const svgElement = document.getElementById('preview-svg');
const svgData = new XMLSerializer().serializeToString(svgElement);
const blob = new Blob([svgData], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'laser_cut_box.svg';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
function exportPDF() {
const width = parseFloat(document.getElementById('width').value);
const depth = parseFloat(document.getElementById('depth').value);
const height = parseFloat(document.getElementById('height').value);
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
// Example: Add text and a simple rectangle to the PDF
doc.text("Laser Cut Box Design", 10, 10);
doc.text(`Dimensions: ${width}x${depth}x${height} inches`, 10, 20);
// You would draw the actual box panels on the PDF here,
// translating your SVG drawing logic to jsPDF commands.
// This is more involved than just converting the SVG element directly
// unless you use a library like html2pdf.js to capture the whole HTML.
// A more robust solution might involve:
// 1. Get the bounding box of your generated SVG content to scale it appropriately.
// 2. Iterate through your calculated panel shapes and draw them using jsPDF's drawing primitives (rect, line, etc.).
// Alternatively, if html2pdf.js is used:
/*
const element = document.getElementById('preview-container'); // Or the SVG element itself
html2pdf().from(element).save('laser_cut_box.pdf');
*/
// For this simple example, we'll just save a blank PDF with some text.
doc.save('laser_cut_box.pdf');
}
document.getElementById('calculateBtn').addEventListener('click', calculateAndPreview);
document.getElementById('exportSvgBtn').addEventListener('click', exportSVG);
document.getElementById('exportPdfBtn').addEventListener('click', exportPDF);
// Initial preview on load
calculateAndPreview();
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MarkTheArtist/test1" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>