当前位置: 首页 > article >正文

别再只用console.log了!用HTML5 Canvas画彩虹动画,轻松理解JavaScript绘图原理

用Canvas绘制彩虹动画JavaScript编程的趣味实践第一次接触JavaScript时我对着黑漆漆的控制台敲下console.log(Hello World)那种兴奋感很快被枯燥的语法练习冲淡。直到发现Canvas绘图这个神奇的功能才意识到原来JavaScript可以如此生动有趣。今天我们就抛开单调的控制台输出用HTML5 Canvas绘制一个会动的彩虹和云朵场景在这个过程中理解JavaScript的核心概念。1. 为什么选择Canvas作为JavaScript学习工具Canvas是HTML5引入的一个革命性特性它允许我们通过JavaScript在网页上绘制图形。对于初学者来说Canvas有几点独特优势即时可视化反馈每一行代码都能立即看到图形变化比抽象的控制台输出直观得多涵盖核心编程概念循环、数组、函数、对象等都能在Canvas项目中自然应用激发学习兴趣可以创作出有视觉冲击力的作品成就感更强理解API设计原理通过图形API学习如何与浏览器交互提示Canvas特别适合视觉型学习者它能将抽象概念转化为具体图形帮助建立编程思维。2. 搭建Canvas基础环境让我们从最基础的HTML结构开始创建一个Canvas绘图环境!DOCTYPE html html head title彩虹动画/title style body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #f0f8ff; } canvas { border: 1px solid #ccc; background: #87ceeb; } /style /head body canvas idmyCanvas width600 height400/canvas script // 获取Canvas元素和绘图上下文 const canvas document.getElementById(myCanvas); const ctx canvas.getContext(2d); /script /body /html这段代码做了几件重要的事情创建了一个600×400像素的Canvas元素通过CSS将其居中显示并添加了天蓝色背景在JavaScript中获取了Canvas的2D绘图上下文3. 绘制静态彩虹彩虹的绘制原理其实很简单画一系列半圆每个半圆用不同的颜色。让我们分解这个任务3.1 定义彩虹颜色彩虹通常由七种颜色组成我们可以用一个数组来表示const rainbowColors [ #FF0000, // 红 #FF7F00, // 橙 #FFFF00, // 黄 #00FF00, // 绿 #0000FF, // 蓝 #4B0082, // 靛 #9400D3 // 紫 ];3.2 绘制彩虹弧线使用Canvas的arc方法绘制半圆关键参数包括圆心坐标(x,y)半径起始角度和结束角度Math.PI表示180度绘制方向false表示顺时针function drawRainbow() { const centerX canvas.width / 2; const centerY canvas.height; const maxRadius canvas.height * 0.8; // 从外向内绘制彩虹 for (let i rainbowColors.length - 1; i 0; i--) { ctx.beginPath(); ctx.arc(centerX, centerY, maxRadius - i * 20, Math.PI, 0, false); ctx.strokeStyle rainbowColors[i]; ctx.lineWidth 20; ctx.stroke(); } }3.3 添加云朵元素云朵可以用几个相连的圆来表现function drawCloud(x, y, size) { ctx.beginPath(); ctx.arc(x, y, size, 0, Math.PI * 2); ctx.arc(x size, y - size/2, size*0.8, 0, Math.PI * 2); ctx.arc(x size*2, y, size, 0, Math.PI * 2); ctx.fillStyle white; ctx.fill(); } // 绘制两朵云 drawCloud(50, 50, 30); drawCloud(400, 80, 25);4. 让场景动起来理解动画循环静态图像已经很好看了但让云朵动起来会更吸引人。这需要我们理解浏览器动画的基本原理。4.1 动画的基本概念动画的本质是快速连续显示一系列静态图像每帧略有不同。在Canvas中实现动画需要清除上一帧的内容更新对象位置绘制新帧重复这个过程4.2 使用requestAnimationFramerequestAnimationFrame是浏览器专门为动画优化的API比传统的setInterval更高效// 定义云朵对象数组 const clouds [ { x: 50, y: 50, size: 30, speed: 1.5 }, { x: 400, y: 80, size: 25, speed: 1 } ]; function animate() { // 1. 清除画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 2. 绘制彩虹 drawRainbow(); // 3. 更新并绘制云朵 clouds.forEach(cloud { cloud.x cloud.speed; if (cloud.x canvas.width cloud.size*2) { cloud.x -cloud.size*2; } drawCloud(cloud.x, cloud.y, cloud.size); }); // 4. 请求下一帧 requestAnimationFrame(animate); } // 启动动画 animate();4.3 动画性能优化技巧为了确保动画流畅运行有几个最佳实践避免在动画循环中创建新对象提前初始化所有需要的对象减少不必要的绘制只重绘发生变化的部分使用离屏Canvas对复杂图形可以先在内存中绘制合理使用requestAnimationFrame不要嵌套多个动画循环5. 扩展功能添加交互元素现在我们的彩虹动画已经基本完成但还可以通过添加交互让它更有趣。5.1 响应鼠标移动让彩虹跟随鼠标移动let rainbowOffset 0; canvas.addEventListener(mousemove, (e) { // 计算鼠标在画布上的相对位置 const rect canvas.getBoundingClientRect(); rainbowOffset (e.clientX - rect.left) - canvas.width/2; }); // 修改drawRainbow函数中的centerX const centerX canvas.width / 2 rainbowOffset * 0.2;5.2 点击添加云朵canvas.addEventListener(click, (e) { const rect canvas.getBoundingClientRect(); const x e.clientX - rect.left; const y e.clientY - rect.top; clouds.push({ x: x, y: y, size: 20 Math.random() * 20, speed: 0.5 Math.random() * 1.5 }); });5.3 添加下雨效果const raindrops []; function createRaindrop() { if (Math.random() 0.3) { raindrops.push({ x: Math.random() * canvas.width, y: 0, speed: 2 Math.random() * 3, length: 10 Math.random() * 20 }); } } function drawRaindrops() { ctx.strokeStyle rgba(255, 255, 255, 0.7); ctx.lineWidth 2; for (let i raindrops.length - 1; i 0; i--) { const drop raindrops[i]; ctx.beginPath(); ctx.moveTo(drop.x, drop.y); ctx.lineTo(drop.x, drop.y drop.length); ctx.stroke(); drop.y drop.speed; if (drop.y canvas.height) { raindrops.splice(i, 1); } } } // 在animate函数中添加 createRaindrop(); drawRaindrops();6. 调试技巧与常见问题在Canvas开发过程中经常会遇到一些棘手的问题。这里分享几个实用的调试技巧6.1 Canvas不显示内容如果Canvas一片空白可以按以下步骤排查检查Canvas尺寸通过JavaScript设置的width/height属性不是CSS确认获取了绘图上下文getContext(2d)不能拼写错误验证绘图代码执行在关键步骤添加console.log确认函数被调用6.2 动画卡顿动画不流畅可能由以下原因导致过多的绘制操作简化图形或减少重绘区域复杂的计算将耗时计算移出动画循环内存泄漏确保没有不断创建新对象而不释放6.3 跨浏览器兼容性虽然现代浏览器对Canvas支持很好但仍需注意前缀问题某些浏览器需要特定前缀功能检测使用if (canvas.getContext)检查支持情况性能差异不同浏览器对复杂图形的渲染效率不同注意在开发过程中可以添加一个调试模式绘制辅助线和边界框帮助理解元素位置和大小。7. 项目结构与代码组织随着功能增加代码会变得复杂。良好的组织方式能提高可维护性7.1 模块化设计将不同功能拆分为独立函数或对象// 彩虹模块 const Rainbow { colors: [...], draw() {...}, update() {...} }; // 云朵模块 const CloudSystem { list: [...], add() {...}, update() {...}, draw() {...} }; // 主循环 function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); Rainbow.draw(); CloudSystem.update(); CloudSystem.draw(); requestAnimationFrame(animate); }7.2 使用类重构对于更复杂的项目可以使用ES6类class Cloud { constructor(x, y, size, speed) { this.x x; this.y y; this.size size; this.speed speed; } update() { this.x this.speed; if (this.x canvas.width this.size*2) { this.x -this.size*2; } } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); // ...其余绘制代码 } } // 使用 const clouds [ new Cloud(50, 50, 30, 1.5), new Cloud(400, 80, 25, 1) ];7.3 配置与常量分离将可配置参数集中管理const Config { canvas: { width: 600, height: 400, bgColor: #87ceeb }, rainbow: { colors: [...], width: 20, heightRatio: 0.8 }, clouds: { minSize: 20, maxSize: 40, minSpeed: 0.5, maxSpeed: 2 } };8. 进一步学习方向掌握了基础Canvas绘图后你可以继续探索以下方向8.1 高级绘图技术渐变和图案填充createLinearGradient、createPattern阴影效果shadowColor、shadowBlur图像处理drawImage、getImageData路径与贝塞尔曲线quadraticCurveTo、bezierCurveTo8.2 性能优化离屏渲染使用辅助Canvas预渲染复杂图形脏矩形技术只重绘发生变化的部分WebGL集成通过getContext(webgl)实现3D图形8.3 框架与库Three.js强大的3D图形库PixiJS专注于2D渲染的高性能引擎Fabric.js提供更高级的Canvas API封装Paper.js矢量图形脚本框架在完成这个彩虹动画项目后我发现自己对JavaScript的事件循环、作用域和面向对象编程有了更直观的理解。Canvas就像一扇窗户让我看到了编程与艺术结合的可能性。下次当你对JavaScript感到枯燥时不妨试试用代码画点什么这种视觉化的学习方式可能会给你带来全新的体验。

