随机化 SVG 形状

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 提供适用于旅程各个阶段的云产品。立即开始使用 200 美元的免费积分!

假设我们想要持续随机化圆的半径。我们可以使用 CSS 来模拟随机效果,但让我们使用 JavaScript 创建真正的伪随机数。

我们这里谈论的是 SVG,因此这是我们的基本圆形

<svg viewBox="0 0 100 100">
  <circle id="circle" cx="50" cy="50" r="50" />
</svg>

一个用于生成随机整数的小型 JavaScript 函数,用于指定范围内的数字

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

为了每秒随机化半径,我们可以这样做

var circle = document.querySelector("#circle");
setInterval(function() {
  circle.setAttribute("r", getRandomInt(5, 50));
}, 1000);
Just for kicks, we could have it transition to the new size in the browsers that support it:

circle {
  transition: r 0.2s;
}

查看演示。

所有 SVG 形状本质上都是由数字构建的,这意味着所有形状都可以进行随机化。

想象一个形状,底部是随机的不规则形状,就像这样

这通常是一个(直线),但绘制起来几乎与一样容易,这将使其在(Chrome)中可转换。所以让我们来做。这是该路径可能的样子

<path d="M-4,-4 L1004,-4 L1004,100 L940,161 L617,186 L555,122 L306,179 L17,177 L-4,100 L-4,-4 Z"></path>

其中一些点是固定的,其他点将被随机化。这是一个图表

我们现在的工作是生成这些随机数,然后将它们组合成一个字符串,然后用该字符串替换 DOM 中的字符串(<path>d 属性)。

记住我们已经有一个生成随机数的函数:getRandomInt()。这是一个简化的概念

var a = getRandomInt(1, 100);
var b = getRandomInt(1, 100);
var c = getRandomInt(1, 100);

var newString = `${a} ${b} ${c}`;

诀窍是按 路径语法 需要的精确格式生成和排列它们。并不难,只是要生成很多数字等等。我将在下面列出完整的内容

var csstricks = {

  init: function() {
    csstricks.randomizeBackgrounds();
  },

  generateRandomPoints: function(minSpread, maxSpread) {
    let points = {};
    points.a = `${getRandomInt(800, 1000)},${getRandomInt(minSpread, maxSpread)}`;
    points.b = `${getRandomInt(600, 800)},${getRandomInt(minSpread, maxSpread)}`;
    points.c = `${getRandomInt(400, 600)},${getRandomInt(minSpread, maxSpread)}`;
    points.d = `${getRandomInt(200, 400)},${getRandomInt(minSpread, maxSpread)}`;
    points.e = `${getRandomInt(0, 200)},${getRandomInt(minSpread, maxSpread)}`;
    return points;
  },

  randomizeHeader: function() {
    let newPoints = csstricks.generateRandomPoints(120, 190);
    let downFacingPoints = `M-4,-4 L1004,-4 L1004,100 L${newPoints.a} L${newPoints.b} L${newPoints.c} L${newPoints.d} L${newPoints.e} L-4,100 L-4,-4 Z`;
    $("#jagged-top").attr("d", downFacingPoints);
  },

  randomizeBackgrounds: function() {
    csstricks.randomizeHeader();
    setInterval(function() {
      csstricks.randomizeHeader();
    }, 2000);
  },

};

csstricks.init();

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

它只是为了组织目的而被分成更小的函数。在最终版本中,我还添加了 setInterval 的更高效版本

这是最终的演示

查看 Pen
CSS-Tricks 标题
,作者 Chris Coyier (@chriscoyier)
CodePen 上。

值得一提的是:SVG 并不像一些网络图形那样真正“硬件加速”。例如,如果您转换元素的变换或不透明度属性,您无需过度担心性能,因为这些属性将被转移到计算机的图形处理器 (GPU)(如果可用)。在这里,使用 SVG 更改此路径数据时,没有这样的好运。您可能会在 Chrome 中看到此演示中相当强烈的内存和 CPU 使用率,因为我们应用了 CSS 过渡。如果没有过渡(只是形状的瞬时改变),则性能在任何浏览器中都不应该成为太大问题。

享受随机化吧!