10241年的月亮重新创建了1969年的杰作
#javascript #css #网络开发人员 #showdev

1969年,德国艺术家马克斯·恩斯特(Max Ernst

Original Poster

标题为 naissance d'une galaxie (星系的诞生),我可以想象它必须花了月份才能完成,并使用模具用于所有点。

幸运的是,我们可以更快地编码!


径向梯度

首先,我们需要一个具有径向背景的背景层:

main {
  background: #06101D radial-gradient(
    #245898, 
    #2C67AB, 
    #244D7A 15%, 
    #475F66, 
    #93A7A2 65%, 
    #234E85 66%, 
    #06101D 70%
  ) no-repeat;
}

Radial Gradient


蓬松的云滤波器

我们需要一些“蓬松的云”来模拟涂漆的层,因此我们将使用CSS滤清器编辑器中的“蓬松”过滤器:

我们在与径向背景的同一层中添加了一个::after-peasudo元素,继承了相同的背景,还使用“蓬松” - 滤波器:

main {
  &::after {
    background: inherit;
    mix-blend-mode: hard-light;
    content: "";
    display: block;
    filter: url(#fluffy) blur(5px); 
    inset: 0;
    opacity: 0.33;
    position: absolute;
  }
}

现在我们有:

Fluffy Filter


标记

在继续点点之前,让我们在标记中添加一个svg元素 - 我们稍后添加innerHTML

<svg viewBox="0 0 1000 1000" class="moon"></svg>

要进行硬编码,这些点可能需要花费的时间与原始绘画一样长,所以让我们使用JavaScript和一些数学来帮助我们!

首先,我们需要一个函数dots(),带有一个configuration-object:

function dots(config =
  {
    dotsring: 8,
    dotsize: 3,
    radius: 2,
    rings: 50,
    rotate: 6,
    spread: 10,
    x: 1000,
    y: 1000
  }) {
  ...
}

解释器:

  • dotsring。每个环。这个数字被添加到每个新环。
  • dotsize。相对点数(请参阅svg viewBox
  • 半径。开始半径索引。在这种情况下,我们想跳过第一个,在月球中央创建一个更大的“孔”。
  • 戒指。戒指的总量
  • 旋转。旋转每个环
  • 扩散。环中的点之间的距离
  • x。 svg的viewBox x宽。
  • y。 svg的viewBox y宽。

接下来,我们需要每个环的坐标数组。为此,我们需要一个小的助手方法:

const coords = (number) => {
  const frags = 360 / number
  return Array.from({ length: number + 1 }, 
  (_, i) => (frags / 180) * i * Math.PI)
}

充满

如果您检查了原始绘画,您会注意到大多数点具有相同的浅黄色颜色。几个随机点是浅蓝色或薰衣草。

要帮助我们用这些值填充随机点,我们需要一个随机方法:

const random = (min, max) =>
  Math.floor(Math.random() * (max - min) + min);

...和一个fill()-hethod,我们将当前的dot-index解析为number

const fill = (number) =>
  ['#74BAA0', '#B3A0C1'][number % random(1, 100)] ||
  '#BCD2A9';

渲染点

要渲染点,我们需要两个循环:

  • 一个戒指。对于每个戒指,我们输出一个<g>元素,向<g> roup一个环内的所有点。

  • 在一个单个环内的点一个。在此内部循环中,我们从使用coords()创建的坐标中计算每个点的xy位置。

之后,我们只是为每个条目输出一个<circle>

let s = '';
for (let i = config.radius; i <= config.rings; i++) {
  const r = config.spread * i;
  const ring = coords(config.dotsring * i);
  s += `<g style="--r:${i * config.rotate}deg">${ring
    .map((value, index) => {
      const x =
        config.x / 2 - Math.round(r * Math.cos(value));
      const y =
        config.y / 2 - Math.round(r * Math.sin(value));
      return `<circle cx="${x}" cy="${y}" r="${
        config.dotsize
      }" fill="${fill(i + index)}" />`;
    })
    .join('')}</g>`;
}
return s;

让我们将输出添加到SVG元素中,我们先前创建了:

document.querySelector('.moon').innerHTML = dots()

...和voilã:

Dots

这可以在CSS而不是SVG?中完成。
是的,在CSS中使用sin()cos(),这绝对是可能的。我只是发现使用SVG工作更容易,并且在使用如此大的“数据集”时,它是viewBox


结合图层

让我们将点与径向,蓬松的露头 - 背景结合在一起:

Combining

我们完成了! ...但是这幅画的下部呢?

我尝试使用drops滤波器(从上面的CSS过滤器编辑器)和一堆叠加梯度,但根本无法获得正确的“外观和感觉”。


添加海报文本

让我们将绘画变成海报,并添加一些文字。

我们将使用cqi-units作为文本,因此它们可以很好地扩展到我们海报的宽度:

Poster Text


构建海报

海报在框架中看起来更好,所以让我们添加一个漂亮的木制框架!

css有一个称为ridgeborder-style,它可以使用:

body {
  border: 1cqi ridge #D39E85;
}

我们得到:

Poster with frame


墙纸

最后,是时候将我们的框海报挂在墙上了。

让我们将壁纸从CSS Patterns添加到<html>-Element和box-shadow<body>-元素:

Wallpaper

美丽,不是吗?希望您的CPU可以管理10241点!

演示