相关文章:

别再只用console.log了!用HTML5 Canvas画彩虹动画,轻松理解JavaScript绘图原理

用Canvas绘制彩虹动画:JavaScript编程的趣味实践 第一次接触JavaScript时,我对着黑漆漆的控制台敲下console.log("Hello World"),那种兴奋感很快被枯燥的语法练习冲淡。直到发现Canvas绘图这个神奇的功能,才意识到原来J…...

Janus-Pro-7B开源镜像价值:支持LoRA微调,适配垂直领域图文任务

Janus-Pro-7B开源镜像价值:支持LoRA微调,适配垂直领域图文任务 Janus-Pro-7B是一个统一的多模态理解与生成AI模型,能够同时处理图像理解和文本到图像的生成任务。这个7.42B参数规模的模型在单一架构中实现了视觉问答、图像描述、OCR识别和文…...

【RAG】【vector_stores044】LanceDB向量存储示例分析

案例目标本案例展示了如何使用LanceDB向量数据库与LlamaIndex框架集成,实现高效的向量存储和检索功能。主要目标包括:演示LanceDB向量存储的基本设置和配置展示如何创建、查询和更新向量索引实现基于元数据的过滤查询演示混合搜索(Hybrid Sea…...

163MusicLyrics:免费高效的网易云QQ音乐歌词下载与格式转换工具

163MusicLyrics:免费高效的网易云QQ音乐歌词下载与格式转换工具 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 还在为本地音乐库缺少歌词而烦恼吗&#xff1…...

tao-8k Embedding效果实测:对比BGE、text2vec,8K上下文优势凸显

tao-8k Embedding效果实测:对比BGE、text2vec,8K上下文优势凸显 1. 引言:为什么需要长文本嵌入模型? 在日常的文本处理任务中,我们经常需要将文本转换为向量表示,这就是嵌入模型的作用。传统的嵌入模型如…...

League-Toolkit:颠覆式英雄联盟辅助工具,让你告别繁琐操作

League-Toolkit:颠覆式英雄联盟辅助工具,让你告别繁琐操作 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否厌倦了…...

2026最新!亲测整理8款会议纪要实用神器,免费好用到哭,职场办公效率必备!

开完3小时季度会,领导拍你肩膀说“下班前把纪要发我”,你抱着电脑逐字听录音,错字连篇还漏了三个领导提的待办,熬到七点半才下班;采访完2小时的行业嘉宾,手动整理要熬半宿,转头嘉宾带口音的词全…...

基于模块化架构的LCU API智能客户端工具集技术解析

基于模块化架构的LCU API智能客户端工具集技术解析 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 在英雄联盟客户端生态中,开发者…...

2026最新!会议纪要怎么记录才能不加班?这3款亲测神器,10分钟搞定好用到哭!

做会议纪要这件事,开发要整理需求评审,产品要记跨部门对齐,运营要盘活动复盘,学生要记课堂讲座,不同人需求天差地别:有人要准,有人要快,有人要长期用得起。我前后测了不下十款2026年…...

量化投资实战:揭秘阿尔法因子构建的五大关键步骤与优化策略

1. 阿尔法因子构建的完整流程 量化投资的核心在于寻找能够持续产生超额收益的阿尔法因子。很多刚入门的量化研究员常常陷入一个误区:拿到数据就直接开始构建因子。实际上,一个完整的因子构建流程应该像建造房子一样,从打地基开始一步步来。 我…...

【 LangChain v1.2 入门系列教程】【二】消息类型与提示词工程

系列文章目录 【 LangChain v1.2 入门系列教程】【一】开篇入门 | 从零开始,跑通你的第一个 AI Agent 【 LangChain v1.2 入门系列教程】【二】消息类型与提示词工程 【 LangChain v1.2 入门系列教程】【三】工具(Tools)开发,让…...

教AI读小说:把《时光机器》变成一串数字的奇妙旅程

版权声明:本文同步发布于个人博客。欢迎交流与转载,但请务必注明出处。 导读:你有没有想过,人工智能是如何“读懂”人类语言的?其实,它们并不认识字。在AI眼里,莎士比亚的十四行诗和超市购物清单…...

拒绝“传话游戏”!DenseNet 如何让神经网络开启“群聊”模式

版权声明:本文同步发布于个人博客。欢迎交流与转载,但请务必注明出处。 摘要:在深度学习的演进史上,ResNet(残差网络)通过“快捷连接”解决了深层网络难以训练的问题。而它的继任者 DenseNet(稠…...

深度学习界的“任督二脉”:为什么 ResNet 只是简单加了个“x”就封神了?

版权声明:本文同步发布于个人博客。欢迎交流与转载,但请务必注明出处。 在深度学习的历史长河中,2015年是一个分水岭。这一年,何恺明团队提出了残差网络(ResNet),不仅拿下了ImageNet大赛冠军&am…...

深度学习里的“自动稳压器”:通俗解读批量规范化(Batch Normalization)

版权声明:本文同步发布于个人博客。欢迎交流与转载,但请务必注明出处。 导读:如果你正在训练深层神经网络,是否遇到过训练慢如蜗牛、学习率稍大就发散、或者网络深了就不收敛的烦恼?今天我们要聊的批量规范化&#xff…...

Camera Graph™:全域相机拓扑,无感跨镜跟踪,彻底解决 ID 跳变与视觉孤岛

一、技术概述 Camera Graph™ 全域相机拓扑网络,是镜像视界(浙江)科技有限公司自主研发的多摄像机空间智能协同核心引擎,属于公司SpaceOS™ 空间智能操作系统的关键底层基础设施。它以全域统一时空基准为骨架,将离散、…...

全文降AI率为什么比手动改更安全?深度解读背后逻辑

全文降AI率为什么比手动改更安全?深度解读背后逻辑 每年毕业季,都有大量同学在降AI率这件事上踩坑。最常见的情况是:辛辛苦苦手动改了好几天,结果AI率反而升了,或者降了但论文被改得面目全非,导师看完一脸懵…...

WorkshopDL:5分钟掌握跨平台Steam创意工坊模组下载的终极方案

WorkshopDL:5分钟掌握跨平台Steam创意工坊模组下载的终极方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在Epic Games Store或GOG平台购买了游戏&#x…...

如何在Windows上轻松构建词法语法分析器:WinFlexBison完整指南

如何在Windows上轻松构建词法语法分析器:WinFlexBison完整指南 【免费下载链接】winflexbison Main winflexbision repository 项目地址: https://gitcode.com/gh_mirrors/wi/winflexbison 如果你正在Windows平台上开发编译器或解释器,那么WinFle…...

Python Web开发入门(二十四)Python观察者模式与发布订阅模式:从紧耦合到事件驱动架构的演进之路

当订单系统新增一个“推送微信模板消息”需求时,看着已有500行代码的 place_order 函数,我突然意识到:每次业务扩张都要修改核心逻辑,这种“if-elif地狱”终将导致系统不可维护。从传统观察者模式到现代化发布订阅架构,我花了9年时间探索事件驱动的最佳实践。本文带你深入…...

如何一键解锁网易云音乐NCM格式:ncmdumpGUI完整使用指南

如何一键解锁网易云音乐NCM格式:ncmdumpGUI完整使用指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾在网易云音乐下载了心爱的歌曲&am…...

告别手写UI!用Gui Guider 1.6 + LVGL 8.3,5分钟拖拽出你的第一个嵌入式界面

从零到一:用Gui Guider 1.6与LVGL 8.3快速构建嵌入式UI的实战指南 在嵌入式开发领域,用户界面(UI)设计往往是最耗时的环节之一。传统的手写代码方式不仅效率低下,还需要开发者深入掌握图形库的复杂API。而如今,借助Gui Guider这样…...

智能游戏助手:OnmyojiAutoScript如何彻底改变你的阴阳师游戏体验

智能游戏助手:OnmyojiAutoScript如何彻底改变你的阴阳师游戏体验 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 还在为阴阳师的日常任务感到疲惫吗?每天…...

Qwen3.5-2B模型轻量化原理剖析:适合移动与边缘计算

Qwen3.5-2B模型轻量化原理剖析:适合移动与边缘计算 1. 轻量化模型的崛起背景 在AI技术快速发展的今天,大模型展现出了惊人的能力,但同时也面临着计算资源消耗大、部署成本高等问题。特别是在嵌入式设备和边缘计算场景中,传统的百…...

Web安全攻防实战:常见漏洞分析与防御策略

基于最新的Web安全攻防资料,我为您整理了一份全面的常见漏洞分析与防御策略指南。以下是核心内容: 一、常见Web安全漏洞分析 1. SQL注入漏洞 原理:攻击者通过在用户输入中插入恶意SQL语句,利用应用程序未对输入进行充分验证的缺陷…...

本科生论文“求生”指南:我用百考通AI,通关了查重与AIGC检测

写在前面:如果你也正在为毕业论文的“双重审判”——查重率与AIGC(AI生成内容)检测率——而焦虑失眠,那么这篇经验分享,或许能为你照亮一条更清晰、更稳妥的路径。本文将带你深度了解一款我亲身使用、并认为切实有效的…...

Qwen3-4B开源大模型部署教程:device_map=‘auto‘适配全系GPU

Qwen3-4B开源大模型部署教程:device_mapauto适配全系GPU 1. 项目概述 Qwen3-4B Instruct-2507是阿里通义千问团队推出的纯文本大语言模型,专门针对文本处理场景进行了深度优化。这个版本移除了视觉相关的冗余模块,专注于代码编写、文案创作…...

深度解析League Akari:基于LCU API的模块化英雄联盟客户端工具集架构

深度解析League Akari:基于LCU API的模块化英雄联盟客户端工具集架构 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League Akari…...

FUTURE POLICE语音模型Ubuntu 20.04部署全流程详解

FUTURE POLICE语音模型Ubuntu 20.04部署全流程详解 想试试那个能生成未来感、赛博朋克风格语音的FUTURE POLICE模型吗?自己动手在服务器上部署,听起来好像挺复杂,又是系统环境,又是GPU驱动,还有各种依赖包。别担心&am…...

2025网盘下载终极解决方案:八大平台直链解析助手完整使用指南

2025网盘下载终极解决方案:八大平台直链解析助手完整使用指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘…...