合成
合成就是常见的蒙板状态,本质上就是如何进行图形的压盖,可以通过设置globalCompositeOperation
属性的值来决定采用什么样的遮盖策略。我们可以先画一个具有重叠关系的方形和圆形:
<script>
window.onload = function() {
let canvas = document.getElementById('test')
if(canvas.getContext) {
let ctx = canvas.getContext('2d')
ctx.fillStyle = 'green'
ctx.fillRect(100, 100, 100, 100)
ctx.fillStyle = 'pink'
ctx.arc(200, 200, 60, 0, 7, false)
ctx.fill()
}
}
</script>
</head>
<body>
<canvas id="test" width="800" height="500" style="background-color: blanchedalmond;"></canvas>
</body>
效果
globalCompositeOperation
默认值为source-over
- 当
globalCompositeOperation = 'source-in'
,新图形只在新图形和目标画布重叠的地方绘制。其他的都是透明的。 - 当
globalCompositeOperation = 'source-out'
,在不与现有画布内容重叠的地方绘制新图形
- 当
globalCompositeOperation = 'source-atop'
,新图形只在与现有画布内容重叠的地方绘制。 - 当
globalCompositeOperation = 'destination-over'
,在现有的画布内容后面绘制新的图形。 - 当
globalCompositeOperation = 'destination-in'
,现有的画布内容保持在新图形和现有画布内容重叠的位置。其他的都是透明的。 - 当
globalCompositeOperation = 'destination-out'
,现有内容保持在新图形不重叠的地方。
更多globalCompositeOperation
的取值可以查看:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Compositing。
案例 —— 刮刮乐
实现思路:将<canvas>
画布定义在一个<div>
中,用画布覆盖掉div
中的文字,利用globalCompositeOperation = 'destination-out'
这个属性值,以及在鼠标移动事件发生时创建的一个透明圆形实现擦除效果。
<head>
<style>
div{
border: 1px solid black;
width: 250px;
height: 60px;
font-size: 40px;
line-height: 60px;
text-align: center;
position: relative;
user-select: none;
}
canvas{
position: absolute;
left: 0;
top: 0;
}
</style>
<script>
window.onload =function() {
let canvas = document.getElementById('test')
if(canvas.getContext) {
let ctx = canvas.getContext('2d')
ctx.fillStyle = 'green'
ctx.fillRect(0, 0, 250, 60)
// 设置新画上的元素可以擦除原来的元素
ctx.globalCompositeOperation = 'destination-out'
// 鼠标按下事件
canvas.onmousedown = function(e) {
canvas.onmousemove = function(e) {
// 画圆,用这个小圆来涂刮
ctx.beginPath()
ctx.arc(e.offsetX, e.offsetY, 8, 0, 7, false)
ctx.fill()
}
}
// 鼠标抬起,取消事件
canvas.onmouseup = function() {
canvas.onmousemove = null
}
}
}
</script>
</head>
<body>
<div>
特等奖
<canvas id="test" width="250" height="60"></canvas>
</div>
</body>
效果