You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中为各类形状添加带混合模式的平滑内阴影?

实现带混合模式的平滑内阴影(复刻Photoshop效果)

太懂这种被一个视觉效果逼到崩溃的感觉了!我之前也在复刻Photoshop内阴影的时候踩过XOR的坑,边缘锯齿真的让人抓狂。其实换个思路,用离屏Canvas+裁剪的方法,就能完美实现带任意混合模式的平滑内阴影,而且对所有形状都适用。

核心思路

XOR合成之所以会破坏边缘平滑度,是因为它直接对像素做异或运算,会丢失半透明的反锯齿像素。而我们可以利用原生阴影的平滑特性,通过以下步骤把外阴影“转化”为内阴影:

  1. 在离屏Canvas上生成形状的反向偏移外阴影(偏移方向和内阴影相反)
  2. 回到主Canvas,用目标形状作为裁剪区域
  3. 将离屏的阴影绘制到裁剪区域内,同时应用需要的混合模式

这种方法既保留了shadowBlur原生的平滑反锯齿,又能支持所有Canvas的混合模式。

完整代码实现

下面是一个通用的内阴影绘制函数,支持任意形状和混合模式:

function drawInnerShadow(ctx, shapePath, shadowOptions) {
  // 解构阴影参数,默认值兜底
  const {
    x = 3,
    y = 3,
    blur = 5,
    color = 'rgba(0,0,0,0.5)',
    blendMode = 'normal'
  } = shadowOptions;
  
  // 创建与主画布同尺寸的离屏Canvas
  const offscreenCanvas = document.createElement('canvas');
  offscreenCanvas.width = ctx.canvas.width;
  offscreenCanvas.height = ctx.canvas.height;
  const offCtx = offscreenCanvas.getContext('2d');
  
  // 步骤1:在离屏Canvas生成反向偏移的外阴影
  offCtx.save();
  offCtx.shadowColor = color;
  offCtx.shadowBlur = blur;
  // 反向偏移:外阴影向外,内阴影向内,所以取反偏移量
  offCtx.shadowOffsetX = -x;
  offCtx.shadowOffsetY = -y;
  // 绘制透明形状,只保留阴影
  offCtx.fillStyle = 'transparent';
  offCtx.fill(shapePath);
  offCtx.restore();
  
  // 步骤2:回到主Canvas绘制内阴影
  ctx.save();
  
  // 先绘制原形状(确保裁剪区域基于这个形状)
  ctx.fill(shapePath);
  
  // 设置裁剪区域:只有形状内部的区域会被绘制
  ctx.clip();
  
  // 应用指定的混合模式
  ctx.globalCompositeOperation = blendMode;
  
  // 绘制离屏的阴影,此时阴影只会显示在裁剪区域内(即形状内部)
  ctx.drawImage(offscreenCanvas, 0, 0);
  
  // 恢复画布状态
  ctx.restore();
}

// ------------------------------
// 使用示例:带Overlay混合模式的圆角矩形内阴影
// ------------------------------
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
canvas.width = 300;
canvas.height = 250;

// 创建圆角矩形路径(支持任意Path2D形状)
const rectPath = new Path2D();
rectPath.roundRect(50, 50, 200, 150, 20);

// 1. 先绘制形状的基础底色
ctx.fillStyle = '#f5f5f5';
ctx.fill(rectPath);

// 2. 绘制内阴影(参数可自定义)
drawInnerShadow(ctx, rectPath, {
  x: 6,
  y: 6,
  blur: 12,
  color: 'rgba(0,0,0,0.6)',
  blendMode: 'overlay'
});

关键优势

  • 完美平滑边缘:利用原生shadowBlur生成阴影,反锯齿完全保留,不会出现XOR方法的边缘瑕疵
  • 全混合模式支持:直接通过globalCompositeOperation设置,支持overlay、multiply、screen等所有Canvas混合模式
  • 适配任意形状:只要能创建Path2D对象的图形(矩形、圆形、自定义路径等)都能适用
  • 性能友好:仅使用一次离屏Canvas绘制,不会有过多的图层合成开销

注意事项

  • 离屏Canvas的尺寸必须和主Canvas一致,避免缩放导致的阴影模糊
  • 如果目标形状是描边样式,裁剪时需要考虑描边宽度(可以用Path2D的addPath结合ctx.lineWidth调整路径范围)
  • 阴影偏移量的方向:内阴影想向左上方偏移,就把x和y设为正数(因为代码里会取反生成反向外阴影)

内容的提问来源于stack exchange,提问作者Tyler John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:22:02