阴影效果

Canvas阴影效果详解,使用shadowColor、shadowBlur等属性创建阴影效果的完整教程。Canvas提供了四个属性来创建阴影效果,可以为图形添加立体感。

阴影属性

属性类型说明
shadowColorstring阴影颜色
shadowBlurnumber阴影模糊程度
shadowOffsetXnumber阴影水平偏移
shadowOffsetYnumber阴影垂直偏移

基本用法

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)

描边阴影演示

阴影应用于填充和描边