2026/1/10 5:53:55
网站建设
项目流程
建筑网站制作,外贸网站宗旨,企业黄页软件,正规网站建设平台文章目录一、认识Canvas#xff1a;定义与核心特性1.1 什么是Canvas#xff1f;1.2 核心特性与应用场景二、基础环境搭建#xff1a;从标签到上下文2.1 Canvas标签基础2.2 获取绘图上下文三、核心绘图API#xff1a;图形与路径3.1 基础图形绘制3.2 路径绘制#xff08;核心…文章目录一、认识Canvas定义与核心特性1.1 什么是Canvas1.2 核心特性与应用场景二、基础环境搭建从标签到上下文2.1 Canvas标签基础2.2 获取绘图上下文三、核心绘图API图形与路径3.1 基础图形绘制3.2 路径绘制核心四、样式与颜色让图形更生动4.1 基础样式设置4.2 渐变效果4.3 图案填充五、文本与图像操作丰富画布内容5.1 文本绘制5.2 图像绘制与处理六、状态管理与变换复杂绘图必备6.1 状态保存与恢复6.2 图形变换七、实战案例时钟与简易画板7.1 案例1简易时钟7.2 案例2简易画板八、常见问题与避坑技巧8.1 图形模糊问题8.2 路径绘制异常8.3 图像跨域问题九、核心知识点总结一、认识Canvas定义与核心特性1.1 什么是CanvasCanvas是HTML5引入的图形绘制标签其本质是一个“像素容器”——它本身不具备绘图能力所有绘制操作都需通过JavaScript脚本完成。浏览器会为Canvas创建一个位图Bitmap开发者通过操作像素来实现各种图形效果这与SVG的矢量图形有本质区别。1.2 核心特性与应用场景核心特性应用场景像素级控制图像处理、滤镜效果即时模式渲染游戏开发、动画效果轻量高效数据可视化图表支持图像/文本混合分享海报生成、水印添加典型案例网易云音乐歌词海报、ECharts图表、在线绘图工具等均以Canvas为核心技术支撑。二、基础环境搭建从标签到上下文2.1 Canvas标签基础Canvas标签的使用需注意两个核心要点虚拟画布尺寸attribute属性和可视区域尺寸style样式二者混淆是初学者最常见的错误。!-- 基础Canvas标签结构 --canvasidmyCanvaswidth600height300styleborder:1px solid #ccc;width:300px;height:150px;您的浏览器不支持HTML5 Canvas请升级浏览器。/canvas关键区别width/height属性定义虚拟画布的实际像素尺寸绘图区域大小右键下载Canvas图像时尺寸与此一致style样式仅控制Canvas在页面中的显示大小若与属性尺寸不一致会导致图像拉伸变形。2.2 获取绘图上下文绘图的核心是获取Canvas的2D上下文对象CanvasRenderingContext2D所有绘图API都通过该对象调用。// 1. 获取Canvas元素constcanvasdocument.getElementById(myCanvas);// 2. 检查浏览器支持性if(!canvas.getContext){alert(浏览器不支持Canvas 2D上下文);return;}// 3. 获取2D绘图上下文核心对象constctxcanvas.getContext(2d);// 此时可通过ctx调用各类绘图方法注意getContext(‘2d’)是目前唯一强制支持的上下文类型调用时需注意大小写敏感。三、核心绘图API图形与路径3.1 基础图形绘制Canvas提供了矩形的原生绘制方法其他图形需通过路径实现。// 1. 填充矩形实心fillRect(x, y, width, height)ctx.fillStyleskyblue;// 设置填充色ctx.fillRect(20,20,100,80);// 左上角(20,20)宽100高80// 2. 描边矩形空心strokeRect(x, y, width, height)ctx.strokeStylered;// 设置描边色ctx.lineWidth2;// 设置线宽ctx.strokeRect(150,20,100,80);// 3. 清除矩形区域clearRect(x, y, width, height)ctx.clearRect(40,40,60,40);// 清除中间部分形成“挖空”效果运行效果两个矩形第一个中间被清除出空白区域。3.2 路径绘制核心路径是绘制复杂图形圆形、多边形等的基础核心流程为beginPath() → 定义路径 → stroke()/fill()。// 案例1绘制实心圆形ctx.beginPath();// 开始新路径避免与之前路径关联// arc(x, y, 半径, 起始角度, 结束角度, 逆时针方向)ctx.arc(300,100,50,0,Math.PI*2,false);// 0到2π为完整圆形ctx.fillStyleorange;ctx.fill();// 填充路径// 案例2绘制三角形ctx.beginPath();ctx.moveTo(400,50);// 移动起点到(400,50)ctx.lineTo(480,150);// 绘制到(480,150)ctx.lineTo(320,150);// 绘制到(320,150)ctx.closePath();// 闭合路径连接起点与终点ctx.strokeStylegreen;ctx.stroke();// 描边路径关键API说明beginPath()重置路径状态必须在绘制新路径前调用moveTo(x,y)移动画笔位置不绘制线条closePath()自动连接起点与终点可选但推荐使用。四、样式与颜色让图形更生动4.1 基础样式设置// 1. 线条样式ctx.lineWidth5;// 线宽ctx.lineCapround;// 线帽butt(默认)/round/squarectx.lineJoinbevel;// 线交点miter(默认)/round/bevel// 2. 绘制带样式的线条ctx.beginPath();ctx.moveTo(50,200);ctx.lineTo(250,200);ctx.strokeStylepurple;ctx.stroke();4.2 渐变效果Canvas支持线性渐变和径向渐变需先创建渐变对象再赋值给fillStyle/strokeStyle。// 1. 线性渐变createLinearGradient(x0, y0, x1, y1)constlinearGradctx.createLinearGradient(300,180,450,220);// 渐变方向linearGrad.addColorStop(0,pink);// 起点颜色linearGrad.addColorStop(1,red);// 终点颜色ctx.fillStylelinearGrad;ctx.fillRect(300,180,150,40);// 2. 径向渐变createRadialGradient(x0, y0, r0, x1, y1, r1)constradialGradctx.createRadialGradient(550,200,10,550,200,50);radialGrad.addColorStop(0,yellow);radialGrad.addColorStop(1,orange);ctx.beginPath();ctx.arc(550,200,50,0,Math.PI*2);ctx.fill();4.3 图案填充可将图片或其他Canvas作为图案填充到图形中。// 1. 创建图片对象constimgnewImage();img.srchttps://www.w3school.com.cn/i/eg_flower.png;// 示例图片img.onloadfunction(){// 2. 创建图案createPattern(图像, 重复方式)constpatternctx.createPattern(img,repeat);// repeat/repeat-x/repeat-y/no-repeatctx.fillStylepattern;ctx.fillRect(50,250,200,100);};五、文本与图像操作丰富画布内容5.1 文本绘制支持填充文本和描边文本可设置字体、对齐方式等样式。// 1. 填充文本ctx.fontbold 24px 微软雅黑;// 字体样式粗细 大小 字体ctx.fillStyleblack;ctx.textAlignleft;// 文本对齐方式ctx.fillText(Canvas文本示例,280,280);// 文本内容x坐标y坐标// 2. 描边文本ctx.font18px 宋体;ctx.strokeStyleblue;ctx.strokeText(描边文本效果,280,320);// 3. 测量文本宽度实用consttextWidthctx.measureText(Canvas文本示例).width;ctx.fillText(上文宽度${textWidth}px,280,350);5.2 图像绘制与处理通过drawImage()方法可将图片绘制到Canvas中支持缩放和裁剪。constimgnewImage();img.srchttps://www.w3school.com.cn/i/eg_flower.png;img.onloadfunction(){// 1. 完整绘制图片drawImage(img, x, y)ctx.drawImage(img,400,250);// 2. 缩放绘制drawImage(img, x, y, width, height)ctx.drawImage(img,500,250,60,60);// 缩放到60x60// 3. 裁剪绘制drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)// 从图片(sx,sy)位置裁剪sw×sh区域绘制到画布(dx,dy)位置缩放到dw×dhctx.drawImage(img,10,10,50,50,400,320,80,80);};注意图片绘制必须在onload回调中执行确保图片加载完成。六、状态管理与变换复杂绘图必备6.1 状态保存与恢复Canvas上下文的状态样式、变换等可通过栈结构保存和恢复适用于复杂绘图场景。// 1. 保存当前状态样式红色、线宽2ctx.save();ctx.strokeStylered;ctx.lineWidth2;ctx.strokeRect(50,400,80,60);// 2. 恢复到之前保存的状态ctx.restore();// 此时绘制的矩形使用默认样式ctx.strokeRect(150,400,80,60);运行效果第一个矩形为红色线宽2第二个为默认黑色线宽1。6.2 图形变换通过平移、旋转、缩放等变换可简化复杂图形的绘制逻辑。// 案例旋转矩形ctx.save();// 保存原始状态// 1. 平移原点到矩形中心旋转中心ctx.translate(300,430);// 2. 旋转30度弧度制Math.PI/180 * 角度ctx.rotate(Math.PI/180*30);// 3. 绘制矩形此时原点在中心需调整坐标ctx.fillStylergba(0, 128, 0, 0.5);ctx.fillRect(-40,-30,80,60);// 左上角(-40,-30)确保中心在原点ctx.restore();// 恢复状态不影响后续绘制// 案例缩放图形ctx.save();ctx.scale(1.5,0.8);// x轴放大1.5倍y轴缩小0.8倍ctx.fillStylergba(255, 0, 0, 0.5);ctx.fillRect(400,400,80,60);ctx.restore();七、实战案例时钟与简易画板7.1 案例1简易时钟综合运用路径、文本、变换和定时器实现动态时钟。functiondrawClock(){// 1. 清除画布ctx.clearRect(0,0,canvas.width,canvas.height);// 2. 绘制表盘ctx.beginPath();ctx.arc(300,200,150,0,Math.PI*2);ctx.fillStylewhite;ctx.fill();ctx.strokeStyleblack;ctx.lineWidth5;ctx.stroke();// 3. 绘制刻度12个大刻度for(leti0;i12;i){ctx.save();ctx.translate(300,200);ctx.rotate(Math.PI/6*i);// 每小时30度ctx.beginPath();ctx.moveTo(0,-130);ctx.lineTo(0,-140);ctx.lineWidth3;ctx.stroke();ctx.restore();}// 4. 获取当前时间constnownewDate();consthoursnow.getHours()%12;constminutesnow.getMinutes();constsecondsnow.getSeconds();// 5. 绘制时针30度/小时 0.5度/分钟ctx.save();ctx.translate(300,200);consthourAngleMath.PI/6*hoursMath.PI/180*0.5*minutes;ctx.rotate(hourAngle);ctx.lineWidth6;ctx.lineCapround;ctx.beginPath();ctx.moveTo(0,20);ctx.lineTo(0,-80);ctx.stroke();ctx.restore();// 6. 绘制分针6度/分钟 0.1度/秒// 分针和秒针绘制逻辑类似省略可自行补充// 7. 绘制秒针// ...// 8. 绘制中心圆点ctx.beginPath();ctx.arc(300,200,8,0,Math.PI*2);ctx.fill();}// 初始化绘制并设置定时器drawClock();setInterval(drawClock,1000);7.2 案例2简易画板结合鼠标事件实现自由绘图功能。letisDrawingfalse;// 绘图状态标记// 鼠标按下开始绘图canvas.addEventListener(mousedown,(e){isDrawingtrue;// 获取鼠标在Canvas中的坐标需处理偏移constposgetCanvasPos(e);ctx.beginPath();ctx.moveTo(pos.x,pos.y);ctx.lineCapround;// 线条圆润ctx.lineWidth5;ctx.strokeStyleblack;});// 鼠标移动绘制线条canvas.addEventListener(mousemove,(e){if(!isDrawing)return;constposgetCanvasPos(e);ctx.lineTo(pos.x,pos.y);ctx.stroke();});// 鼠标松开/离开结束绘图canvas.addEventListener(mouseup,()isDrawingfalse);canvas.addEventListener(mouseleave,()isDrawingfalse);// 工具函数获取鼠标在Canvas中的相对坐标functiongetCanvasPos(e){constrectcanvas.getBoundingClientRect();return{x:e.clientX-rect.left,y:e.clientY-rect.top};}八、常见问题与避坑技巧8.1 图形模糊问题原因Canvas虚拟尺寸与显示尺寸不一致或未适配设备像素比。// 解决方案适配设备像素比functioninitCanvas(){constdprwindow.devicePixelRatio||1;// 设备像素比constrectcanvas.getBoundingClientRect();// 设置虚拟尺寸为显示尺寸 * 像素比canvas.widthrect.width*dpr;canvas.heightrect.height*dpr;// 缩放上下文确保绘制比例正确ctx.scale(dpr,dpr);// 重新设置样式尺寸canvas.style.width${rect.width}px;canvas.style.height${rect.height}px;}8.2 路径绘制异常问题线条重复绘制或样式混乱。解决方案beginPath()必须在每次绘制新路径前调用避免与之前的路径状态关联。8.3 图像跨域问题问题绘制跨域图片后调用toDataURL()会报错。解决方案1. 服务器设置CORS响应头2. 图片添加crossOrigin属性。constimgnewImage();img.crossOriginanonymous;// 启用跨域img.srchttps://example.com/image.png;九、核心知识点总结核心流程获取Canvas元素 → 获取2D上下文 → 调用绘图API → 渲染图形关键概念区分虚拟画布尺寸attribute与可视尺寸style路径绘制需用beginPath()重置常用APIfillRect/strokeRect矩形、arc圆形、moveTo/lineTo路径、drawImage图像进阶技巧利用save()/restore()管理状态通过变换简化复杂绘图适配设备像素比解决模糊问题。Canvas的学习核心在于实践建议从基础图形开始逐步尝试动画和交互效果结合实际场景加深理解。