a pure css implementation of some sunlight streaming in through the window

A Pure CSS Implementation of Sunlight Streaming Through a Window

纯 CSS 实现:模拟阳光穿过窗户的效果

Inspired by daylightcomputer.com and sunlit.place, this project uses basic div elements with background images. I sourced the leaves from Adobe Stock and downscaled them to ~300x500, knowing I would be blurring them anyway.

daylightcomputer.comsunlit.place 的启发,本项目完全由带有背景图的 div 元素构成。叶子的素材来自 Adobe Stock,我将其缩小到约 300x500 像素,因为我预料到后续会进行模糊处理。

<div id="blinds">
  <div class="shutters">
    <div class="shutter"></div>
    ...
    <div class="shutter"></div>
  </div>
  <div class="vertical">
    <div class="bar"></div>
    <div class="bar"></div>
  </div>
</div>

Progressive Blur

渐进式模糊

To make the diffusion effect convincing, objects closer to the wall should be less blurry than those further away. This utilizes multiple blur layers, each with a mask image to constrain its effect zone.

为了让光影的漫反射效果更逼真,靠近墙壁的物体应该比远离墙壁的物体模糊度更低。这里使用了多个模糊图层,每个图层都配有一个遮罩图像(mask image)来限制其作用区域。

#progressive-blur { position: absolute; height: 100%; width: 100%; }
#progressive-blur>div { 
  position: absolute; height: 100%; width: 100%; inset: 0; 
  backdrop-filter: blur(var(--blur-amount)); 
  mask-image: linear-gradient(252deg, transparent, transparent var(--stop1), black var(--stop2), black); 
}
/* ... (blur layers defined here) */

Leaf Billowing

叶片飘动

I created a leaf billowing effect using small amounts of rotate and scale for dynamism. I used SVG filters and the lesser-known feTurbulence and feDisplacementMap tags to add a higher octave of noise to make individual leaves billow.

我通过少量的 rotate(旋转)和 scale(缩放)来增加动态感,从而创造出叶片飘动的效果。我使用了 SVG 滤镜以及较少见的 feTurbulencefeDisplacementMap 标签,通过增加更高倍频的噪点,让每一片叶子都能产生飘动感。

/* SVG filter for wind effect */
<filter id="wind" ...>
  <feTurbulence type="fractalNoise" numOctaves="2" seed="1">
    <animate attributeName="baseFrequency" ... />
  </feTurbulence>
  <feDisplacementMap in="SourceGraphic">
    <animate attributeName="scale" ... />
  </feDisplacementMap>
</filter>

Sunrise/Sunset Transitions

日出/日落过渡

The light/dark transition was initially too abrupt, so I added a transition between the two. A simple linear interpolation of colors wasn’t exciting enough, so I created a sunrise/sunset color animation. These colors were handpicked after observing many sunsets and some experimentation. There is also a subtle “glow” that acts as a crude approximation of light bouncing off the floor.

起初,明暗之间的切换过于生硬,所以我增加了一个过渡效果。简单的线性颜色插值不够生动,因此我制作了一个日出/日落的色彩动画。这些颜色是我在观察了多次日落并经过多次实验后手动挑选的。此外,还有一个微妙的“光晕”效果,作为光线在地板上反射的粗略模拟。

3D Transform

3D 变换

Finally, standard skew + rotate + transform didn’t yield the desired result because they only provide affine transforms, and I wanted that specific perspective distortion. I decided to derive a transform matrix by drawing shapes in Desmos and solving for a 4D perspective transform matrix that matrix3d can use in CSS.

最后,标准的 skew(倾斜)+ rotate(旋转)+ transform(变换)无法达到我想要的效果,因为它们只能提供仿射变换,而我需要那种特定的透视畸变。我决定通过在 Desmos 中绘制形状,并求解出一个 4D 透视变换矩阵,以便在 CSS 中使用 matrix3d

(Python script for calculating the homography matrix omitted for brevity) (为简洁起见,此处省略计算单应性矩阵的 Python 脚本)