使

使用 SVG 创建生成式社交图像!最终成果!但是……它到底是用来做什么的?起飞吧🚀

2025-05-27

使用 SVG 创建生成社交图像!

最终结果

但是...它到底是用来做什么的?

升空🚀

2021年了,网络世界充满了各种奇异、恐怖、美丽的事物。该如何确保你的网站脱颖而出呢?

好吧,除了一些精彩的内容之外,我认为一个很棒的生成社交图像(就像本教程中使用的图像一样!)可能是一个很好的一步✨

我们来做一些吧!


最终结果

首先,让我们直接跳到最后。这是本教程的最终结果:

这是一个可扩展、可编辑、可自动生成的社交图片!点击上方 CodePen 中的按钮或更改文本内容,就能看到图片神奇地重新设计。🔮


但是...它到底是用来做什么的?

我称之为“社交图像”“元图像”,是您粘贴链接时在 Slack / Twitter / Facebook 中显示的小预览。

以下是在野外发现的一些社会图像示例……

Stephanie Eckles的精美纹理设计

定制的、有质感的社交形象

DEV + Ben Halpern备受喜爱的社交形象

DEV社区社交形象

Josh Comeau的一些非常酷的 3D 氛围

Twitter 上的自定义 3D 风格社交图片

虽然我所有的例子都来自 Twitter,但重要的是要记住(使用 SVG 创建社交图像的巨大好处)不同的网站可能需要不同的尺寸。

SVG幸运的是,借助+的强大功能viewBox,我们在本教程中创建的图像可以轻松调整为任意尺寸/纵横比。太棒了!


升空🚀

好了,我想开场白就到这里。我们准备开始建造了。各位,穿上工装裤!

HTML 标记

首先让我们为页面添加一些 HTML:



<div class="wrapper">
  <div class="social-image-wrapper">
  <!-- Save a space for our SVG! -->
  </div>
  <div class="controls">
    <div class="controls__randomize">
      <p class="controls__label">Randomize:</p>
      <button class="controls__btn controls__btn--alignment">Alignment</button>
      <button class="controls__btn controls__btn--colors">Colors</button>
      <button class="controls__btn controls__btn--shapes">Shapes</button>
    </div>
    <button class="controls__btn controls__btn--save">Save</button>
  </div>
</div>


Enter fullscreen mode Exit fullscreen mode

在此代码片段中,我们添加了 UI 所需的 HTML 标记,并将所有内容弹出到一个漂亮的小包装器中div


SVG 标记

添加完用户界面的 HTML 代码后,接下来就是主要标记事件了。我之前提到过,社交图片将使用<svg>元素创建,所以让我们在 中添加一个social-image-wrapper



<div class="social-image-wrapper">
  <svg
    viewBox="0 0 1200 630"
    xmlns="http://www.w3.org/2000/svg"
    class="social-image"
  >
    <foreignObject x="0" y="0" width="1200" height="630">
      <div class="social-image__html">
        <div class="social-image__text">
          <h1
            xmlns="http://www.w3.org/1999/xhtml"
            class="social-image__title"
            contenteditable
          >
            All of this text is editable... click on it and start typing!
          </h1>
          <h2
            xmlns="http://www.w3.org/1999/xhtml"
            class="social-image__meta"
            contenteditable
          >
            As you type, the background will adapt itself to the text, making
            sure the shapes never overlap.
          </h2>
        </div>
      </div>
    </foreignObject>
  </svg>
</div>


Enter fullscreen mode Exit fullscreen mode

这里有不少东西要解开,不过别担心!我们可以一起解决🤝

视图框

首先,我们创建<svg>元素并定义一个viewBox



<svg
  viewBox="0 0 1200 630"
  xmlns="http://www.w3.org/2000/svg"
  class="social-image"
>
  ...
</svg>


Enter fullscreen mode Exit fullscreen mode

该属性定义了我们将在其中绘制viewBox所有内容的坐标空间。在我们的例子中,它是<svg>1200x630px

借助 的功能viewBox,我们可以相对于固定的坐标空间定位/缩放所有内容,同时<svg>本身也可以缩放到任意大小。功能强大 ⚡

外部对象

接下来,我们foreignObject向元素添加一个填充了一些 HTML 的标签<svg>



<foreignObject x="0" y="0" width="1200" height="630">
  ...
</foreignObject>


Enter fullscreen mode Exit fullscreen mode

