使用三角函数实现 CSS 随机性

发布于 2024-12-16 12:29:08 字数 6060 浏览 1 评论 0

在过去, 我已经介绍了 CSS 中的伪随机性主题使用模运算 和 I 使用素数创建一个自动计数器,可以用于为每个对象生成不同的值 。因此,我们可以独立计算每个元素的伪随机值。

尽管这个解决方案很强大,但它也有一些缺点:

  • 模函数不连续
  • 它过于复杂:需要 3 个变量和 @property 定义我们想要生成的每个随机值
  • 需要使用 @property 尚未得到广泛支持

幸运的是,我们可以做得更好!在本文中,我想使用三角学提出一个更好的解决方案。

更好的方法

自从我上次探讨这个主题以来,CSS 中出现了新的令人惊奇的功能。最令人兴奋的新增内容之一是三角函数。他们解锁了许多以前不可能完成的任务。它们也是 CSS 原生支持的第一个有界连续函数,使它们成为创建伪随机生成器的惊人工具。

随机性与伪随机性

显然,这里提出的解决方案仅生成伪随机值。所有值均使用预定常数计算。 正如我之前的文章中所述 ,我们可以添加一个额外的 --seed 变量并从系统外部更改它(例如在加载时在 JavaScript 中设置)以提供不太确定的结果,但 CSS 不提供任何可使用的非确定性方法。也就是说,该解决方案应该足以为动画、位置等获得足够的伪随机值。如果您想用它来解决您的加密函数,您可能一开始就没有使用正确的技术???

正弦函数的特征

正弦和余弦函数之所以有趣有很多原因。它们在涉及圆周和旋转的各种操作中非常有用。但在我们的例子中,我们可以将它们的属性用于其他目的。

有界函数

正弦和余弦的重要特性之一是,结果值始终限制在 -1 和 1 之间。这意味着,无论您传递给它的值有多大或多小,结果将始终是此值的一个值范围。然后,我们可以对范围 [0,1] 执行简单的归一化。有了标准化的值,我们可以用它来通过简单的线性映射来表示任何值。

--x: calc(0.5 + 0.5 * sin(var(--n) * 342.06184 + 23.434));

/* Then we can use it as following */
background: rgb(calc(50 + var(--x) * 100), 0, 0);
/* Red will be in the range of 50-150.

上面的代码使用了我在上一篇文章中介绍的计数器 var(--n) ,其中我使用素数创建了一种在 CSS 中自动创建计数器变量的有效方法。

CSS 中的计数:解锁 CSS 变量的魔力

使用质数在 CSS 中创建通用计数器,您可以将其用于各种用途。

然后将该值乘以一些任意值并偏移以提供伪随机大数(这些值并不真正没关系,您可以根据需要更改它们以获得不同的结果)。之后,我们使用 sine 函数将其映射到范围 [-1, 1] 。最后,如下面的动画所示,我们可以通过应用简单的代数变换将其映射到范围 [0, 1] 。一旦我们从范围 [0, 1] 中获取值,我们就可以使用线性映射将其映射到任何其他所需的值。

缩放可视化

连续性

另一个特点正弦函数的连续性。您可以 在此处探索连续性的完整正式定义 ,但为了简单起见,您可以考虑它正弦或余弦函数输入的微小变化最终会导致输出的微小变化。因此,我们可以在动画时实现值的逐渐变化,同时仍然让系统随机行为。

连续性可视化

示例

如下一些示例展示了使用三角函数生成伪随机值的潜力。

圆网格

第一个示例显示了实际的正弦属性。生成的值是随机的,但当涉及到颜色和大小动画时,我们仍然可以保持顺序和连续性。

请参阅 hypersphere 的 Pen 使用三角函数实现 CSS 中的随机性 ( @hypersphere )在 CodePen 上。

代码的关键部分是计算 x、y、z 和 w 变量,它们分别用于表示红色、绿色、蓝色和宽度。

div::before {
  --x: calc(0.5 + 0.5 * sin(4.284 * var(--n)));
  --y: calc(0.5 + 0.5 * sin(7.284 * var(--n)));
  --z: calc(0.5 + 0.5 * sin(4 * var(--n) + 2 * var(--t)));
  --w: calc(0.5 + 0.5 * sin((0.2 * cos(var(--t)/100) + 0.8) * 49.123 * var(--n) + var(--t)));
  
  background: rgb(
    calc(50 +  100 * var(--x)),
    calc(200 + 30 * var(--y)),
    calc(120 + 100 * var(--z))
  );
  width: calc(50% + var(--w)*50%);
}

最后 2 个变量,除了我们的计数器之外 --n ,使用时间变量 --t ,它是通过运行逐渐改变变量的动画获得的:

@property --t {
  syntax: '<number>'; /* <- defined as type number for the transition to work */
  initial-value: 0;
  inherits: true;
}
:root {
  --t: 0;
}

@keyframes timeOn {
  50% {--t: 30}
}

html {
  animation: 30s timeOn infinite linear;
}

这是代码中唯一使用 @property 的部分。为了使其在所有浏览器中工作,我们只需在 JavaScript 中更新此变量,而不会失去在纯 CSS 中计算其他所有内容的能力。

Blob

随机性还可以与 SVG 元素一起使用,使其与 SVG 过滤器结合使用时成为强大的工具。下面的演示的灵感来自 精彩的 CSS-Tricks 文章 The Gooey Effect

请参阅 hypersphere 的 Pen Randomness in CSS with Trigonometry using SVG Circles ( @hypersphere ) 在 CodePen 上。

每个单独斑点的位置是使用简单的公式确定的。唯一的区别是我们使用 cx、cy、r 和 fill 来设置它们的样式,因为它们是 SVG 元素。

.blobs > circle {
  --x: calc(sin(var(--t) + var(--n) * 74.543 + 432.43312));
  --y: calc(cos(var(--t) + var(--n) * 2.34 + 1.432));
  --v: calc(0.5 + 0.5 * sin(var(--n) * var(--n) * 4.343 + 2.673));
  
  cx: calc(10vw + var(--x) * 80vw);
  cy: calc(10vh + var(--y) * 80vh);
  r: calc(var(--v) * 5vw + 1vw);
}

为了实现粘糊糊的效果,我们使用以下 SVG 过滤器:

<filter>
    <feGaussianBlur in="SourceGraphic" result="blur" stdDeviation="15" />
    <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 22 -11" result="goo" />
    <feBlend in2="goo" in="SourceGraphic" result="mix" />
</filter>

Memphis Pattern

最后一个演示是 我之前尝试在 CSS 中实现随机性时使用的示例的更新版本 其中我使用了模运算符。使用新的解决方案,计算更容易理解和修改。

请参阅 hypersphere 的 Pen 使用三角随机性的孟菲斯图案 ( @hypersphere )在 CodePen 上。


这篇文章也 可以在我的 Medium 博客上找到 。如果您喜欢它,请考虑前往那里并关注我以获取更多内容。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

养猫人

暂无简介

0 文章
0 评论
25 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文