为了账号安全,请及时绑定邮箱和手机立即绑定

如果我有 2 个画布在彼此之上,是否可以实现 html 画布复合操作“更轻”?

如果我有 2 个画布在彼此之上,是否可以实现 html 画布复合操作“更轻”?

犯罪嫌疑人X 2022-01-13 10:56:00
我想在绿色画布上显示白色到透明的渐变。我不希望渐变变暗,所以我使用“较轻”的复合操作。这完美地工作。第一个渐变是我想要的。它逐渐从白色变为背景,第二个渐变使用 source-over 并且从白色变为深色。那不是我想要的。var ac = a.getContext('2d');// green backgroundac.fillStyle = 'green';ac.fillRect(0, 0, 100, 100);// white-to-transparent gradient but lighter COvar g = ac.createLinearGradient(20, 0, 80, 0);g.addColorStop(0, 'white');g.addColorStop(1, 'transparent');ac.fillStyle = g;ac.globalCompositeOperation = 'lighter';ac.fillRect(20, 20, 60, 10);// white-to-transparent gradientac.globalCompositeOperation = 'source-over';ac.fillRect(20, 40, 60, 10);<canvas id="a" width=100 height=100></canvas>因为在实际代码中我使用复杂的合成,并且出于性能原因,我决定将它分成两个画布。背景画布为绿色,渐变显示在顶部。问题是“打火机”现在不起作用。是否有可能达到与前一种情况相同的结果?var bc = b1.getContext('2d');// green backgroundbc.fillStyle = 'green';bc.fillRect(0, 0, 100, 100);var bc = b2.getContext('2d');// white-to-transparent gradient but lighter COvar g = bc.createLinearGradient(20, 0, 80, 0);g.addColorStop(0, 'white');g.addColorStop(1, 'transparent');bc.fillStyle = g;bc.globalCompositeOperation = 'lighter';bc.fillRect(20, 20, 60, 10);// white-to-transparent gradientbc.globalCompositeOperation = 'source-over';bc.fillRect(20, 40, 60, 10);// white-to-#ffffff00 gradient source-overvar g = bc.createLinearGradient(20, 0, 80, 0);g.addColorStop(0, 'white');g.addColorStop(1, '#ffffff00');bc.globalCompositeOperation = 'source-over';bc.fillRect(20, 60, 60, 10);// white-to-#00000000 gradient source-overvar g = bc.createLinearGradient(20, 0, 80, 0);g.addColorStop(0, 'white');g.addColorStop(1, '#00000000');bc.globalCompositeOperation = 'source-over';bc.fillRect(20, 80, 60, 10);<div>  <canvas id="b1" width=100 height=100 style="position: fixed; left: 0; top: 0;"></canvas>    <canvas id="b2" width=100 height=100 style="position: fixed; left: 5px; top: 5px; border: 1px solid red;"></canvas></div>如您所见,没有一种组合可以达到相同的结果。我不能使用白色到绿色的渐变,因为在真实的代码背景中不仅仅是绿色。在这些演示中,我使用绿色来演示它。那么这甚至可能吗?如何达到同样的效果?
查看完整描述

1 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

画布合成操作仅适用于源画布,并且仅在绘制时起作用。如果你想在两个画布元素之间应用效果,你需要求助于普通的 CSS,比如mix-blend-mode(虽然不一样)


如果你想避免重新绘制整个背景,你可以有一个单独的(可能是屏幕外的)画布,并将其复制到你的最终图像drawImage


var bc1 = b1.getContext('2d');

// green background

bc1.fillStyle = 'green';

bc1.fillRect(0, 0, 100, 100);


var bc2 = b2.getContext('2d');

bc2.drawImage(b1, 0, 0);

// white-to-transparent gradient but lighter CO

var g = bc2.createLinearGradient(20, 0, 80, 0);

g.addColorStop(0, 'white');

g.addColorStop(1, 'transparent');

bc2.fillStyle = g;

bc2.globalCompositeOperation = 'lighter';

bc2.fillRect(20, 20, 60, 10);

// white-to-transparent gradient

bc2.globalCompositeOperation = 'source-over';

bc2.fillRect(20, 40, 60, 10);

// white-to-#ffffff00 gradient source-over

var g = bc2.createLinearGradient(20, 0, 80, 0);

g.addColorStop(0, 'white');

g.addColorStop(1, '#ffffff00');

bc2.globalCompositeOperation = 'source-over';

bc2.fillRect(20, 60, 60, 10);

// white-to-#00000000 gradient source-over

var g = bc2.createLinearGradient(20, 0, 80, 0);

g.addColorStop(0, 'white');

g.addColorStop(1, '#00000000');

bc2.globalCompositeOperation = 'source-over';

bc2.fillRect(20, 80, 60, 10);

#b1 {

  display: none

}


#b2 {

  position: fixed;

  left: 5px;

  top: 5px;

  border: 1px solid red;

}

<div>

  <canvas id="b1" width="100" height="100"></canvas>

  <canvas id="b2" width="100" height="100"></canvas>

</div>


查看完整回答
反对 回复 2022-01-13
  • 1 回答
  • 0 关注
  • 131 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信