ZetCode

JavaScript Canvas globalCompositeOperation 教程

最后修改于 2025 年 4 月 3 日

本教程将探讨 JavaScript 中 Canvas 的 globalCompositeOperation 属性。它控制新绘制的内容如何与现有画布内容进行合成。掌握此属性可实现高级视觉效果和混合模式。

基本定义

globalCompositeOperation 决定了形状和图像如何在画布上绘制。它影响新内容与现有像素之间的混合。该属性接受各种字符串值,这些值定义了不同的合成操作。

常见操作包括 'source-over'(默认)、'multiply'、'screen'、'overlay' 和 'destination-out'。每种操作都通过以不同方式组合源像素和目标像素来创建独特的视觉效果。

基本 source-over 示例

此示例演示了默认的 'source-over' 合成操作。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Source-over Example</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Draw blue rectangle
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 100, 100);
    
    // Draw red rectangle with default source-over
    ctx.fillStyle = 'red';
    ctx.globalCompositeOperation = 'source-over';
    ctx.fillRect(100, 100, 100, 100);
</script>

</body>
</html>

此示例首先绘制一个蓝色矩形,然后绘制一个重叠的红色矩形。默认的 'source-over' 操作使红色矩形显示在上方。

新绘制的内容(源)放置在现有内容(目标)之上。这是在没有显式合成的情况下绘制到画布的标准行为。

destination-over 示例

此示例展示了 'destination-over' 如何将现有内容置于新绘制的内容之上。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Destination-over Example</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Draw blue rectangle
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 100, 100);
    
    // Draw red rectangle with destination-over
    ctx.fillStyle = 'red';
    ctx.globalCompositeOperation = 'destination-over';
    ctx.fillRect(100, 100, 100, 100);
</script>

</body>
</html>

在这里,我们首先绘制一个蓝色矩形,然后设置 'destination-over',接着绘制红色。这将使现有的蓝色矩形显示在新红色矩形之上。

'destination-over' 在您想绘制到现有内容后面时很有用。它常用于创建背景效果或水印类视觉效果。

multiply 示例

此示例演示了 'multiply' 混合模式,该模式使颜色变暗。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Multiply Example</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Draw yellow rectangle
    ctx.fillStyle = 'yellow';
    ctx.fillRect(50, 50, 100, 100);
    
    // Draw blue rectangle with multiply
    ctx.fillStyle = 'blue';
    ctx.globalCompositeOperation = 'multiply';
    ctx.fillRect(100, 100, 100, 100);
</script>

</body>
</html>

此示例首先绘制一个黄色矩形,然后绘制一个带有 'multiply' 的蓝色矩形。重叠区域变为绿色(在 RGB 颜色模型中,黄色 × 蓝色 = 绿色)。

'multiply' 会将源像素和目标像素的颜色通道相乘。它非常适合创建阴影效果或模拟彩色透明滤镜。

screen 示例

此示例显示了 'screen' 操作,该操作使颜色变亮。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Screen Example</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Draw red rectangle
    ctx.fillStyle = 'red';
    ctx.fillRect(50, 50, 100, 100);
    
    // Draw green rectangle with screen
    ctx.fillStyle = 'green';
    ctx.globalCompositeOperation = 'screen';
    ctx.fillRect(100, 100, 100, 100);
</script>

</body>
</html>

在这里,我们绘制一个红色矩形,然后用 'screen' 操作绘制一个绿色矩形。重叠区域变为黄色(在加法混合中,红色 + 绿色 = 黄色)。

'screen' 会反转、相乘,然后再次反转,产生更亮的结果。它可用于创建发光效果或模拟光束重叠。

destination-out 示例

此示例演示了 'destination-out',该操作会擦除现有内容。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Destination-out Example</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Draw blue rectangle
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 200, 100);
    
    // Erase part with destination-out
    ctx.globalCompositeOperation = 'destination-out';
    ctx.beginPath();
    ctx.arc(150, 100, 50, 0, Math.PI * 2);
    ctx.fill();
</script>

</body>
</html>

此示例首先绘制一个蓝色矩形,然后使用带圆形的 'destination-out'。圆形充当橡皮擦,在矩形中创建一个孔。

'destination-out' 仅在源像素未重叠的地方显示目标内容。它常用于创建蒙版或从现有图形中裁剪形状。

来源

MDN globalCompositeOperation 文档

本教程涵盖了关键的 globalCompositeOperation 模式及实际示例。尝试这些操作可以极大地增强您的画布图形能力和视觉效果。

作者

我的名字是 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 JS Canvas 教程