如何在Canvas中实现与CSS效果完全一致的对角线线性渐变
Canvas线性渐变对齐CSS效果解决方案
问题根源
当前实现和CSS渲染不一致的核心原因有两点:
- 角度适配错误:CSS的
linear-gradient角度规则与Canvas坐标系角度规则不同:CSS中0deg代表方向向上,角度顺时针递增;Canvas的2D坐标系Y轴向下,默认角度计算规则与CSS存在90度偏移。 - 渐变线长度计算错误:你当前用固定值200计算渐变终点,没有适配200*100的矩形尺寸,CSS的渐变线会自动延伸到刚好完整覆盖元素区域,渐变起止点需要根据容器尺寸动态计算。
修正后的实现代码
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); // 显式设置canvas画布尺寸,避免拉伸模糊 canvas.width = 200; canvas.height = 100; // 对应CSS里的渐变角度 const cssGradientAngle = 135; // 转换为Canvas坐标系下的弧度 const angle = (90 - cssGradientAngle) * Math.PI / 180; const dx = Math.cos(angle); const dy = Math.sin(angle); // 计算渐变线起止点,和W3C定义的CSS渐变计算逻辑对齐 const halfWidth = canvas.width / 2; const halfHeight = canvas.height / 2; const halfDiagonalLength = Math.hypot(halfWidth, halfHeight); const startX = halfWidth - dx * halfDiagonalLength; const startY = halfHeight - dy * halfDiagonalLength; const endX = halfWidth + dx * halfDiagonalLength; const endY = halfHeight + dy * halfDiagonalLength; var gradient = ctx.createLinearGradient(startX, startY, endX, endY); gradient.addColorStop(0, 'RGBA(0, 255, 0, 1)'); gradient.addColorStop(1, 'RGBA(255, 0, 0, 1)'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, canvas.width, canvas.height);
效果说明
上述代码的渐变线计算逻辑完全对齐CSS线性渐变规则,不管容器尺寸、渐变角度如何调整,都可以实现和CSS渲染完全一致的效果。
内容的提问来源于stack exchange,提问作者Roland Soós
相关产品推荐
相关产品推荐

