Jump to content

Recommended Posts

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>

 

Link to comment
https://forums.phpfreaks.com/topic/323203-need-help-with-layoutdesign/
Share on other sites

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.

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.