如何为 Canvas 聚光灯效果添加彩色光照特效

酷涛姑娘_3375

酷涛姑娘_3375

2026-05-23

798人浏览

原创

如何为 Canvas 聚光灯效果添加彩色光照特效

本文详解如何使用 Canvas 的径向渐变与混合模式(如 color-dodge 和 lighter)实现带颜色的动态聚光灯效果,替代纯黑白遮罩,让光照呈现暖色晕染、自然衰减的真实感。

本文详解如何使用 canvas 的径向渐变与混合模式(如 `color-dodge` 和 `lighter`)实现带颜色的动态聚光灯效果,替代纯黑白遮罩,让光照呈现暖色晕染、自然衰减的真实感。

在原方案中,开发者采用 destination-out 混合模式“挖空”圆形区域来模拟手电筒效果——这是一种基于遮罩的黑白高对比方式,虽简单但无法表现色彩、光晕或柔和过渡。若想让聚光灯具备真实光源质感(如暖黄光晕、中心高亮、边缘渐隐),需转向叠加式着色渲染:即先完整绘制图像,再用带颜色的径向渐变以加性混合模式(additive compositing)覆盖照射区域。

Markdown Canvas
Markdown Canvas

将Markdown文件转换为美观的HTML页面,适用于Canvas或浏览器查看。用于用户请求渲染、可视化、显示或分享Markdown文件时。

下载

✅ 核心原理:渐变 + 加性混合

  • createRadialGradient(x0, y0, r0, x1, y1, r1) 创建从圆心向外扩散的渐变,支持多色阶控制光色分布;
  • globalCompositeOperation = "color-dodge" 强化高光与色彩饱和度,适合模拟强光中心;
  • globalCompositeOperation = "lighter" 简单叠加亮度,增强边缘柔光感;
  • globalAlpha 分层调控 可精细平衡不同混合模式的强度,避免过曝。

? 完整可运行示例代码

<canvas id="flashlight-canvas" style="border: 1px solid #333;"></canvas><script>
const canvas = document.getElementById("flashlight-canvas");
const ctx = canvas.getContext("2d");
let mouseX = 0, mouseY = 0;
let radius = 150;
let draw = () => {}; // 占位函数,待图片加载后赋值

// 创建并加载图像(注意:必须等待 load 事件!)
const image = new Image();
image.src = "https://3.api.artsmia.org/800/109833.jpg";
image.addEventListener("load", () => {
  canvas.width = image.naturalWidth;
  canvas.height = image.naturalHeight;
  draw = drawFlashlight; // 启用绘制逻辑
  draw(); // 首帧渲染
}, { once: true });

// 构建彩色径向渐变(模拟暖调聚光灯)
const lightGrad = ctx.createRadialGradient(0, 0, 0, 0, 0, radius);
lightGrad.addColorStop(0.0, "#ffdd99");   // 中心:明亮暖黄
lightGrad.addColorStop(0.3, "#ffb74d");   // 中段:琥珀橙
lightGrad.addColorStop(0.6, "#ff9800");   // 过渡:深橙
lightGrad.addColorStop(0.9, "#b76e00");   // 边缘:暗棕
lightGrad.addColorStop(1.0, "rgba(0,0,0,0)"); // 完全透明,实现自然衰减

function drawImage() {
  ctx.setTransform(1, 0, 0, 1, 0, 0); // 重置变换
  ctx.globalCompositeOperation = "source-over";
  ctx.drawImage(image, 0, 0);
}

function drawFlashlight() {
  drawImage();

  // 应用光照:平移坐标系至鼠标位置,绘制渐变圆
  ctx.setTransform(1, 0, 0, 1, mouseX, mouseY);
  ctx.fillStyle = lightGrad;

  // 第一层:color-dodge 增强中心亮度与色调
  ctx.globalAlpha = 0.8;
  ctx.globalCompositeOperation = "color-dodge";
  ctx.beginPath();
  ctx.arc(0, 0, radius, 0, Math.PI * 2);
  ctx.fill();

  // 第二层:lighter 柔化边缘光晕
  ctx.globalAlpha = 0.4;
  ctx.globalCompositeOperation = "lighter";
  ctx.fill();
}

