【问题标题】:How is a CSS gradient path calculated?CSS渐变路径是如何计算的?
【发布时间】:2017-05-20 12:18:31
【问题描述】:

当使用线性渐变时,例如

div {
  width: 300px;
  height: 50px;
  background: linear-gradient(to right, blue, red);
}
<div></div>

颜色可以通过不同的路径改变。

在上面的示例中,可以通过线性修改R 和B 通道来完成,而不触及G 通道——但变化也可以是非线性的(例如,提供,一种线性感,因为它更符合生理性),或者通过修补G 频道(再次因为它在我们眼中似乎是更真实的“红到蓝过渡”)。

linear-gradient 中用于在两种颜色之间切换的公式是什么?

【问题讨论】:

  • 试试:background: linear-gradient(to right, blue 50% , red 50%); 看看它的作用:) 并阅读developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient 开始了解它的工作原理以及如何使用它;)
  • @GCyrillus:我不明白你的评论。我知道linear-gradient 是什么以及如何使用它。我不知道是什么 formula 用于从一种颜色过渡到另一种颜色。可以使用线性转换(在轴上以相等的步长从 0 到 254(因此每个均匀的通道中的数值变化相同)或使用转换先慢后快的公式(例如,抛物线的) )因为(这只是一个例子)它看起来更好(更线性)我们的眼睛(它们本身是高度非线性的。您提供的链接根本没有讨论这个。
  • @GCyrillus (cont) 也许这只是一个线性过渡,但在那种情况下,像 (100,212,34) 到 (2,28,133) 这样的东西在视觉上可能不是从第一种颜色到第二个(因为它是一种与这两者无关的颜色)。深入来说,我想知道这些转换是否添加了生理成分,或者它只是一个数学线性函数。
  • 我相信这只是从 steps 到 steps 的线性过渡,它因绘制区域的大小而异。我们看到的(紫色)不是我们所期望的。如果您不设置任何值,两种颜色都会从一侧喷涂到另一侧,并在褪色时混合。 :) (编辑:尝试蓝色或红色之外的透明颜色)
  • 刚刚添加了codepen.io/anon/pen/egmbyB 来说明我的评论;)

标签: css algorithm colors linear-gradients


【解决方案1】:

HTML/CSS 中的渐变是线性插值,纯数学。根据 W3C 画布规范:

创建渐变后(见下文),会沿渐变放置色标,以定义颜色沿渐变的分布方式。每个停靠点的渐变颜色是为该停靠点指定的颜色。在每个这样的停止之间,颜色和 alpha 分量必须在 RGBA 空间上进行线性插值,而无需预先乘以 alpha 值来找到在该偏移处使用的颜色。在第一站之前,颜色必须是第一站的颜色。在最后一站之后,颜色必须是最后一站的颜色。当没有停止时,渐变为透明黑色。

SVG 的工作方式相同。

CSS 渐变是相同的,除了一个区别(强调我的):

在两个色标之间,线条的颜色在两个色标的颜色之间进行插值,插值发生在 预乘 RGBA 空间中。

所以这三个都使用线性插值,canvas/SVG 使用非预乘 alpha,而 CSS 使用预乘 alpha(看起来确实更好)。至于为什么会有所不同,请参见以下示例:

html, body, svg, div {
  display: block;
  width: 100%;
  height: 100%;
  margin: 0; 
  padding: 0;
  background: white;
}
svg {height: 60%;}
div.gradient {
  height: 20%;
  margin-top: 0.2%;
  background: linear-gradient(to right,
  rgba(0%, 100%, 0%, 1),
  rgba(0,0,0,0));
}
<svg>
  <linearGradient id="a">
    <stop offset="0" stop-color="lime"
      stop-opacity="1" />
    <stop offset="1" stop-color="lime"
      stop-opacity="0" />
  </linearGradient>
  <linearGradient id="b">
    <stop offset="0" stop-color="lime"
      stop-opacity="1" />
    <stop offset="1" stop-color="black"
      stop-opacity="0" />
  </linearGradient>
  <linearGradient id="c">
    <stop offset="0" stop-color="rgba(0%, 100%, 0%, 1)" />
    <stop offset="1" stop-color="rgba(0,0,0,0)" />
  </linearGradient>
  <rect width="100%" height="33%"
    fill="url(#a)" />
  <rect width="100%" height="33%" y="33.5%"
    fill="url(#b)" />
  <rect width="100%" height="33%" y="67%"
    fill="url(#c)" />
</svg>
<div class="gradient"></div>
<ul>
  <li>Top: SVG gradient with constant stop-color and transitioned stop-opacity;</li>
  <li>2nd: SVG gradient with stop-color transitioning to black and stop-opacity transitioning to zero;</li>
  <li>3rd: SVG gradient with rgba colors;</li>
  <li>Bottom: CSS gradient with the same rgba colors.</li>
</ul>
<p>All transition from opaque lime to fully transparent; in all but the first SVG gradient, the final stop is transparent black.  The CSS gradient scales the intensity of the color by the alpha value before transitioning, so you don't get the fade to gray effect.</p>

免责声明:那不是我的 sn-p!我从这个CodePen example 中获取了它,但是如果我自己不添加代码,我不会让我链接到它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多