我不是 web/CSS 程序员,但我需要一个看起来像 CSS 的 box-shadow 算法,并决定找出它是如何工作的。
我使用 CSSmatic 的在线 box-shadow 工具进行下面的比较。
该算法似乎有两个步骤。
第 1 步:矢量化比例和移位
如图所示,27px
CSS spread inset意味着形状被缩放到尺寸27*2
像素更小。这对于轮廓框阴影(例如27*2
像素较大)是反转的。
水平/垂直偏移是不言自明的。
第 2 步:高斯模糊
历史
Mozilla 开发人员 David Baron 在这里写了一篇关于 CSS box-shadow 实现的详细文章。
直到 2011 年,CSS 模糊半径还没有标准含义。可以对应不同浏览器的不同算法和参数:
不同的浏览器……历史上对相同的模糊半径做了不同的事情,无论是在模糊算法方面,还是在半径对该算法的意义方面(即,给定半径使事情变得多么模糊)。.... 在过去的一年中,CSS 和 HTML 规范发生了变化(对于 CSS)以定义此模糊半径的含义或(对于 HTML)以便它们在此定义上彼此一致。
这些历史差异可以解释moz-
前缀(您提到的)和webkit-
前缀的目的。这些可能会为 Mozilla 和基于 WebKit的浏览器指定要使用的替代 box-shadow 参数。
由于标准化,我希望这些前缀版本现在已被弃用,但可能用于与旧浏览器的兼容性。
标准化
根据 Baron 的说法,现在有一个精确的、标准的 box-shadow 模糊半径定义:
模糊效果现在由 css3-background 和 HTML 定义为
标准偏差 (σ) 等于给定模糊半径的一半的高斯模糊,并允许合理的近似误差。
数学家可以将其扩展为一个精确的公式。
视觉近似
通过在GIMP中反复试验,我发现通过将 CSS 模糊参数乘以 5/3(1.6666...),然后四舍五入到最接近的整数获得的高斯模糊半径会产生非常接近的视觉近似值(到 Firefox 50 中的 CSS):
7px
CSS 模糊 (Firefox 50) ~~ ceil(7 * 5/3.0) = 12.0
GIMP 中的高斯半径
30px
CSS 模糊 (Firefox 50) ~~ ceil(30 * 5/3.0) = 50.0
GIMP 中的高斯半径
75px
CSS 模糊 (Firefox 50) ~~ ceil(75 * 5/3.0) = 125.0
GIMP 中的高斯半径
执行
Ivan Kuckir 分享了一些快速的高斯模糊算法。