// 绑定鼠标移动事件(含防抖建议见下方)
canvas.addEventListener("mousemove", (e) => {
  const rect = canvas.getBoundingClientRect();
  mouseX = e.clientX - rect.left;
  mouseY = e.clientY - rect.top;
  draw();
});
</script>

⚠️ 关键注意事项

  • 务必等待 image.onload:否则 naturalWidth/Height 为 0,Canvas 尺寸异常,绘图失败;
  • 避免 destination-out 混合模式:它会擦除像素,无法叠加颜色;应全程使用 source-over / color-dodge / lighter 等叠加型模式;
  • 渐变坐标系需配合 setTransform:将渐变原点锚定在 (mouseX, mouseY),而非画布左上角;
  • 性能优化建议:高频 mousemove 可加节流(如 requestAnimationFrame 控制帧率),防止重绘过载;
  • 移动端适配:需额外监听 touchmove 并转换 touches[0] 坐标。

✅ 效果升级方向

  • 动态调整 radius 实现缩放/聚焦;
  • 结合 shadowBlur 在光照边缘添加轻微发光;
  • 使用 ctx.filter = "blur(2px)"(需开启 will-change: filter)实现更柔和光晕;
  • 引入 HSL 渐变色停靠点,实现冷暖光切换动画。

通过上述方法,你不仅能实现彩色聚光灯,更能精准控制光色温度、衰减曲线与混合强度——让 Canvas 光效真正服务于视觉叙事,而非仅作技术演示。

相关专题

更多
html5动画制作有哪些制作方法
html5动画制作有哪些制作方法

html5动画制作方法有使用CSS3动画、使用JavaScript动画库、使用HTML5 Canvas等。想了解更多html5动画制作方法相关内容,可以阅读本专题下面的文章。

2023.10.23

3831

6

canva可画使用技巧汇总
canva可画使用技巧汇总

本专题汇集了PHP中文网精心整理的Canva可画新手使用技巧大全,专为零基础用户打造。无论你是想制作精美海报、PPT还是社交媒体配图,这里都有从注册登录、模板搜索到AI辅助设计、导出分享的全流程保姆级教程。通过深入浅出的图文指南,帮助你快速跨越设计门槛,轻松掌握Canva可画的实用操作,让每个人都能成为设计达人!

2026.05.19

224

21

canva可画新手使用指南
canva可画新手使用指南

本专题专为零基础用户打造,系统讲解Canva可画的核心功能与实用技巧。从注册登录、模板选择到图文编辑、导出分享,手把手带你快速上手。涵盖海报、PPT、简历等高频场景,结合AI工具提升效率,让你5分钟做出专业级设计,轻松应对学习、工作与社交需求。

2026.05.06

800

25

canva可画硬件门槛与适配设备指南
canva可画硬件门槛与适配设备指南

本专题聚焦Canva可画的硬件门槛与适配设备指南,全面解析网页版与App在不同终端上的运行要求。结合PHP中文网提供的专业技术教程,帮助用户精准排查设备卡顿、白屏等问题,快速判断电脑、平板及手机是否满足流畅使用Canva可画的各项硬性指标。

2026.05.19

94

11

canva可画使用技巧汇总
canva可画使用技巧汇总

本专题汇集了PHP中文网精心整理的Canva可画新手使用技巧大全,专为零基础用户打造。无论你是想制作精美海报、PPT还是社交媒体配图,这里都有从注册登录、模板搜索到AI辅助设计、导出分享的全流程保姆级教程。通过深入浅出的图文指南,帮助你快速跨越设计门槛,轻松掌握Canva可画的实用操作,让每个人都能成为设计达人!

2026.05.19

224

21

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

120

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

100

14

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

2026.09.30

80

12

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

2026.09.30

60

26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Canva使用教程
Canva使用教程

共0课时 | 0人学习