为照片添加 CSS 光晕效果,打造明亮的视觉效果

Avatar of Shimin Zhang
张世敏

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 价值 200 美元的免费信用额度!

我非常喜欢 J.J. Abrams 导演的电影。 我喜欢它们紧凑的剧情、俏皮的对话,当然还有:变形镜头光晕像 Abrams 这样的电影制作人使用镜头光晕 为他们的电影增添一抹“自制”的真实感,这是一种我们可以轻松地在 Photoshop 等工具中重现的技术,然后将其作为光栅图像添加到我们的网站中。

但如果我们想在不使用照片编辑工具的情况下应用相同的光晕效果呢? 我们可以创建 CSS 光晕来为我们的画廊图像、背景照片或用户资料增添电影般的触感。

摄影中存在不同类型的光晕。 我们正在使用的是一种称为伪影的光晕,因为它们会在光线进入镜头并反射到镜头表面时留下小的光斑,这些光斑呈现出相机光圈的形状。

A diagram showing how light enters a camera lens at various angles to create a flare.
来源: 维基百科

这是一个很好的例子,展示了我们要制作的那种光晕,直接从 J.J. Abrams 的电影剧照中提取出来,当然了

An example of the CSS lens flare we are making, showing a flare to the right of an actor in a still from the 2009 Star Trek movie
星际迷航 (2009)

上面的光晕包含几个部分。 让我们列出它们,以便我们知道要实现的目标

  1. 中心光源呈现为一个发光的球形光。
  2. 有一些水平椭圆形光线——光线被扭曲和模糊,形成细长的椭圆。
  3. 随机的光线以不同的角度从中心光源射出。

我们从下面的 HTML 元素开始,它们映射到我们的光晕组件。 存在一个中心光源和两个非对角圆形光晕、三个水平镜头光晕和三个锥形光线状光晕。

<div class="lens-center"></div>
    <div class="circle-1"></div>
    <div class="circle-2"></div>
    <div class="left-flare horizontal-flare"></div>
    <div class="right-flare horizontal-flare"></div>
    <div class="full-flare horizontal-flare"></div>
    <div class="conic-1"></div>
    <div class="conic-2"></div>
    <div class="conic-3"></div>
</div>

最后,为了使我们的光晕能够真实地叠加在图像上,它的中心光源必须是可调整的。 这样,我们就可以将它放置在图片上的一个可信的现有光源上,并且不会与任何面部重叠。

CSS 光晕的背景和光源

让我们从 CSS 光晕的黑色背景和中心光源开始。 大多数 网络上的渐变 都是具有纯色过渡的线性渐变,但我们可以将 alpha 通道应用于它们,这实际上是产生发光效果的好方法。 带有多层半透明颜色的圆形径向渐变为我们提供了良好的相机中心效果。

background: radial-gradient(
  closest-side circle at center,
  hsl(4 5% 100% / 100%) 0%,
  hsl(4 5% 100% / 100%) 15%,
  hsl(4 10% 70% / 70%) 30%,
  hsl(4 0% 50% / 30%) 55%,
  hsl(4 0% 10% / 5%) 75%,
  transparent 99
);
filter: blur(4px);

对 HSL 语法感到好奇吗? 它很新,并且似乎是 在所有 CSS 颜色函数中定义 alpha 透明度的未来方向

请注意,我们正在使用 CSS 模糊滤镜 来使渐变看起来更像漫射光层。

现在我们知道了如何添加圆形光晕,我们还将在光源后面添加一个更大的漫射光晕,以及三个额外的光晕,这些光晕与中心成 45deg 角,使效果看起来更加逼真。

设置水平光线

让我们从水平光晕开始。 我们可以采取一些方法,一个非常细长的椭圆渐变是最简单的方法。 但是,我注意到水平光晕通常不像我的参考照片中的那么对称,因此我想让我的光晕也稍微不对称一些。

幸运的是,径向渐变在 CSS 中有一个可选的位置参数。 我们可以创建相同水平光晕的两个大小略有不同的左右部分,并且颜色略有不同。 我们还可以添加一个不透明度滤镜,以使水平光晕与中心交汇的区域变得不那么突兀。

background: radial-gradient(
  closest-side circle at center,
  transparent 50%,
  hsl(4 10% 70% / 40%) 90%,
  transparent 100%
);
filter: blur(5px);

趁此机会,让我们在视窗底部三分之二处添加一个完整的细长椭圆形底部光晕,以增添另一抹“真实感”。

创建漫射光线

在径向光晕和水平光晕到位之后,我们剩下的就是从光源射出的倾斜光线。 我们可以添加额外的椭圆径向渐变,然后倾斜和平移容器,以获得近似效果。 但我们也有一个已经为这项工作而设计的 CSS 渐变,即锥形渐变。 下面是一个示例,它在距容器右下角 5deg 的位置提供一个 7deg 锥形渐变。

background: conic-gradient(
  from 5deg at 0% 100%,
  transparent 0deg,
  hsl(4 10% 70% / 30%) 7deg,
  transparent 15deg
);
transform-origin: bottom left;
transform: rotate(-45deg);

我们将添加一些以光晕中心为中心的锥形渐变,并具有各种半透明颜色的渐变角度。 由于锥形渐变会显示其容器 div 的角,因此我们将使用光源作为原点对其进行旋转变换,从而产生偏移漫射光线滤镜效果。

使用 CSS 自定义属性创建更灵活的光晕

到目前为止,我们已经创建了一个响应式但位置固定的光晕效果,它位于固定位置。 在不破坏周围的水平光晕和锥形光晕的情况下,很难调整光晕的中心。

为了使 CSS 光晕既可调整又更不容易损坏,我们将通过一组自定义属性公开光源光晕的位置、大小和色调。

:root {
  --hue: 4;
  --lens-center-size: 40%;
  --lens-spread-size: 80%;
  --lens-left: 55%;
  --lens-top: 15%;
}

趁此机会,我们还将调整光晕的色调和水平光晕的高度。 对于水平光晕的宽度,我们使用 CSS 变量重载 使它们可以独立调整; 否则,我们将回退到光源光晕中心或图像中心。

.left-flare {
  width: var(--left-flare-width, var(--lens-left, 50%));
}

这就是完成的 CSS 光晕效果的样子,它具有照片背景,并且光晕向上移动,使光源位置看起来很可信。 继续,添加您自己的照片,看看它在不同环境中的效果!

其他 CSS 和非 CSS 光晕示例

当然,这只是创建 CSS 光晕的一种方法。 我喜欢这种方法,因为它在光晕及其各个部分的颜色、大小和位置方面很灵活。 这使得它成为一个更可重复使用的组件,可以在许多环境中使用。

这是 Keith Grant 创建的一个示例,它使用线性渐变和 CSS 自定义属性。 然后,它添加了一些 JavaScript 代码,以随机化 HSLA 值。

Nicholas Guest 创建了另一个 CSS 光晕,它在 .flare 元素的 ::before::after 伪元素上应用了盒子阴影来实现效果,另外还添加了一点 jQuery 代码,使光晕在悬停时跟随鼠标移动。

这个示例使用 Canvas 创建,它很巧妙,因为它让光源在悬停时跟随鼠标移动,同时显示了光源位置发生变化时光晕伪影的位置也会发生变化。

这里也有类似的想法

还有一个有趣的示例使用 GSAP、Canvas 和一个名为 JS.LensFlare 的库。

您将如何处理 CSS 光晕效果? 在评论中分享您的想法!