CANVAS画布图形合成模式演示
<style>.mama { margin: 20px auto 0; max-width: 800px; }
#canv { display: block; margin: 20px auto; border: 1px solid gray; }
#btnWrap { margin: auto; width: 750px; display: flex; gap: 6px 4px; flex-direction: row; flex-wrap: wrap; }
#btnWrap button { width: 120px; }
.tMid { text-align: center; }
</style>
<div class="mama">
<h3 class="tMid">—— globalCompositeOperation</h3>
<canvas id="canv" width="600" height="400"></canvas>
<div id="btnWrap"></div>
<p>弄清 source-* 和 destination-* :前八个合成属性为图形层级关系。source 指源,新绘制的图形;destination 指目标,已绘制好的图形。上面演示,图形分两部分:一,矩形图片是目标,是事先绘制好的图形;二,三个红蓝绿圆球,三个圆同在一张图片,这是源,是后面绘制上去的新图形。为方便理解,以下的描述将先绘制的目标图像说成现有图形,后绘制的源图像说成新图形或新绘制图形。</p>
<p>简单理解就是:上面的演示,矩形部分是先绘制好的图像,是目标即现有图形;红蓝绿圆球是一个整体,是源,后面追加绘制上去的新图形。</p>
<p>合成属性含义:</p>
<p>一、层级关系属性</p>
<p>1. source-over : 默认,在现有图形上绘制新图形;</p>
<p>2. source-in : 在现有图形上绘制新图形,现有图形变成透明;</p>
<p>3. source-out : 在现有图形之外绘制新图形,现有图形透明、现有图形之内的新绘图图形透明;</p>
<p>4. source-atop :在现有图形顶部绘制新图形,现有图形之外的新图形不显示;</p>
<p>5. destination-over : 现有图形处在新绘制图形的上层,绘制于现有图形内的新图形被覆盖;</p>
<p>6. destination-in : 在新绘制图形内显示现有图形,只有两个图形交合的部分渲染出来,其余区域透明;</p>
<p>7. destination-out : 和 destination-in 相反,在新绘制图形外显示现有图形,新绘制图形全部透明;</p>
<p>8. destination-atop : 现有图形处在新绘制图形顶层,但现有图形仅保留和新绘制图形重叠部分;</p>
<p>二、融合关系属性</p>
<p>9. lighter : 两个重叠图形的颜色通过颜色值相加来确定;</p>
<p>10. copy : copy为复制之意,只显示新图形,也就是拷贝新图形覆盖了现有图形;</p>
<p>11. xor : 形状在重叠处变为透明,并在其他地方正常绘制;</p>
<p>12. multiply : 将顶层像素与底层相应像素相乘,结果是一幅更黑暗的图片;</p>
<p>13. screen : 像素被倒转、相乘、再倒转,结果是一幅更明亮的图片(与 multiply 相反);</p>
<p>14. overlay : multiply 和 screen 的结合。原本暗的地方更暗,原本亮的地方更亮;</p>
<p>15. darken : 保留两个图层中最暗的像素;</p>
<p>16. lighten : 保留两个图层中最亮的像素;</p>
<p>17. color-dodge : 将底层除以顶层的反置;</p>
<p>18. color-burn : 将反置的底层除以顶层,然后将结果反过来;</p>
<p>19. hard-light : 类似于 overlay,multiply 和 screen 的结合,但上下图层互换了;</p>
<p>20. soft-light : 柔和版本的 hard-light。纯黑或纯白不会导致纯黑或纯白;</p>
<p>21. difference : 从顶层减去底层(或反之亦然),始终得到正值;</p>
<p>22. exclusion : 与 difference 类似,但对比度较低;</p>
<p>23. hue : 保留底层的亮度(luma)和色度(chroma),同时采用顶层的色调(hue);</p>
<p>24. saturation : 保留底层的亮度和色调,同时采用顶层的色度;</p>
<p>25. color : 保留了底层的亮度,同时采用了顶层的色调和色度;</p>
<p>26. luminosity : 保持底层的色调和色度,同时采用顶层的亮度。</p>
</div>
<script>
(function () {
let btns = [], btnlast = 0;
let ctx = canv.getContext('2d');
let img1 = new Image(), img2 = new Image;
img1.onload = () => ctx.drawImage(img1, 0, 0, 520, 320);
img2.onload = () => ctx.drawImage(img2, 300, 100, 300, 300);
img1.src = 'https://638183.freep.cn/638183/t22/51/7036.jpg';
img2.src = 'https://638183.freep.cn/638183/small/ball_rgb.png';
let draw_image = (pic1, pic2, gco = 'source-over') => {
ctx.clearRect(0,0,canv.width,canv.height);
ctx.drawImage(img1, 0, 0, 520, 320);
ctx.save();
ctx.globalCompositeOperation = gco;
ctx.drawImage(img2, 300, 100, 300, 300);
ctx.restore();
};
let ops = ['source-over','source-in','source-out','source-atop','destination-over','destination-in','destination-out','destination-atop','lighter','copy','xor','multiply','screen','overlay','darken','lighten','color-dodge','color-burn','hard-light','soft-light','difference','exclusion','hue','saturation','color','luminosity'];
ops.forEach((item, key) => {
let btn = document.createElement('button');
btns.push(btn);
btns.style.color = 'red';
btn.innerText = item.value = item;
btn.title = key + 1;
btn.onclick = () => {
draw_image(img1, img2, item);
btns.style.color = 'black';
btn.style.color = 'red';
btnlast = key;
}
btnWrap.appendChild(btn);
});
})();
</script>
占位 占位 我看不明白的。支持。 我也看不明白,但是可以尝试着套用。谢谢老师教程!{:4_180:} 亦是金 发表于 2024-3-29 09:09
我也看不明白,但是可以尝试着套用。谢谢老师教程!
{:4_190:} 庶民 发表于 2024-3-29 09:01
我看不明白的。支持。
没关系。画布是一个相当复杂的知识体系。 本帖最后由 南无月 于 2024-3-29 18:01 编辑
mix-blend-mode: normal; //正常
mix-blend-mode: multiply; //正片叠底
mix-blend-mode: screen; //滤色
mix-blend-mode: overlay; //叠加
mix-blend-mode: darken; //变暗
mix-blend-mode: lighten; //变亮
mix-blend-mode: color-dodge; //颜色减淡
mix-blend-mode: color-burn; //颜色加深
mix-blend-mode: hard-light; //强光
mix-blend-mode: soft-light; //柔光
mix-blend-mode: difference; //差值
mix-blend-mode: exclusion; //排除
mix-blend-mode: hue; //色相
mix-blend-mode: saturation; //饱和度
mix-blend-mode: color; //颜色
mix-blend-mode: luminosity; //亮度
mix-blend-mode: initial; //初始
mix-blend-mode: inherit; //继承
mix-blend-mode: unset; //复原
我记的相关滤镜笔记抄过来一份。。这个跟老师第二部分融合密切相关
一直觉得演示的代码要极其复杂。。。
两三个选项已是不容易。。
这一下子整出26个按纽。。
好壮观啊。。。{:4_199:}
南无月 发表于 2024-3-29 17:59
mix-blend-mode: normal; //正常
mix-blend-mode: multiply; //正片叠底
mix-blend-mode: screen; //滤 ...
对,颜色融合相关差不多,画布的要丰富一些 南无月 发表于 2024-3-29 18:03
一直觉得演示的代码要极其复杂。。。
两三个选项已是不容易。。
这一下子整出26个按纽。。
工厂模式,批量生产 这么多东西,哈哈,忽然觉得脑容量不够用了{:4_173:} 虽然内容多,但一个个看下来,这些效果好神奇啊,运用得好,会产生意想不到的效果呢{:4_199:} “弄清 source-* 和 destination-* :前八个合成属性为图形层级关系。source 指源,新绘制的图形;destination 指目标,已绘制好的图形。”
这样一分类,前八个就好理解多了。后来居上,后来的源对目标发起攻击{:4_173:}
目标岿然不动,对源产生各种互动{:4_173:}
后面的那些和颜色融合有相似之处。这样一分,的确好理解多了{:4_187:} 马黑黑 发表于 2024-3-29 18:09
对,颜色融合相关差不多,画布的要丰富一些
{:4_199:}二者知识点可以互通有无。。帮助理解 南无月 发表于 2024-3-29 17:59
mix-blend-mode: normal; //正常
mix-blend-mode: multiply; //正片叠底
mix-blend-mode: screen; //滤 ...
月儿把这个发来对照,真不错{:4_187:} 马黑黑 发表于 2024-3-29 18:10
工厂模式,批量生产
按纽批量生产容易理解。。
产生相应的26个图片效果,我来安排的话估计它们会打架。。{:4_170:}
这个对应的好复杂呀 红影 发表于 2024-3-29 20:32
月儿把这个发来对照,真不错
这个做贴子常用的一些滤镜,我看跟这里的融合也是对应的{:4_173:} “xor : 形状在重叠处变为透明,并在其他地方正常绘制”
这个可以弄个人物剪影了{:4_173:} 红影 发表于 2024-3-29 20:35
“xor : 形状在重叠处变为透明,并在其他地方正常绘制”
这个可以弄个人物剪影了
是的,还可以弄真正的空心字