如何创建随机算法来创建模拟军事模仿路径的 svg 图像

问题描述 投票:0回答:1

我想创建一个军事模仿背景 SVG 图像,使用 JS 中的算法生成随机不对称几何形状。

目标是得到这样的东西:
military mimetic pattern

使用基本的 SVG 几何图形:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000"
    viewBox="0 0 1000 1000" style="background-color:yellow">
    
    <path d="M 250,500 C 250,500 500,0 750,500 Z" fill="brown">
</svg>
javascript svg path
1个回答
0
投票
  1. 形状必须延伸到画布之外,才不会奇怪地出现在里面
  2. 形状必须缩小尺寸
  3. 形状必须分布,以免单一颜色占主导地位

我不知道如何使形状“脏” - 也许使用一些透明度和“脏”背景

// Helper function to shuffle an array
const shuffleArray = (array) => 
    array.map((value) => ({ value, sort: Math.random() }))
         .sort((a, b) => a.sort - b.sort)
         .map(({ value }) => value);

const generateMimeticSVG = (width, height, numShapes) => {
    const ns = "http://www.w3.org/2000/svg";
    const colors = ["#4b5320", "#8b4513", "#000000", "#c0c0c0"]; // Green, Brown, Black, Beige
    const shapesPerColor = Math.floor(numShapes / colors.length); // Equal distribution
    const shuffledColors = shuffleArray(
        Array.from({ length: shapesPerColor }, () => colors).flat()
    );
    const maxSize = 150; // Maximum size for shapes in pixels

    // Generate a random point with optional noise
    const randomPoint = (centerX, centerY, maxSize) => ({
        x: centerX + (Math.random() - 0.5) * maxSize + (Math.random() - 0.5),
        y: centerY + (Math.random() - 0.5) * maxSize + (Math.random() - 0.5),
    });

    // Generate a rounded path with added dirt/noise
    const createPath = (points) =>
        points.reduce(
            (d, point, i, arr) => {
                if (i === 0) return `M ${point.x},${point.y} `;
                const cp = {
                    x: (arr[i - 1].x + point.x) / 2 + (Math.random() - 0.5),
                    y: (arr[i - 1].y + point.y) / 2 + (Math.random() - 0.5),
                };
                return `${d}Q ${arr[i - 1].x},${arr[i - 1].y} ${cp.x},${cp.y} `;
            },
            ""
        ) +
        `Q ${points[points.length - 1].x},${points[points.length - 1].y} ${(points[0].x + points[points.length - 1].x) / 2},${(points[0].y + points[points.length - 1].y) / 2} Z`;

    const svg = document.createElementNS(ns, "svg");
    svg.setAttribute("width", width);
    svg.setAttribute("height", height);
    svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
    svg.style.backgroundColor = "#4b5320"; // Base military green

    // Generate shapes
    Array.from({ length: numShapes }).forEach((_, i) => {
        const centerX = Math.random() * width;
        const centerY = Math.random() * height;
        const points = Array.from(
            { length: Math.floor(Math.random() * 5) + 3 }, 
            () => randomPoint(centerX, centerY, maxSize)
        );

        const path = document.createElementNS(ns, "path");
        path.setAttribute("d", createPath(points));
        path.setAttribute("fill", shuffledColors[i % shuffledColors.length]);
        path.setAttribute("opacity", 0.7);

        svg.appendChild(path);
    });

    return svg;
};

// Usage: Generate SVG and add to the document
const svgContainer = document.getElementById("svg-container"); // Assuming <div id="svg-container"></div>
const mimeticSVG = generateMimeticSVG(800, 600, 450); // 800x600 canvas, 400 shapes
svgContainer.appendChild(mimeticSVG);
<div id="svg-container" style="width: 100%; height: 100vh;"></div>

© www.soinside.com 2019 - 2024. All rights reserved.