这就是事情开始变得有趣的地方!foreignObject可用于将来自另一个 XML 命名空间(在我们的例子中是 HTML)的内容添加到<svg>元素。

添加后,它将HTML自动缩放到viewBox与常规内容一样的大小SVG。此功能非常强大,因为它允许我们使用 CSS 来设置社交图片内容的样式,同时保留 SVG 的流畅性和渲染能力。

稍后我们会对此进行详细介绍。

注意:HTML添加的任何元素都foreignObject必须具有xmlns="http://www.w3.org/1999/xhtml"属性。

contenteditable 属性

这里最后要检查的是contenteditable添加到我们的h1h2标签的属性:



<h1
  xmlns="http://www.w3.org/1999/xhtml"
  class="social-image__title"
  contenteditable
>
  All of this text is editable... click on it and start typing!
</h1>


Enter fullscreen mode Exit fullscreen mode

contenteditable仅允许用户编辑标签内的文本HTML。这对我们来说非常完美,因为这意味着用户可以轻松添加自己的内容并立即预览结果。


时尚时刻💅

好的,现在我们已经有了创建精美社交图片所需的所有标记。不过,看起来可能有点不太好。我们真的应该解决这个问题。

页面样式

首先,让我们为 UI 添加一些样式:



* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --black: hsl(0, 0%, 10%);
}

body {
  width: 100vw;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 2rem;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  color: var(--black);
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.wrapper {
  width: 100%;
  max-width: 60rem;
  min-width: 20rem;
  margin: 0 auto;
  overflow: hidden;
}

.controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin: 2rem 0;
}

.controls__label {
  margin-right: 1rem;
  font-weight: 500;
  font-size: 1rem;
}

.controls__randomize {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
}

.controls__btn {
  width: 8rem;
  height: 2.25rem;
  margin-right: 1rem;
  background: #fff;
  border-radius: 0;
  border: none;
  border: 2px solid var(--black);
  font-family: inherit;
  color: var(--black);
  font-size: 1rem;
  font-weight: 500;
  cursor: pointer;
}

.controls__btn:hover {
  background: var(--black);
  color: #fff;
}

.controls__btn--save {
  position: relative;
  margin-left: auto;
  margin-right: 0;
  background: var(--black);
  color: #fff;
}

.controls__btn--save:hover {
  background: #fff;
  color: var(--black);
}

.controls__saving-disabled {
  font-size: 0.875rem;
  margin-top: 2rem;
  font-weight: 500;
  display: none;
  font-style: italic;
}

@media only screen and (max-width: 800px) {
  body {
    padding: 0.75rem;
  }

  .controls__btn {
    width: 6rem;
    height: 2rem;
    font-size: 0.875rem;
    margin-top: 0.75rem;
  }

  .controls__label {
    font-size: 0.875rem;
    margin-right: 0.5rem;
    width: 100%;
  }
  .controls__btn--save {
    width: 100%;
    margin-top: 1.25rem;
  }
}

@media only screen and (max-width: 480px) {
  .controls__btn {
    margin-right: 0.5rem;
  }
}


Enter fullscreen mode Exit fullscreen mode

我不会深入讲解这些 CSS,因为它不是本文的主要功能。如果您对这些样式有任何疑问,请随时给我留言。

社交形象风格

接下来,让我们在元素<style>中添加一个内部标签<svg>。它将包含社交图片本身的所有样式:



<svg
  viewBox="0 0 1200 630"
  xmlns="http://www.w3.org/2000/svg"
  class="social-image"
>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .social-image {
      --align-text-x: flex-start;
      --align-text-y: flex-end;

      width: 100%;
      background: #f5f7fa;
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
        "Segoe UI Symbol";
      line-height: 1;
    }

    .social-image__html {
      display: flex;
      height: 100%;
      justify-content: var(--align-text-x);
      align-items: var(--align-text-y);
      padding: 72px;
    }

    .social-image__text {
      max-width: 700px;
    }

    .social-image__title {
      font-size: 56px;
      line-height: 68px;
      font-weight: 800;
      margin-bottom: 24px;
      letter-spacing: -0.0125em;
      outline: none;
    }

    .social-image__meta {
      font-weight: 500;
      font-size: 24px;
      line-height: 36px;
      outline: none;
      letter-spacing: -0.0125em;
    }
  </style>
  ...
</svg>


Enter fullscreen mode Exit fullscreen mode

我们将此 CSS 添加到内部<style>标签中,因为我遇到了一些问题,导致html2canvas样式在标签外部无法按预期渲染<svg>。这样也能很好地控制内容。

