用JavaScript和SVG圈子包装
#javascript #css #网络开发人员 #showdev

我喜欢日本艺术家Yayoi Kusama的作品,并且很长一段时间都想制作她著名的点的互动海报。

尽管我父亲是一位退休的数学老师,但我只是 超简单的“圆包装”算法,所以我最终做了更简单的事情:

function kusamaDots(
  numDots,
  minRadius,
  maxRadius,
  width,
  height
) {
  const dots = [];

  function createDot() {
    const x = Math.floor(Math.random() * width);
    const y = Math.floor(Math.random() * height);
    const radius =
      Math.random() * (maxRadius - minRadius) + minRadius;
    const dot = { radius, x, y };
    if (!dots.some((c) => intersects(dot, c))) {
      return dot;
    }
    return null;
  }

  while (dots.length < numDots) {
    const dot = createDot();
    if (dot !== null) dots.push(dot);
  }
  return dots;
}

参数为:

  1. numDots。点总数。
  2. minRadius。点的最小半径。
  3. maxRadius。点的最大半径。
  4. “ canvas”(SVG ViewBox)的width
  5. 相同的height

createDot方法在viewBox的边界内创建一个随机的xy-position。它在minRadiusmaxRadius的值之间设置一个随机半径。

它创建一个dot-object,然后检查点是否与任何其他点(已经创建的点)相交。为此,我们需要一个小型帮助者:

function intersects(first, second) {
  const dx = first.x - second.x;
  const dy = first.y - second.y;
  const distance = Math.sqrt(dx * dx + dy * dy);
  const sumOfRadii = first.radius + second.radius;
  return distance <= sumOfRadii;
}

如果DOT与任何其他点相交 ,则为return

之后,while循环运行直到达到numDots

to output dots,我们只需在svg中创建<circle>s:

const dots = kusamaDots(
  e.target.valueAsNumber,
  10,
  150,
  1000,
  1000
);
svg.innerHTML = dots
  .map(
    (dot) =>
      `<circle r="${dot.radius}" cx="${dot.x}" cy="${dot.y}"></circle>`
  )
  .join("")

CSS

CSS非常简单。框架和响应式文本类似于The Moon in 10241 Dots

最重要的部分是用于点颜色的自定义属性(如fill)!

但是,我决定做一个自定义的范围滑块和一个颜色挑剔的作为海报的一部分,从而使其成为交互式海报:

Kusama Poster Final

你能发现它们吗?!

拖拉滑块,然后单击颜色挑选以制作自己的海报:

Modified version


演示