让我们制作可以导出到 SVG 和 PNG 的生成艺术

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 价值 200 美元的免费积分!

假设您是一位设计师。 太棒了。 您已被聘请为会议做一些设计工作。 各种各样的事情。 网站。 打印日程表。 用于房间的大海报。 前滚滑梯。 您说出来吧。

所以你想出了一个美学风格,一种将所有东西联系在一起并使其感觉一致的设计氛围。 然而,每次使用都将是独特且不同的。 太棒了,让我们从那里开始。

您正在您的设计软件中捣鼓,而您想出的美学风格是这些以随机模式重叠的矩形,它们具有特定的有限色调,您认为这可以适用于所有材料。

嘿,当然。 这是一个有趣的背景图案。 您可以在它上面放置白色框以设置文字或其他任何东西,这仅仅是您可以广泛使用的通用背景美学。

但是当它在设计软件中时,它并不是非常随机,对吗? 我想您可以弄清楚如何编写软件脚本。 但是我们是网络人,所以让我们用网络的方式来做。 让我们依靠 JavaScript 和 SVG 来开始。

我们可以像这样以编程方式定义我们的色调

const colorPalette = ["#9B2E69", "#D93750", "#E2724F", "#F3DC7B", "#4E9397"];

然后编写一个函数,该函数只根据您提供的最小值和最大值生成一堆随机矩形

const rand = (max) => {
  return Math.floor(Math.random() * max);
};

const makeRects = (maxX, maxY) => {
  let rects = "";
  for (let i = 0; i < 100; i++) {
    rects += `
      <rect
        x="${rand(maxX + 50) - 50}"
        y="${rand(maxY + 50) - 50}"
        width="${rand(200) + 20}"
        height="${rand(200) + 20}"
        opacity="0.8${rand(10)}"
        fill="${colorPalette[rand(5)]}"
      />
    `;
  }
  return rects;
};

您可以调用该函数并将所有这些矩形放到一个 <svg> 中,从而获得一些不错的生成艺术作品。

现在您的工作轻松了! 要创建新的作品,您可以一遍又一遍地运行代码,然后您将获得不错的 SVG,可用于您需要的任何地方。

假设您的客户要求您提供一些此类艺术作品,用于他们正在进行的其他事物的背景。 他们需要一个不同尺寸的背景! 在不同的纵横比! 他们现在需要!

我们在浏览器中执行此操作的事实在这里非常有用。 浏览器窗口可以轻松调整大小。 ,我知道。 所以让我们将父 SVG 的大小调整为整个视窗。 这是调用该函数以在此处生成所有随机矩形的 SVG

const makeSVG = () => {
  const w = document.body.offsetWidth;
  const h = document.body.offsetHeight;
  const svg = `<svg width="${w}" height="${h}">
    ${makeRects(w, h)}
  </svg>`;
  return svg;
};

因此,如果我们在浏览器中执行此操作,如果浏览器非常宽阔且矮胖,我们将获得一个宽阔而矮胖的 SVG 结果

但我们如何将其从浏览器中提取到实际的 SVG 文件中? 好吧,可能有一些本机平台方法可以做到这一点,但我只是用 Google 搜索了一个解决方案,找到了一个可以解决问题的代码片段。 我将 SVG 作为字符串获取,将其放入数据 URL 作为链接上的 href,并伪造单击该链接。 我在单击按钮时执行此操作。

function download(filename, text) {
  var pom = document.createElement("a");
  pom.setAttribute(
    "href",
    "data:text/plain;charset=utf-8," + encodeURIComponent(text)
  );
  pom.setAttribute("download", filename);

  if (document.createEvent) {
    var event = document.createEvent("MouseEvents");
    event.initEvent("click", true, true);
    pom.dispatchEvent(event);
  } else {
    pom.click();
  }
}

const downloadSvgButton = document.querySelector("#download-svg-button");
downloadSvgButton.addEventListener("click", () => {
  download("art.svg", window.globalSVGStore);
});

但我需要的是 PNG!

…您的客户哭泣。 讲道理。 并非每个人都拥有可以查看和处理 SVG 的软件。 您只需截取页面的屏幕截图。 而且老实说,这可能是一个不错的选择。 我有一个高像素密度的显示屏,这些屏幕截图效果很好。

但是既然我们已经为 SVG 创建了一个下载机,我们不妨也让它适用于 PNG。 这一次我的谷歌搜索导致了 FileSaver.js。 如果我有一个 <canvas>,我可以 toBlob 该东西并将其保存到文件中。 而且我可以通过 canvg 将我的 <svg> 转换为 <canvas>

因此,当我们调用生成 SVG 的函数时,我们只需将其绘制到画布上,画布将自动与 SVG 的大小相同,而 SVG 的大小已调整为覆盖视窗。

const setup = () => {
  const v = canvg.Canvg.fromString(ctx, makeSVG());
  v.start();
};

我们可以随时调用该设置函数,所以不妨也为它创建一个按钮,并在浏览器窗口调整大小时调用它。 以下是实际操作

这是最终结果

它可以更智能。 例如,它可以根据视窗体积来决定绘制多少个矩形。 我只是认为构建用于生成设计资产的艺术生成机器非常巧妙,尤其是为了解决现实世界中的客户问题。

这个想法完全来自我对一些实际设计师构建的类似工具的窥视。 他们的工具更酷,还有更多选项,我知道他们为谁构建的这个工具很开心,因为是他们向我展示了它。 我联系了那位设计师,但他们太忙了,无法接下这样的写作任务。