Canvas阴影效果详解,使用shadowColor、shadowBlur等属性创建阴影效果的完整教程。Canvas提供了四个属性来创建阴影效果,可以为图形添加立体感。
| 属性 | 类型 | 说明 |
|---|---|---|
| shadowColor | string | 阴影颜色 |
| shadowBlur | number | 阴影模糊程度 |
| shadowOffsetX | number | 阴影水平偏移 |
| shadowOffsetY | number | 阴影垂直偏移 |
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// 设置阴影
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 10
ctx.shadowOffsetX = 5
ctx.shadowOffsetY = 5
// 绘制带阴影的图形
ctx.fillStyle = '#3498db'
ctx.fillRect(50, 50, 100, 80)
// 不同模糊程度
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowOffsetX = 5
ctx.shadowOffsetY = 5
ctx.shadowBlur = 0
ctx.fillRect(50, 50, 80, 60)
ctx.shadowBlur = 5
ctx.fillRect(150, 50, 80, 60)
ctx.shadowBlur = 15
ctx.fillRect(250, 50, 80, 60)
ctx.shadowBlur = 30
ctx.fillRect(350, 50, 80, 60)
// 不同偏移方向
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 10
// 右下偏移
ctx.shadowOffsetX = 10
ctx.shadowOffsetY = 10
ctx.fillRect(50, 50, 80, 60)
// 左上偏移
ctx.shadowOffsetX = -10
ctx.shadowOffsetY = -10
ctx.fillRect(150, 50, 80, 60)
// 右上偏移
ctx.shadowOffsetX = 10
ctx.shadowOffsetY = -10
ctx.fillRect(250, 50, 80, 60)
// 左下偏移
ctx.shadowOffsetX = -10
ctx.shadowOffsetY = 10
ctx.fillRect(350, 50, 80, 60)
// 不同颜色阴影
ctx.shadowBlur = 15
ctx.shadowOffsetX = 5
ctx.shadowOffsetY = 5
// 黑色阴影
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.fillRect(50, 50, 80, 60)
// 红色阴影
ctx.shadowColor = 'rgba(255, 0, 0, 0.5)'
ctx.fillRect(150, 50, 80, 60)
// 蓝色阴影
ctx.shadowColor = 'rgba(0, 0, 255, 0.5)'
ctx.fillRect(250, 50, 80, 60)
// 绿色阴影
ctx.shadowColor = 'rgba(0, 255, 0, 0.5)'
ctx.fillRect(350, 50, 80, 60)
// 使用阴影创建发光效果
ctx.shadowColor = '#3498db'
ctx.shadowBlur = 20
ctx.shadowOffsetX = 0
ctx.shadowOffsetY = 0
ctx.fillStyle = '#3498db'
ctx.beginPath()
ctx.arc(100, 100, 30, 0, Math.PI * 2)
ctx.fill()
// 多次绘制增强发光
ctx.shadowBlur = 40
ctx.fill()
Canvas没有直接的内阴影支持,但可以通过多次绘制模拟:
function drawInnerShadow(ctx, x, y, width, height, radius) {
// 外部阴影
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 15
ctx.shadowOffsetX = 5
ctx.shadowOffsetY = 5
ctx.fillStyle = '#3498db'
ctx.fillRect(x, y, width, height)
// 内部高光
ctx.shadowColor = 'transparent'
const gradient = ctx.createLinearGradient(x, y, x, y + height)
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)')
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)')
ctx.fillStyle = gradient
ctx.fillRect(x, y, width, height / 2)
}
清除阴影
// 设置阴影
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 10
ctx.shadowOffsetX = 5
ctx.shadowOffsetY = 5
ctx.fillRect(0, 0, 100, 100)
// 清除阴影
ctx.shadowColor = 'transparent'
ctx.shadowBlur = 0
ctx.shadowOffsetX = 0
ctx.shadowOffsetY = 0
ctx.fillRect(110, 0, 100, 100)
阴影影响性能
// 阴影计算开销较大,大量使用会影响性能
// 在动画中尽量减少阴影使用
// 不推荐:每帧都绘制阴影
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 10
// ...绘制
requestAnimationFrame(animate)
}
// 推荐:使用缓存
const cachedCanvas = document.createElement('canvas')
const cachedCtx = cachedCanvas.getContext('2d')
// 在缓存画布上绘制带阴影的图形
cachedCtx.shadowColor = 'rgba(0, 0, 0, 0.5)'
cachedCtx.shadowBlur = 10
cachedCtx.fillRect(0, 0, 100, 100)
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(cachedCanvas, 0, 0)
requestAnimationFrame(animate)
}
阴影与透明度
// 阴影颜色支持透明度
ctx.shadowColor = 'rgba(0, 0, 0, 0.3)' // 30%透明度
ctx.shadowColor = 'rgba(0, 0, 0, 0.8)' // 80%透明度
阴影与描边
// 阴影同时应用于填充和描边
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 10
ctx.fillStyle = '#3498db'
ctx.fillRect(50, 50, 100, 80)
ctx.strokeStyle = '#e74c3c'
ctx.lineWidth = 3
ctx.strokeRect(200, 50, 100, 80)