再次强调,我不会在这里详细介绍 CSS,但此样式表的主要效果是:

  • 设置一些CSS 自定义属性,结合flexbox来处理社交图片中文本的位置。我们可以稍后使用 JavaScript 修改这些自定义属性。

  • 为文本内容添加一些排版样式。我们这里使用的是系统字体。也可以使用自定义字体,但这样做会增加一些复杂性,因为字体需要嵌入到 中<svg>。下次再说吧!

我们迄今为止的进展

现在这两个样式表都已添加到各自的位置,您应该会在浏览器中看到类似这样的内容:

正在调整大小的简单社交图像设计

很酷吧!当你调整浏览器大小时,看看我们的 HTML 是如何神奇地随着<svg>元素缩放的 ✨

至此,一切准备就绪,一切美好即将到来。让我们前往 JS-town,实现梦想吧🎨


下一站,JavaScript 中心🚂

包安装

我们先把无聊的事情处理掉,安装这个项目所需的软件包。我们将要使用的软件包是:

  • svg.js - 用于简化 SVG 脚本(创建和更新 SVG 元素,例如<circle>
  • html2canvas - 用于截取我们的<svg>社交图片的屏幕截图,以便下载
  • file-saver - 用于处理社交图像被捕获后的保存html2canvas
  • resize-observer-polyfillResizeObserver - 为不支持它的浏览器添加 polyfill

如果您正在关注 CodePen,您可以简单地将这些导入添加到您的 JS 文件中:



import { SVG } from "https://cdn.skypack.dev/@svgdotjs/svg.js";
import html2canvas from "https://cdn.skypack.dev/html2canvas@1.0.0-rc.7";
import ResizeObserver from "https://cdn.skypack.dev/resize-observer-polyfill@1.5.1";
import FileSaver from "https://cdn.skypack.dev/file-saver@2.0.5";


Enter fullscreen mode Exit fullscreen mode

如果您在自己的环境中工作,则可以使用以下命令安装所需的软件包:



npm i svgjs html2canvas resize-observer-polyfill file-saver 


Enter fullscreen mode Exit fullscreen mode

然后可以像这样导入包:



import { SVG } from "svg.js";
import html2canvas from "html2canvas";
import ResizeObserver from "resize-observer-polyfill";
import FileSaver from "file-saver";


Enter fullscreen mode Exit fullscreen mode

注意:如果您在自己的环境中工作,则需要 Webpack 或 Parcel 等捆绑器来处理这些导入。

DOM 元素引用

现在我们已经拥有了该项目所需的所有包,我们应该添加一些引用各种 DOM 元素(按钮、社交图像 svg 等)的变量

为此,我们可以添加:



const socialImageSVG = document.querySelector(".social-image");
const socialImageTitle = document.querySelector(".social-image__title");
const socialImageMeta = document.querySelector(".social-image__meta");

const saveBtn = document.querySelector(".controls__btn--save");
const alignmentBtn = document.querySelector(".controls__btn--alignment");
const colorBtn = document.querySelector(".controls__btn--colors");
const shapesBtn = document.querySelector(".controls__btn--shapes");


Enter fullscreen mode Exit fullscreen mode

颜色

接下来是定义一些颜色变量。这些变量将存储一些 HSL 颜色,我们稍后会定义它们,并最终用于为我们的社交形象着色:



let baseColor;
let baseColorWhite;
let baseColorBlack;

let complimentaryColor1;
let complimentaryColor2;

let shapeColors;


Enter fullscreen mode Exit fullscreen mode

很好。现在所有颜色都是空的,不过没关系。

对齐选项

除了随机颜色之外,我们的社交图片还允许文本随机对齐。为了进一步简化操作,我们将flex用于控制对齐的属性存储在一个数组中:



const alignmentOpts = ["flex-start", "flex-end", "center"];


Enter fullscreen mode Exit fullscreen mode

太棒了!我们很快就会用到这些值。

设置 svg.js 实例

我们将在这里使用svg.js来实现快速、简单的 SVG 脚本编写。如果没有 svg.js,创建和更新 SVG 元素将会非常繁琐。

我们可以像这样创建一个新的 svg.js 实例:



const shapes = SVG(socialImageSVG).group();


Enter fullscreen mode Exit fullscreen mode

这行代码的意思是——<group>在我们的根元素中创建一个新的 SVG 元素,<svg>我可以使用诸如 之类的方法轻松地在其中绘制shapes.rect(...)

添加random()实用功能

在我们继续之前,让我们快速添加一个小的实用函数random,它会生成一个范围内的随机数:



function random(min, max) {
  return Math.random() * (max - min) + min;
}


Enter fullscreen mode Exit fullscreen mode

这工具超级好用。如果你想尝试一些更具生成性的东西,一定要把它留着以后用!我一直都在用它。

选择一些随机颜色

在我的教程中,我通常会把颜色留到最后,但我觉得这次我们应该早点定义它们。它们是最终结果不可或缺的一部分,设置好颜色会让接下来的步骤更容易理解。

为了生成一些随机颜色,我们可以添加以下setColors函数:



function setColors() {
  const baseHue = random(0, 360);
  const saturation = random(60, 90);

  baseColor = `hsl(${baseHue}, ${saturation}%, 60%)`;
  baseColorWhite = `hsl(${baseHue}, ${saturation}%, 97%)`;
  baseColorBlack = `hsl(${baseHue}, 95%, 3%)`;

  complimentaryColor1 = `hsl(${baseHue + 90}, ${saturation}%, 60%)`;
  complimentaryColor2 = `hsl(${baseHue + 180}, ${saturation}%, 60%)`;

  shapeColors = [complimentaryColor1, complimentaryColor2, baseColor];

  socialImageSVG.style.background = baseColorWhite;
  socialImageSVG.style.color = baseColorBlack;
}


Enter fullscreen mode Exit fullscreen mode

该函数的作用如下:

  1. 选择一个随机色调,介于 0 到 360 之间
  2. 选择一个随机饱和度,介于 60 到 90 之间
  3. 定义一个基色、一个非常深的颜色和一个非常浅的颜色,所有颜色都基于相同的色调。这是创建简单调色板并保持一致性的好方法。
  4. 选择两种互补色,每种颜色的色相与前一种颜色成90度角,且饱和度和亮度相同。这是另一种简单有效的找到搭配颜色的方法。
  5. 将补色和底色存储在shapeColors数组中。稍后我们将用它们来填充形状
  6. 将社交图片的背景设置为非常浅的颜色,并将其文本颜色设置为非常深的颜色

现在,如果我们调用setColors(),我们应该会看到社交图片的背景和文本颜色发生变化。变化会非常微妙。希望是这样的:

丰富多彩的社会形象

看起来不错。继续!

创建随机形状位置

接下来,我们需要生成一些随机的、不重叠的矩形,用于放置形状。我们希望这些矩形不仅避免彼此重叠,也避免与文本重叠。

一个小问题

为了避免在创建随机矩形时文本重叠,我们需要知道每个文本元素相对于我们的的<svg>尺寸viewBox

通常为了这个目的我们会使用getBBox但是getBBox它只适用于 SVG 元素,而我们的文本是 HTML。

这并不是那么糟糕,我们可以创建自己的relativeBounds函数来立即解决这个问题!

这里是:



function relativeBounds(svg, HTMLElement) {
  const { x, y, width, height } = HTMLElement.getBoundingClientRect();

  const startPoint = svg.createSVGPoint();
  startPoint.x = x;
  startPoint.y = y;

  const endPoint = svg.createSVGPoint();
  endPoint.x = x + width;
  endPoint.y = y + height;

  const startPointTransformed = startPoint.matrixTransform(
    svg.getScreenCTM().inverse()
  );
  const endPointTransformed = endPoint.matrixTransform(
    svg.getScreenCTM().inverse()
  );

  return {
    x: startPointTransformed.x,
    y: startPointTransformed.y,
    width: endPointTransformed.x - startPointTransformed.x,
    height: endPointTransformed.y - startPointTransformed.y
  };
}


Enter fullscreen mode Exit fullscreen mode

太棒了!我不会深入讲解这个函数,因为我知道它比较枯燥,但它本质上为我们提供了getBBox在 SVG 中使用 HTML 元素的功能。

现在我们有了relativeBounds函数,我们可以生成形状位置。

让我们添加一个generateRandomRects和一个detectRectCollision函数:



function generateRandomRects(existing) {
  const rects = [...existing];
  const tries = 250;
  const maxShapes = 6;

  for (let i = 0; i < tries; i++) {
    if (rects.length === maxShapes + existing.length) break;

    const size = random(100, 600);

    const rect = {
      x: random(-size, 1200),
      y: random(-size, 630),
      width: size,
      height: size
    };

    if (!rects.some((r) => detectRectCollision(r, rect))) {
      rects.push(rect);
    }
  }

  return rects;
}

function detectRectCollision(rect1, rect2, padding = 32) {
  return (
    rect1.x < rect2.x + rect2.width + padding &&
    rect1.x + rect1.width + padding > rect2.x &&
    rect1.y < rect2.y + rect2.height + padding &&
    rect1.y + rect1.height + padding > rect2.y
  );
}


Enter fullscreen mode Exit fullscreen mode

具体来说:

  1. 将一些现有的矩形存储在数组中(在我们的例子中,是文本元素的周围矩形或边界)
  2. 对于一定次数的尝试:创建一个随机大小的矩形。如果这个新矩形与任何其他矩形均不重叠,则将其存储。
  3. 一旦所有尝试都用完,或者达到最大形状数量,就返回我们成功生成的随机矩形

你可能会注意到padding矩形碰撞代码中有一个看起来很奇怪的选项。它定义了矩形之间的最小距离。我发现它能让代码看起来更简洁一些。

关于不完美的说明

这远非一个完美的函数。由于使用蛮力来放置矩形,因此速度相当慢,而且我们无法保证maxShapes多次尝试后一定能达到目标。

但这是否意味着它不好呢?绝对不是。

我们现在更关心的是视觉效果,而不是算法效率,而这些值似乎能产生相当美观的效果。生成式设计的真正挑战在于对这类值的调整。

你应该尝试改变这些参数。尝试改变最大形状数量,或者调整我们的尺寸,或者增加最大尝试次数。看看结果。重复。这里没有正确答案!

绘制我们的形状

好了,我们已经准备好一些代码来生成不重叠的矩形。让我们把它们变成现实!

首先,让我们添加一个新generate功能:



function generate() {
  shapes.clear();

  const htmlRects = [
    relativeBounds(socialImageSVG, socialImageTitle),
    relativeBounds(socialImageSVG, socialImageMeta)
  ];

  const rects = generateRandomRects(htmlRects);

  for (const rect of rects.slice(2, rects.length)) {
    drawRandomShape(rect);
  }
}


Enter fullscreen mode Exit fullscreen mode

这实际上是一小段代码。generateRandomRects这里完成了大部分繁重的工作。我们说的是:

  1. 清除任何已经存在的形状(这在以后动态重新生成图像时很有用)
  2. 将两个文本元素相对于的边界存储viewBox在一个数组中
  3. 生成一堆随机、不重叠的矩形
  4. 对于每个随机矩形(除前两个文本矩形之外)其中绘制一个随机形状。

现在,我们实际上还没有drawRandomShape函数。让我们添加一个。作为一个简单的开始,请尝试以下代码:



function drawRandomShape(rect) {
  const { x, y, width, height } = rect;
  shapes.rect(width, height).x(x).y(y);
}


Enter fullscreen mode Exit fullscreen mode

添加后drawRandomShape,您可以安全地调用,generate而不会让浏览器生气:



generate();


Enter fullscreen mode Exit fullscreen mode

如果你现在检查浏览器,你应该会看到类似这样的内容:

带有随机矩形的社交图像

太棒了!这些就是我们之前生成的随机矩形,以一种非常简单的方式呈现。

不过,我们可以扩展。让我们更新drawRandomShape并添加一个小的randomColor实用函数:



function randomColor() {
  // ~~ === shorthand for Math.floor()
  return shapeColors[~~random(0, shapeColors.length)];
}

function drawRandomShape({ x, y, width, height }) {
  const shapeChoices = ["rect", "ellipse", "triangle"];
  let shape;

  switch (shapeChoices[~~random(0, shapeChoices.length)]) {
    case "ellipse":
      shape = shapes.ellipse(width, height).x(x).y(y);
      break;
    case "triangle":
      shape = shapes
        .polygon(`0 ${height}, ${width / 2} 0, ${width} ${height}`)
        .x(x)
        .y(y);
      break;
    default:
      shape = shapes.rect(width, height).x(x).y(y);
  }

  const color = randomColor();

  if (random(0, 1) > 0.25) {
    shape.fill(color);
  } else {
    shape
      .stroke({
        color,
        width: 16
      })
      .fill("transparent");
  }

  shape.node.classList.add("shape");
  shape.rotate(random(0, 90)).scale(0.825);
  shape.opacity(random(0.5, 1));
}


Enter fullscreen mode Exit fullscreen mode

以下是这里发生的事情的详细说明:

  1. 选择随机形状类型
  2. 使用 svg.js 根据我们的形状选择渲染不同的 SVG 元素
  3. 从我们之前定义的选项中随机选择一种颜色
  4. 25% 的情况下,将此颜色应用于形状轮廓。其余 75% 的情况下,使用此颜色填充形状
  5. shape给元素添加一个类,以便我们以后可以快速引用它
  6. 将形状旋转某个随机值,并将其不透明度降低一个随机量

呼!事情变得相当紧张了。让我们休息一下,惊叹一下我们精彩的创作!

添加了形状和颜色的社交图像

哇!🤩 看起来不错,各位。我们差不多完成了。刷新浏览器,每次都会看到不同的内容。

交互性

本教程的最后一步是实现交互。这主要涉及将事件监听器附加到内容上,并运行我们已经定义的功能。

为了简洁起见,我已经在代码中添加了注释。如果您需要更多详细信息或对此有任何疑问,请随时告诉我!

连接按钮



// regenerate our shapes and shape positions
shapesBtn.addEventListener("click", () => {
  generate();
});

// set new random color values and update the existing shapes with these colors
colorBtn.addEventListener("click", () => {
  setColors();

  // find all the shapes in our svg and update their fill / stroke
  socialImageSVG.querySelectorAll(".shape").forEach((node) => {
    if (node.getAttribute("stroke")) {
      node.setAttribute("stroke", randomColor());
    } else {
      node.setAttribute("fill", randomColor());
    }
  });
});

// choose random new alignment options and update the CSS custom properties, regenerate the shapes
alignmentBtn.addEventListener("click", () => {
  socialImageSVG.style.setProperty("--align-text-x", alignmentOpts[~~random(0, alignmentOpts.length)]);
  socialImageSVG.style.setProperty("--align-text-y", alignmentOpts[~~random(0, alignmentOpts.length)]);
  generate();
});

// save our social image as a .png file
saveBtn.addEventListener("click", () => {
  const bounds = socialImageSVG.getBoundingClientRect();

  // on save, update the dimensions of our social image so that it exports as expected
  socialImageSVG.style.width = "1200px";
  socialImageSVG.style.height = "630px";
  socialImageSVG.setAttribute("width", 1200);
  socialImageSVG.setAttribute("height", 630);
  // this fixes an odd visual "cut off" bug when exporting
  window.scrollTo(0, 0);

  html2canvas(document.querySelector(".social-image-wrapper"), {
    width: 1200,
    height: 630,
    scale: 2 // export our image at 2x resolution so it is nice and crisp on retina devices
  }).then((canvas) => {
    canvas.toBlob(function (blob) {
      // restore the social image styles
      socialImageSVG.style.width = "100%";
      socialImageSVG.style.height = "auto";
      socialImageSVG.setAttribute("width", "");
      socialImageSVG.setAttribute("height", "");

      FileSaver.saveAs(blob, "generative-social-image.png");
    });
  });
});


Enter fullscreen mode Exit fullscreen mode

处理新的文本输入

好的,所有按钮都连接好了,太棒了。不过还有最后一个功能需要添加。当用户输入时,我们需要更新形状的位置。为此,我们可以ResizeObserver在每次文本元素的宽度/高度尺寸发生变化时运行一个函数。

一探究竟:



const resizeObserver = new ResizeObserver(() => {
  generate();
});

resizeObserver.observe(socialImageTitle);
resizeObserver.observe(socialImageMeta);


Enter fullscreen mode Exit fullscreen mode

现在,当您输入时,您应该会看到您的社交图像更新,就像 CodePen 示例一样。


我们成功了!

哎呀,真是太棒了!好消息是,我们终于完成了。希望你在这里学到了一些关于生成式设计的知识,甚至学到了一些实用的 SVG 小技巧。

我认为你可以在很多地方采用这个方法,如果你根据本教程创建了一些很酷的东西,我很乐意听到你的意见😎

如果您确实喜欢这篇文章,请在 Twitter 上关注我@georgedoescode,享受源源不断的创意编码乐趣。

你也可以给我买杯咖啡来支持我的教程☕

非常感谢你的阅读!下次再见❤️

文章来源:https://dev.to/georgedoescode/tutorial-create-generative-social-images-using-svg-2c47
PREV
我的第一个包含 React 和 AWS 的作品集
NEXT
我的开源项目获得 2000 星 一些背景 今天发布