1969年,德国艺术家马克斯·恩斯特(Max Ernst
标题为 naissance d'une galaxie (星系的诞生),我可以想象它必须花了月份才能完成,并使用模具用于所有点。
幸运的是,我们可以更快地编码!
径向梯度
首先,我们需要一个具有径向背景的背景层:
main {
background: #06101D radial-gradient(
#245898,
#2C67AB,
#244D7A 15%,
#475F66,
#93A7A2 65%,
#234E85 66%,
#06101D 70%
) no-repeat;
}
蓬松的云滤波器
我们需要一些“蓬松的云”来模拟涂漆的层,因此我们将使用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;
}
}
现在我们有:
标记
在继续点点之前,让我们在标记中添加一个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()
创建的坐标中计算每个点的x
和y
位置。
之后,我们只是为每个条目输出一个<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ã:
这可以在CSS而不是SVG?中完成。
是的,在CSS中使用sin()
和cos()
,这绝对是可能的。我只是发现使用SVG工作更容易,并且在使用如此大的“数据集”时,它是viewBox
。
结合图层
让我们将点与径向,蓬松的露头 - 背景结合在一起:
我们完成了! ...但是这幅画的下部呢?
我尝试使用drops
滤波器(从上面的CSS过滤器编辑器)和一堆叠加梯度,但根本无法获得正确的“外观和感觉”。
添加海报文本
让我们将绘画变成海报,并添加一些文字。
我们将使用cqi
-units作为文本,因此它们可以很好地扩展到我们海报的宽度:
构建海报
海报在框架中看起来更好,所以让我们添加一个漂亮的木制框架!
css有一个称为ridge
的border-style
,它可以使用:
body {
border: 1cqi ridge #D39E85;
}
我们得到:
墙纸
最后,是时候将我们的框海报挂在墙上了。
让我们将壁纸从CSS Patterns添加到<html>
-Element和box-shadow
到<body>
-元素:
美丽,不是吗?希望您的CPU可以管理10241点!
演示