hyster Posted August 22, 2024 Share Posted August 22, 2024 The code works fine, the help i need is with the design/layout as im far from artistic and do not know how to make it look good, only way i can do it is with massive trial and error and hit something by accident. i think im close but ......... <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Marks of Excellence Generator</title> <style> body { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; margin: 0; font-family: Arial, sans-serif; background-color: #f0f0f0; } h1 { margin-bottom: 20px; } .info-box { display: flex; justify-content: center; align-items: center; width: 100%; max-width: 700px; background-color: #fff; padding: 15px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); margin-bottom: 20px; text-align: left; } .controls { display: flex; flex-direction: column; align-items: center; margin-bottom: 20px; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } .section-container { display: flex; background-color: #ff; gap: 20px; /* Space between sections */ margin-bottom: 20px; } .section { display: flex; flex-direction: column; gap: 10px; /* Space between items in each section */ padding: 15px; background-color: #f9f9f9; border-radius: 8px; box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); width: 300px; text-align: center; /* Center align text in section */ } .section label { margin-right: 5px; } .section input[type="number"], .section input[type="color"] { margin-bottom: 5px; width: 80px; } .color-picker-container { display: flex; justify-content: center; gap: 10px; /* Space between color pickers */ margin-bottom: 10px; } .size-container { display: flex; justify-content: center; gap: 10px; /* Space between size inputs */ } .controls button { margin-top: 10px; padding: 10px 20px; border: none; border-radius: 4px; background-color: #007BFF; color: #fff; cursor: pointer; } .controls button:hover { background-color: #0056b3; } #canvas-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; /* Space between images */ } </style> <!-- JSZip library --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> </head> <body> <h1>Customizable Marks of Excellence Generator</h1> <br /> <div class="info-box"> <ul> <li> If you just want a shape, set Stripe Width & Border Size to 0.</li> <li> If you want a bar behind shape adjust height & width of stripe.</li> <li> Select options or preset, Click Generate to preview. Download when happy. </li> <li>Unzip. Keep folder structure</li> <li> Convert .png to .dds (Can do it <a href="https://imagetostl.com/convert/file/png/to/dds#convert" target="_blank">here</a> online). Replace .png with the .dds </li> <li>Rezip with compression set to "store".</li> <li>Change .zip to .wotmod then place in C:\Games\World_of_Tanks_EU\mods\<span style="color: red">{Ver num}</span>\ . <li>Import/Export can be used to save a configuration to alter later</li> </ul> </div> <div class="controls"> <div class="section-container"> <div class="section"> <div><b>Stripes</b></div> <div> <div class="color-picker-container"> <label for="stripeColor">Color:</label> <input type="color" id="stripeColor" value="#ffffff" /> <label for="borderColor">Border Color:</label> <input type="color" id="borderColor" value="#000000" /> </div> </div> <div class="size-container"> <div> <label for="stripeWidth">Width:</label> <input type="number" id="stripeWidth" value="60" min="1" max="256" /> </div> <div> <label for="stripeHeight">Height:</label> <input type="number" id="stripeHeight" value="245" min="1" max="256" /> </div> <div> <label for="borderSize">Border Size:</label> <input type="number" id="borderSize" value="10" min="0" max="10" /> </div> </div> </div> <div class="section"> <div><b>Shape</b></div> <div> <label for="shape">Shape:</label> <select id="shape"> <option value="none">None</option> <option value="circle">Circle</option> <option value="square">Square</option> <option value="triangle">Triangle</option> <option value="4-point-star">4-Point Star</option> <option value="star" selected>5-Point Star</option> <!-- Set this option as selected --> <option value="6-point-star">6-Point Star</option> <option value="pentagon">Pentagon</option> <option value="hexagon">Hexagon</option> <option value="diamond">Diamond</option> </select> </div> <div> <div class="color-picker-container"> <label for="shapeColor">Color:</label> <input type="color" id="shapeColor" value="#FF0000" /> <label for="shapeBorderColor">Border Color:</label> <input type="color" id="shapeBorderColor" value="#000000" /> </div> </div> <div class="size-container"> <div> <label for="shapeSize">Size:</label> <input type="number" id="shapeSize" value="35" min="1" max="256" /> </div> <div> <label for="shapeBorderSize">Border Size:</label> <input type="number" id="shapeBorderSize" value="5" min="0" max="10" /> </div> </div> </div> </div> <div class="section-container"> <div class="section"> <div><b>Presets</b></div> <div> <div> <label for="presetSelect">Stripes:</label> <select id="presetSelect"> <option value="">Select a preset</option> <option value="stripe 1">Stripe 1</option> <option value="stripe 2">Stripe 2</option> <option value="stripe 3">Stripe 3</option> <option value="shape 1">Shape 1</option> <option value="shape 2">Shape 2</option> <option value="shape 3">Shape 3</option> <!-- Add more options corresponding to your presets --> </select> <div> <input type="file" id="import-file" accept="application/json" style="display: none;" /> </div> <div><br> <button id="import-button">Import Settings</button> <button id="export-button">Export Settings</button> </div> </div> <div class="size-container"></div> </div> </div> <div class="section" style="width: 300px"> <div><b>Background</b></div> <div> <label for="backgroundColor">Color:</label> <input type="color" id="backgroundColor" value="#ffff00" <label for="transparentBackground">Transparent:</label> <input type="checkbox" id="transparentBackground" /> </div> <div> <button id="generate-button">Generate</button> <button id="download-button">Download All</button> </div> </div> </div> </div> <div id="canvas-container"></div> <script> document.getElementById('import-button').addEventListener('click', function() { document.getElementById('import-file').click(); }); document.getElementById('import-file').addEventListener('change', importSettings); function importSettings(event) { const file = event.target.files[0]; if (file && file.type === 'application/json') { const reader = new FileReader(); reader.onload = function(e) { const settings = JSON.parse(e.target.result); document.getElementById('stripeColor').value = settings.stripeColor; document.getElementById('borderColor').value = settings.borderColor; document.getElementById('stripeWidth').value = settings.stripeWidth; document.getElementById('stripeHeight').value = settings.stripeHeight; document.getElementById('borderSize').value = settings.borderSize; document.getElementById('shape').value = settings.shape; document.getElementById('shapeSize').value = settings.shapeSize; document.getElementById('shapeColor').value = settings.shapeColor; document.getElementById('shapeBorderColor').value = settings.shapeBorderColor; document.getElementById('shapeBorderSize').value = settings.shapeBorderSize; document.getElementById('backgroundColor').value = settings.backgroundColor; document.getElementById('transparentBackground').checked = settings.transparentBackground; }; reader.readAsText(file); } else { alert('Please upload a valid JSON file.'); } } document.getElementById('export-button').addEventListener('click', exportSettings); function exportSettings() { const settings = { stripeColor: document.getElementById('stripeColor').value, borderColor: document.getElementById('borderColor').value, stripeWidth: parseInt(document.getElementById('stripeWidth').value), stripeHeight: parseInt(document.getElementById('stripeHeight').value), borderSize: parseInt(document.getElementById('borderSize').value), shape: document.getElementById('shape').value, shapeSize: parseInt(document.getElementById('shapeSize').value), shapeColor: document.getElementById('shapeColor').value, shapeBorderColor: document.getElementById('shapeBorderColor').value, shapeBorderSize: parseInt(document.getElementById('shapeBorderSize').value), backgroundColor: document.getElementById('backgroundColor').value, transparentBackground: document.getElementById('transparentBackground').checked }; const blob = new Blob([JSON.stringify(settings, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'settings.json'; a.click(); URL.revokeObjectURL(url); } document.getElementById('presetSelect').addEventListener('change', function() { const selectedPreset = this.value; if (selectedPreset && presets[selectedPreset]) { const presetValues = presets[selectedPreset]; document.getElementById('stripeColor').value = presetValues.stripeColor; document.getElementById('borderColor').value = presetValues.borderColor; document.getElementById('stripeWidth').value = presetValues.stripeWidth; document.getElementById('stripeHeight').value = presetValues.stripeHeight; document.getElementById('borderSize').value = presetValues.borderSize; document.getElementById('shape').value = presetValues.shape; document.getElementById('shapeSize').value = presetValues.shapeSize; document.getElementById('shapeColor').value = presetValues.shapeColor; document.getElementById('shapeBorderColor').value = presetValues.shapeBorderColor; document.getElementById('shapeBorderSize').value = presetValues.shapeBorderSize; document.getElementById('backgroundColor').value = presetValues.backgroundColor; document.getElementById('transparentBackground').checked = presetValues.transparentBackground; // Optionally trigger the generation of the image with the new preset values generateMarks(); } }); const presets = { "stripe 1": { stripeColor: "#FFFFFF", borderColor: "#000000", stripeWidth: 60, stripeHeight: 245, borderSize: 10, shape: "none", shapeSize: 40, shapeColor: "#FF0000", shapeBorderColor: "#000000", shapeBorderSize: 2, backgroundColor: "#000000", transparentBackground: true }, "shape 1": { stripeColor: "#00FF00", borderColor: "#000000", stripeWidth: 100, stripeHeight: 60, borderSize: 0, shape: "star", shapeSize: 30, shapeColor: "#0000FF", shapeBorderColor: "#FFFFFF", shapeBorderSize: 3, backgroundColor: "#FFFFFF", transparentBackground: true }, "stripe 2": { stripeColor: "#FF0000", borderColor: "#000000", stripeWidth: 60, stripeHeight: 245, borderSize: 10, shape: "diamond", shapeSize: 40, shapeColor: "#00ff00", shapeBorderColor: "#FFFFFF", shapeBorderSize: 5, backgroundColor: "#FFFFFF", transparentBackground: true }, "shape 2": { stripeColor: "#FF0000", borderColor: "#000000", stripeWidth: 0, stripeHeight: 0, borderSize: 0, shape: "pentagon", shapeSize: 40, shapeColor: "#00ff00", shapeBorderColor: "#000000", shapeBorderSize: 5, backgroundColor: "#FFFFFF", transparentBackground: true }, "shape 3": { stripeColor: "#FF0000", borderColor: "#000000", stripeWidth: 100, stripeHeight: 30, borderSize: 0, shape: "4-point-star", shapeSize: 35, shapeColor: "#00ff00", shapeBorderColor: "#000000", shapeBorderSize: 5, backgroundColor: "#FFFFFF", transparentBackground: true }, // Add more presets as needed "stripe 3": { "stripeColor": "#ffffff", "borderColor": "#000000", "stripeWidth": 60, "stripeHeight": 245, "borderSize": 0, "shape": "none", "shapeSize": 40, "shapeColor": "#00ff00", "shapeBorderColor": "#ffffff", "shapeBorderSize": 5, "backgroundColor": "#ffffff", "transparentBackground": true } }; const imgSize = 256; const zip = new JSZip(); // Initialize the ZIP object // Folder path inside the ZIP file const folderPath = "res/gui/maps/vehicles/decals/insignia"; function drawShape(ctx, shape, x, y, size, color, borderColor, borderSize) { ctx.fillStyle = color; ctx.strokeStyle = borderColor; ctx.lineWidth = borderSize; ctx.beginPath(); switch (shape) { case "circle": ctx.arc(x, y, size, 0, 2 * Math.PI); break; case "square": ctx.rect(x - size / 2, y - size / 2, size, size); break; case "triangle": ctx.moveTo(x, y - size); ctx.lineTo(x + size, y + size); ctx.lineTo(x - size, y + size); ctx.closePath(); break; case "star": drawStar(ctx, x, y, size, 5); // 5-point star break; case "4-point-star": drawStar(ctx, x, y, size, 4); // 4-point star break; case "6-point-star": drawStar(ctx, x, y, size, 6); // 6-point star break; case "pentagon": drawPolygon(ctx, x, y, size, 5); break; case "hexagon": drawPolygon(ctx, x, y, size, 6); break; case "diamond": ctx.moveTo(x, y - size); ctx.lineTo(x + size, y); ctx.lineTo(x, y + size); ctx.lineTo(x - size, y); ctx.closePath(); break; } ctx.fill(); if (borderSize > 0) { ctx.stroke(); } } function drawStar(ctx, cx, cy, radius, points) { const outerRadius = radius; const innerRadius = radius / 2; const step = Math.PI / points; ctx.beginPath(); let rot = Math.PI / 2 * 3; let x = cx; let y = cy; for (let i = 0; i < points * 2; i++) { x = cx + Math.cos(rot) * outerRadius; y = cy + Math.sin(rot) * outerRadius; ctx.lineTo(x, y); rot += step; x = cx + Math.cos(rot) * innerRadius; y = cy + Math.sin(rot) * innerRadius; ctx.lineTo(x, y); rot += step; } ctx.lineTo(cx, cy - outerRadius); ctx.closePath(); } function drawPolygon(ctx, x, y, radius, sides) { let angle = (Math.PI / 2) * 3; // Adjust the starting angle for the pentagon to point upwards let step = (2 * Math.PI) / sides; ctx.beginPath(); for (let i = 0; i < sides; i++) { ctx.lineTo(x + radius * Math.cos(angle), y + radius * Math.sin(angle)); angle += step; } ctx.closePath(); } function drawStripes(ctx, numberOfStripes, stripeWidth, stripeHeight, stripeColor, stripeBorderColor, stripeBorderSize, shape, shapeSize, shapeColor, shapeBorderColor, shapeBorderSize) { const middleY = imgSize / 2; const stripeHalfHeight = stripeHeight / 2; // Draw the stripes for (let i = 0; i < numberOfStripes; i++) { let centerX; if (numberOfStripes === 1) { centerX = imgSize / 2; } else { centerX = (i * (imgSize / numberOfStripes)) + (imgSize / (numberOfStripes * 2)); } const halfStripeWidth = stripeWidth / 2; const xStart = centerX - halfStripeWidth; // Draw stripe ctx.fillStyle = stripeColor; ctx.fillRect(xStart, middleY - stripeHalfHeight, stripeWidth, stripeHeight); if (stripeBorderSize > 0) { ctx.strokeStyle = stripeBorderColor; ctx.lineWidth = stripeBorderSize; ctx.strokeRect(xStart, middleY - stripeHalfHeight, stripeWidth, stripeHeight); } // Draw the shape if present if (shape !== "none") { drawShape(ctx, shape, centerX, middleY, shapeSize, shapeColor, shapeBorderColor, shapeBorderSize); } } } function generateMarks() { const container = document.getElementById('canvas-container'); container.innerHTML = ''; // Clear the container for preview const stripeColor = document.getElementById('stripeColor').value; const stripeBorderColor = document.getElementById('borderColor').value; const backgroundColor = document.getElementById('backgroundColor').value; const stripeWidth = parseInt(document.getElementById('stripeWidth').value); const stripeHeight = parseInt(document.getElementById('stripeHeight').value); const stripeBorderSize = parseInt(document.getElementById('borderSize').value); const shape = document.getElementById('shape').value; const shapeSize = parseInt(document.getElementById('shapeSize').value); const shapeColor = document.getElementById('shapeColor').value; const shapeBorderColor = document.getElementById('shapeBorderColor').value; const shapeBorderSize = parseInt(document.getElementById('shapeBorderSize').value); const transparentBackground = document.getElementById('transparentBackground').checked; // Array of countries const countries = ["china", "czech", "france_uk", "germany", "italian", "japan", "poland", "sweden", "usa", "ussr"]; // Generate images for each country countries.forEach(country => { const zipFolder = zip.folder(`${folderPath}`); for (let numStripes = 1; numStripes <= 3; numStripes++) { const canvas = document.createElement('canvas'); canvas.width = imgSize; canvas.height = imgSize; const ctx = canvas.getContext('2d'); if (transparentBackground) { ctx.clearRect(0, 0, imgSize, imgSize); } else { ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, imgSize, imgSize); } drawStripes(ctx, numStripes, stripeWidth, stripeHeight, stripeColor, stripeBorderColor, stripeBorderSize, shape, shapeSize, shapeColor, shapeBorderColor, shapeBorderSize); // Append canvas to container to display preview only for China if (country === "china" && (numStripes === 1 || numStripes === 2 || numStripes === 3)) { container.appendChild(canvas); } canvas.toBlob(function(blob) { zipFolder.file(`gun_${country}_${numStripes}.png`, blob); // Updated file name with 'gun_' }); } }); } function initializePage() { // Generate initial preview generateMarks(); } // Initialize the page with a preview when it loads window.onload = initializePage; document.getElementById('generate-button').addEventListener('click', generateMarks); document.getElementById('download-button').addEventListener('click', function() { zip.generateAsync({ type: "blob" }).then(function(content) { saveAs(content, "marks_of_excellence.zip"); }); }); // Save a preset document.getElementById('savePresetButton').addEventListener('click', function() { const presetName = document.getElementById('presetName').value; if (!presetName) { alert('Please enter a name for the preset.'); return; } const preset = { stripeColor: document.getElementById('stripeColor').value, borderColor: document.getElementById('borderColor').value, stripeWidth: parseInt(document.getElementById('stripeWidth').value), stripeHeight: parseInt(document.getElementById('stripeHeight').value), borderSize: parseInt(document.getElementById('borderSize').value), shape: document.getElementById('shape').value, shapeSize: parseInt(document.getElementById('shapeSize').value), shapeColor: document.getElementById('shapeColor').value, shapeBorderColor: document.getElementById('shapeBorderColor').value, shapeBorderSize: parseInt(document.getElementById('shapeBorderSize').value), backgroundColor: document.getElementById('backgroundColor').value, transparentBackground: document.getElementById('transparentBackground').checked }; localStorage.setItem(presetName, JSON.stringify(preset)); alert('Preset saved!'); }); // Load a preset document.getElementById('loadPresetButton').addEventListener('click', function() { const presetName = document.getElementById('presetName').value; if (!presetName) { alert('Please enter a name for the preset.'); return; } const preset = JSON.parse(localStorage.getItem(presetName)); if (preset) { document.getElementById('stripeColor').value = preset.stripeColor; document.getElementById('borderColor').value = preset.borderColor; document.getElementById('stripeWidth').value = preset.stripeWidth; document.getElementById('stripeHeight').value = preset.stripeHeight; document.getElementById('borderSize').value = preset.borderSize; document.getElementById('shape').value = preset.shape; document.getElementById('shapeSize').value = preset.shapeSize; document.getElementById('shapeColor').value = preset.shapeColor; document.getElementById('shapeBorderColor').value = preset.shapeBorderColor; document.getElementById('shapeBorderSize').value = preset.shapeBorderSize; document.getElementById('backgroundColor').value = preset.backgroundColor; document.getElementById('transparentBackground').checked = preset.transparentBackground; alert('Preset loaded!'); } else { alert('Preset not found.'); } }); // Delete a preset document.getElementById('deletePresetButton').addEventListener('click', function() { const presetName = document.getElementById('presetName').value; if (!presetName) { alert('Please enter a name for the preset.'); return; } localStorage.removeItem(presetName); alert('Preset deleted!'); }); </script> </body> </html> Quote Link to comment https://forums.phpfreaks.com/topic/323203-need-help-with-layoutdesign/ Share on other sites More sharing options...
gizmola Posted Tuesday at 04:20 PM Share Posted Tuesday at 04:20 PM This is an old thread, but just in case, here are a few pieces of advice: Move your CSS into an external file Include a CSS Reset OR use a CSS framework that includes one. (for example "bootstrap css") Consider use of BEM for organization and better integration of markup and styling Investigate use of SASS (allows use of variables, nesting of css classes within source sass) Convert all pixel sizing to use REM (or EM inside of @Media queries) Make UI responsive using media queries Base colors on a color based theme. Sites like https://coolors.co/ are very useful in this regard. Here's an example color pallet: https://coolors.co/bcd4de-a5ccd1-a0b9bf-9dacb2-949ba0 You have a cool app, but I do think a simpler layout would make it simpler and more usable. The font use and coloring would be improved if labels and headings weren't the same color (black) as the inputs. It looks like you are trying to pack in multiple fields horizontally, with labels, which makes it busy. When you choose transparent background, the background input should be made read only. The "Preview" section should have the same section treatment (background, border, padding etc) as the other sections. Quote Link to comment https://forums.phpfreaks.com/topic/323203-need-help-with-layoutdesign/#findComment-1654533 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.