如何为Canvas手电筒效果添加色彩效果?
实现彩色手电筒光照效果
完全可以给你的手电筒效果添加彩色光照,下面提供两种实用的实现方式:
方法一:渐变彩色光照
这种方式模拟真实带色光源,让手电筒区域呈现自然的色彩渐变:
修改你的JavaScript代码如下:
document.addEventListener("DOMContentLoaded", function() { const canvas = document.getElementById("flashlight-canvas"); const ctx = canvas.getContext("2d"); const image = document.getElementById("darkimage"); canvas.width = image.width; canvas.height = image.height; let radius = 150; let mouseX = canvas.width / 2, mouseY = canvas.height / 2; // 初始位置设为画布中心 function drawFlashlight() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 1. 绘制底层原图 ctx.globalCompositeOperation = "source-over"; ctx.drawImage(image, 0, 0); // 2. 给整张图覆盖一层半透明彩色遮罩 ctx.fillStyle = "rgba(255, 165, 0, 0.6)"; // 橙色半透明,可自行调整颜色和透明度 ctx.fillRect(0, 0, canvas.width, canvas.height); // 3. 用径向渐变挖出手电筒区域,露出原图与色彩混合的效果 ctx.globalCompositeOperation = "destination-out"; const gradient = ctx.createRadialGradient(mouseX, mouseY, 0, mouseX, mouseY, radius); gradient.addColorStop(0, "rgba(0,0,0,1)"); // 中心完全透明,露出下方色彩 gradient.addColorStop(1, "rgba(0,0,0,0)"); // 边缘不透明,保留遮罩 ctx.fillStyle = gradient; ctx.beginPath(); ctx.arc(mouseX, mouseY, radius, 0, 2 * Math.PI); ctx.fill(); // 恢复默认混合模式 ctx.globalCompositeOperation = "source-over"; } canvas.addEventListener("mousemove", function(e) { mouseX = e.clientX - canvas.getBoundingClientRect().left; mouseY = e.clientY - canvas.getBoundingClientRect().top; drawFlashlight(); }); drawFlashlight() });
方法二:纯色叠加光照
如果想要更简洁的纯色光照,直接在手电筒区域叠加颜色:
document.addEventListener("DOMContentLoaded", function() { const canvas = document.getElementById("flashlight-canvas"); const ctx = canvas.getContext("2d"); const image = document.getElementById("darkimage"); canvas.width = image.width; canvas.height = image.height; let radius = 150; let mouseX = canvas.width / 2, mouseY = canvas.height / 2; function drawFlashlight() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 1. 绘制底层原图 ctx.drawImage(image, 0, 0); // 2. 在手电筒区域叠加渐隐的彩色层 ctx.globalCompositeOperation = "source-atop"; // 仅在已有图像区域绘制 const gradient = ctx.createRadialGradient(mouseX, mouseY, radius*0.5, mouseX, mouseY, radius); gradient.addColorStop(0, "rgba(0, 200, 255, 0.5)"); // 中心亮蓝色 gradient.addColorStop(1, "rgba(0, 200, 255, 0)"); // 边缘渐隐 ctx.fillStyle = gradient; ctx.beginPath(); ctx.arc(mouseX, mouseY, radius, 0, 2 * Math.PI); ctx.fill(); ctx.globalCompositeOperation = "source-over"; } canvas.addEventListener("mousemove", function(e) { mouseX = e.clientX - canvas.getBoundingClientRect().left; mouseY = e.clientY - canvas.getBoundingClientRect().top; drawFlashlight(); }); drawFlashlight() });
调整说明
- 修改
rgba()中的数值即可更换光照颜色,比如rgba(255,0,0,0.5)是半透明红色 - 最后一个数值控制透明度,0为完全透明,1为完全不透明
- 调整渐变的
addColorStop参数,可以改变光照的过渡柔和度
内容的提问来源于stack exchange,提问作者Rslab8711
相关产品推荐
相关产品推荐

