用canvas模拟日落余晖需先绘纯色建筑剪影,再以createlineargradient构建西偏南方向暖色渐变光照层,通过globalcompositeoperation='overlay'叠加,并辅以阴影柔化与天际微光提升立体感。

用 Canvas 的 createLinearGradient 模拟日落余晖打在建筑侧影上的光影,关键不是“画光”,而是用渐变色块精准覆盖建筑轮廓的受光面,并随太阳方位动态偏移方向与冷暖过渡——它本质是静态剪影 + 动态光照层的叠加。
一、先画建筑剪影(纯色遮罩层)
建筑本身不发光,只反射光。所以第一步是用不透明纯色(如 #2c3e50)绘制建筑外轮廓或简化几何体(矩形、多边形),作为“接受光照的基底”:
- 用
beginPath()+lineTo()或rect()勾勒建筑侧视剪影(建议只保留左侧/右侧边缘,体现“侧影”) - 填充时设
ctx.fillStyle = '#2c3e50',不加任何透明度,确保后续渐变能清晰叠加 - 若需多栋建筑,每栋单独绘制并保存其边界框(x, y, width, height),方便后续渐变定位
二、构建日落线性渐变(核心光照层)
日落余晖是低角度、暖色调、方向性强的平行光。用 createLinearGradient(x0, y0, x1, y1) 模拟其投射方向:
- 设光源方向为西偏南:例如太阳在画面右下方,渐变起点
(x0, y0)取建筑右侧中点,终点(x1, y1)向右下延伸(如x1 = x0 + 80, y1 = y0 + 40) - 颜色停靠点按真实日落逻辑设置:
gradient.addColorStop(0, 'rgba(255, 220, 160, 0.7)')—— 高亮暖黄(直射面)gradient.addColorStop(0.5, 'rgba(255, 140, 60, 0.4)')—— 中段橙红(过渡区)gradient.addColorStop(1, 'rgba(200, 80, 40, 0)')—— 暗端消隐(背光边缘) - 渐变必须覆盖整栋建筑区域,推荐用建筑包围盒计算起止点,避免局部漏光
三、用 globalCompositeOperation='overlay' 叠加光影
直接 fill 渐变会盖掉建筑,要用混合模式让光“贴合”在剪影上:
- 绘制完建筑剪影后,不调用 clearRect,保持画布状态
- 设置
ctx.globalCompositeOperation = 'overlay'—— 它会让渐变在暗部提亮、亮部加深,自然模拟侧光对立体结构的强化 - 用该渐变 fill 同一个建筑路径(或用
clip()先裁剪到建筑形状内再 fill,更安全) - 绘制完毕立即恢复
ctx.globalCompositeOperation = 'source-over',防止影响后续元素
四、增强真实感的细节处理
仅渐变仍显平面,加入两个轻量技巧立刻提升体积感:
-
边缘柔化:在叠加光影前,给建筑路径加
ctx.shadowBlur = 3–6、shadowColor = 'rgba(0,0,0,0.15)',制造微弱环境光漫射 -
天际微光晕:在建筑顶部上方,用
createRadialGradient画一个极淡的暖白光斑(rgba(255,245,220,0.08)),filter: blur(12px)后 drawImage 到主画布,模拟天空散射光补亮屋檐 - 若需动态效果(如太阳缓慢西沉),只需每帧更新渐变的
(x1, y1)坐标和颜色停靠点透明度,用requestAnimationFrame驱动即可











