Canvas 绘制带圆角的矩形图
实现步骤:
- 绘制一个圆角矩形 (打开冰箱)
- 对圆角矩形进行剪切(把 🐘 放进去)
- 将图片绘制到矩形内(关上冰箱)
绘制圆角矩形
arcTo 方案
arcTo 可以根据控制点和半径绘制圆弧路径
js
// 绘制圆角矩形(使用 arcTo)
function drawRoundedRect(ctx, x, y, width, height, radius) {
// 重置当前路径
ctx.beginPath()
// 移动到左上角
ctx.moveTo(x + radius, y)
// 绘制右上角
ctx.arcTo(x + width, y, x + width, y + radius, radius)
// 绘制右下角
ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius)
// 绘制左下角
ctx.arcTo(x, height, x, height - radius, radius)
// 绘制左上角
ctx.arcTo(x, y, x + radius, y, radius)
// 填充当前路径
ctx.fill()
}
quadraticCurveTo 二次贝塞尔曲线方案
quadraticCurveTo 用于创建二次贝塞尔曲线
js
// 绘制圆角矩形(使用二次贝塞尔曲线 quadraticCurveTo)
function drawRoundedRect(ctx, x, y, width, height, radius) {
// 重置当前路径
ctx.beginPath()
// 移动到右上角
ctx.moveTo(x + width - radius, y)
// 绘制右上角曲线
ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
// 绘制右边线
ctx.lineTo(x + width, y + height - radius)
// 绘制右下角曲线
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
// 绘制下边线
ctx.lineTo(x + radius, y + height)
// 绘制左下角曲线
ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
// 绘制左边线
ctx.lineTo(x, y + radius)
// 绘制左上角曲线
ctx.quadraticCurveTo(x, y, x + radius, y)
// 绘制上边线(创建从当前点回到起始点的路径)
ctx.closePath()
// 填充当前路径
ctx.fill()
}
不得不说贝塞尔曲线真烦人,圆角矩形还是 arcTo 香
绘制图片
clip 方案
clip 可以从原始画布剪切任意形状和尺寸的区域。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 绘制带圆角的矩形图 — clip</title>
</head>
<body>
<div>
<img
id="img"
src="https://mms1.baidu.com/it/u=181635795,1817021705&fm=253&app=138&f=JPEG&fmt=auto&q=75?w=500&h=284"
alt=""
/>
</div>
<canvas id="canvas" width="500" height="284"></canvas>
<script>
// 绘制圆角矩形(使用 arcTo)
function drawRoundedRect(ctx, x, y, width, height, radius) {
// 保存当前环境的状态
ctx.save()
// 重置当前路径
ctx.beginPath()
// 移动到左上角
ctx.moveTo(x + radius, y)
// 绘制右上角
ctx.arcTo(x + width, y, x + width, y + radius, radius)
// 绘制右下角
ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius)
// 绘制左下角
ctx.arcTo(x, height, x, height - radius, radius)
// 绘制左上角
ctx.arcTo(x, y, x + radius, y, radius)
// 填充当前路径
ctx.fill()
}
const img = document.getElementById('img')
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
window.onload = function () {
const x = 0
const y = 0
const width = canvas.width
const height = canvas.height
let radius = 50
// 处理圆角边界值
radius = Math.min(radius, Math.min(width, height) / 2)
// 绘制圆角矩形
drawRoundedRect(ctx, x, y, width, height, radius)
// 对矩形进行剪切
ctx.clip()
// 绘制图片
ctx.drawImage(img, x, y, width, height)
}
</script>
</body>
</html>
CodeSandbox: Canvas 绘制带圆角的矩形图 — clip
globalCompositeOperation 方案
globalCompositeOperation 可以设置要在绘制新形状时应用的合成操作的类型
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 绘制带圆角的矩形图 — globalCompositeOperation</title>
</head>
<body>
<div>
<img
id="img"
src="https://mms1.baidu.com/it/u=181635795,1817021705&fm=253&app=138&f=JPEG&fmt=auto&q=75?w=500&h=284"
alt=""
/>
</div>
<canvas id="canvas" width="500" height="284"></canvas>
<script>
// 绘制圆角矩形(使用 arcTo)
function drawRoundedRect(ctx, x, y, width, height, radius) {
// 保存当前环境的状态
ctx.save()
// 重置当前路径
ctx.beginPath()
// 移动到左上角
ctx.moveTo(x + radius, y)
// 绘制右上角
ctx.arcTo(x + width, y, x + width, y + radius, radius)
// 绘制右下角
ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius)
// 绘制左下角
ctx.arcTo(x, height, x, height - radius, radius)
// 绘制左上角
ctx.arcTo(x, y, x + radius, y, radius)
// 填充当前路径
ctx.fill()
}
const img = document.getElementById('img')
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
window.onload = function () {
const x = 0
const y = 0
const width = canvas.width
const height = canvas.height
let radius = 600
// 处理圆角边界值
radius = Math.min(radius, Math.min(width, height) / 2)
// 绘制圆角矩形
drawRoundedRect(ctx, x, y, width, height, radius)
// 只在新图形和目标画布重叠的地方绘制图形
ctx.globalCompositeOperation = 'source-in'
// 绘制图片
ctx.drawImage(img, x, y, width, height)
}
</script>
</body>
</html>
CodeSandbox: Canvas 绘制带圆角的矩形图 — globalCompositeOperation
这是李总教我的方案,再次膜拜一下大佬