HTML5 Canvas的核心方法与属性详细讲解

HTML5 Canvas核心API详解

文章目录

HTML5 Canvas的核心方法与属性详细讲解

HTML5 Canvas 的强大之处在于其丰富的绘图 API,通过 CanvasRenderingContext2D(2D 上下文,简称 ctx)提供的方法和属性,能实现从简单图形到复杂动画的全场景绘制。以下是最核心的方法与属性,按功能分类详解:

一、Canvas 元素基础:画布的「尺寸与上下文」

Canvas 元素本身的属性和方法是绘图的基础,决定了画布的「容器特性」。

1. widthheight 属性(Canvas 元素)
  • 功能:定义画布的实际像素尺寸(绘图坐标系的范围),是绘图的「真实画布大小」。
  • 用法:必须通过元素属性设置(而非 CSS),否则图形会按 CSS 尺寸拉伸。
  • 示例
    <!-- 正确:600x400 像素的画布 -->
    <canvas id="myCanvas" width="600" height="400"></canvas>
    
    <style>
      #myCanvas { 
        border: 1px solid #000; 
        /* 错误:用 CSS 设置宽高会导致拉伸(如设为 300px 会压缩画布) */
        /* width: 300px;  */
      }
    </style>
    
  • 注意:若通过 JS 动态修改,需直接赋值(canvas.width = 800),修改后画布会清空并重置。
2. getContext('2d') 方法(Canvas 元素)
  • 功能:获取 2D 绘图上下文对象(ctx),所有绘图操作均通过该对象执行,是 Canvas 绘图的「入口」。
  • 用法:调用后返回 CanvasRenderingContext2D 实例,包含所有绘图方法。
  • 示例
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d'); // 获取 2D 上下文,后续操作通过 ctx 完成
    
  • 注意:若浏览器不支持 Canvas,getContext 会返回 null,可提前判断兼容性。

二、路径绘制:图形的「骨架搭建」

路径是 Canvas 绘图的基础,通过一系列点和线定义图形轮廓,再通过「填充」或「描边」显式化。

1. beginPath()closePath()(ctx 方法)
  • 功能beginPath() 开启新路径(隔离当前图形与之前的路径);closePath() 闭合路径(连接当前点与起点)。
  • 用法:绘制任何图形前需用 beginPath() 初始化路径,避免与上一路径关联。
  • 示例
    // 绘制三角形(闭合路径)
    ctx.beginPath(); // 开启新路径
    ctx.moveTo(100, 100); // 起点
    ctx.lineTo(200, 100); // 线段1
    ctx.lineTo(150, 50); // 线段2
    ctx.closePath(); // 闭合(连接(150,50)到(100,100))
    ctx.stroke(); // 描边显示
    
  • 注意closePath() 仅闭合路径,不会自动描边/填充,需配合 stroke()fill()
2. moveTo(x, y)lineTo(x, y)(ctx 方法)
  • 功能moveTo(x, y) 移动画笔到指定坐标(不绘制);lineTo(x, y) 从当前点绘制线段到目标坐标。
  • 用法:用于绘制折线、多边形等线性图形。
  • 示例
    ctx.beginPath();
    ctx.moveTo(50, 50); // 移动到起点(50,50)
    ctx.lineTo(200, 50); // 水平线
    ctx.lineTo(200, 150); // 垂直线
    ctx.lineTo(50, 150); // 水平线
    ctx.closePath(); // 闭合为矩形
    ctx.fillStyle = 'lightblue';
    ctx.fill(); // 填充
    
3. arc(x, y, r, startAngle, endAngle, anticlockwise)(ctx 方法)
  • 功能:绘制圆弧或圆形,参数分别为:圆心坐标 (x,y)、半径 r、起始角度(弧度)、结束角度(弧度)、是否逆时针(false 为顺时针)。
  • 用法:圆形是 startAngle=0endAngle=2π 的圆弧。
  • 示例
    // 绘制半圆(上半圆)
    ctx.beginPath();
    ctx.arc(300, 100, 50, Math.PI, 0, false); // 从π(180°)到0(0°),顺时针
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 3;
    ctx.stroke();
    
    // 绘制完整圆形
    ctx.beginPath();
    ctx.arc(400, 100, 50, 0, Math.PI * 2, false); // 0到2π(360°)
    ctx.fillStyle = 'green';
    ctx.fill();
    
  • 注意:角度需用弧度(角度 × Math.PI / 180 转换,如 90° 为 Math.PI/2)。
4. rect(x, y, width, height)(ctx 方法)
  • 功能:创建矩形路径(等价于用 moveTo+lineTo 绘制矩形轮廓)。
  • 用法:需配合 stroke()fill() 显式化,也可直接用 strokeRect/fillRect 简化。
  • 示例
    ctx.beginPath();
    ctx.rect(50, 200, 150, 80); // x=50,y=200,宽150,高80
    ctx.strokeStyle = 'purple';
    ctx.stroke();
    

三、样式与颜色:图形的「外观装饰」

通过样式属性控制图形的填充、描边效果,决定视觉呈现。

1. fillStylestrokeStyle(ctx 属性)
  • 功能fillStyle 定义填充颜色/样式;strokeStyle 定义描边颜色/样式,支持:
    • 颜色值(#ff0000rgb(255,0,0)rgba(255,0,0,0.5));
    • 渐变对象(createLinearGradient/createRadialGradient);
    • 图案对象(createPattern)。
  • 示例
    // 1. 纯色
    ctx.fillStyle = '#ffcc00';
    ctx.fillRect(50, 50, 100, 100);
    
    // 2. 线性渐变
    const linearGrad = ctx.createLinearGradient(200, 50, 300, 150); // 从(200,50)到(300,150)
    linearGrad.addColorStop(0, 'blue');
    linearGrad.addColorStop(1, 'pink');
    ctx.fillStyle = linearGrad;
    ctx.fillRect(200, 50, 100, 100);
    
    // 3. 图案填充
    const img = new Image();
    img.src = 'dot.png';
    img.onload = () => {
      const pattern = ctx.createPattern(img, 'repeat'); // 重复图案
      ctx.strokeStyle = pattern;
      ctx.lineWidth = 10;
      ctx.strokeRect(350, 50, 100, 100);
    };
    
2. lineWidthlineCaplineJoin(ctx 属性)
  • 功能
    • lineWidth:线段宽度(默认1px);
    • lineCap:线段端点样式(butt 平角/round 圆角/square 方角,默认 butt);
    • lineJoin:线段连接处样式(miter 尖角/round 圆角/bevel 斜角,默认 miter)。
  • 示例
    ctx.lineWidth = 10;
    ctx.lineCap = 'round'; // 端点圆角
    ctx.lineJoin = 'round'; // 连接处圆角
    
    ctx.beginPath();
    ctx.moveTo(50, 200);
    ctx.lineTo(150, 150);
    ctx.lineTo(250, 200);
    ctx.stroke();
    

四、文本绘制:画布上的「文字排版」

通过文本方法在画布上绘制文字,支持填充和描边。

1. fillText(text, x, y, [maxWidth])strokeText(text, x, y, [maxWidth])(ctx 方法)
  • 功能fillText 绘制填充文字;strokeText 绘制描边文字,参数为:文本内容、起点坐标 (x,y)、可选最大宽度(超过会压缩)。
  • 用法:需先设置 fonttextAlign 等样式属性。
  • 示例
    ctx.font = 'bold 36px "Microsoft YaHei"'; // 字体样式(必须设置,否则默认10px sans-serif)
    ctx.textAlign = 'center'; // 水平对齐(left/center/right)
    ctx.textBaseline = 'middle'; // 垂直对齐(top/middle/bottom)
    
    ctx.fillStyle = '#333';
    ctx.fillText('Canvas 文本', 300, 100); // 在(300,100)居中绘制填充文字
    
    ctx.strokeStyle = 'red';
    ctx.strokeText('描边文字', 300, 150); // 绘制描边文字
    

五、图像操作:画布上的「图片处理」

通过 drawImage 方法在画布上绘制图片,支持完整绘制、缩放、裁剪。

drawImage()(ctx 方法,多参数形式)
  • 功能
    • 基础:drawImage(img, x, y) → 在 (x,y) 绘制完整图片;
    • 缩放:drawImage(img, x, y, w, h) → 绘制图片并缩放到 w×h
    • 裁剪:drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh) → 裁剪原图 (sx,sy) 开始的 sw×sh 区域,绘制到 (dx,dy) 并缩放到 dw×dh
  • 示例
    const img = new Image();
    img.src = 'scene.jpg'; // 图片路径
    img.onload = () => {
      // 1. 绘制完整图片到(50,50)
      ctx.drawImage(img, 50, 50);
      
      // 2. 缩放绘制(缩放到200x150)
      ctx.drawImage(img, 350, 50, 200, 150);
      
      // 3. 裁剪绘制(裁剪原图(100,100)开始的200x200区域,绘制到(50, 250)并缩放到150x150)
      ctx.drawImage(img, 100, 100, 200, 200, 50, 250, 150, 150);
    };
    
  • 注意:图片必须加载完成(onload 事件触发)后才能绘制,否则无效果;跨域图片绘制后会污染画布,导致无法用 toDataURL 导出。

六、变换与状态:坐标系的「乾坤大挪移」

通过变换方法修改坐标系,实现旋转、缩放、平移,配合状态保存/恢复管理绘图状态。

1. translate(x, y)rotate(angle)scale(sx, sy)(ctx 方法)
  • 功能
    • translate(x,y):平移坐标系原点到 (x,y)(后续绘图基于新原点);
    • rotate(angle):旋转坐标系(以当前原点为中心,角度为弧度);
    • scale(sx,sy):缩放坐标系(sx 水平缩放,sy 垂直缩放,1为原尺寸)。
  • 示例
    // 绘制旋转的矩形
    ctx.save(); // 保存当前状态(原点、旋转等)
    
    ctx.translate(200, 200); // 原点移到(200,200)
    ctx.rotate(Math.PI / 4); // 旋转45°(π/4弧度)
    
    ctx.fillStyle = 'orange';
    ctx.fillRect(-50, -50, 100, 100); // 以新原点为中心绘制100x100矩形
    
    ctx.restore(); // 恢复到保存的状态(避免影响后续绘图)
    
2. save()restore()(ctx 方法)
  • 功能save() 保存当前绘图状态(样式、变换、裁剪路径等)到栈中;restore() 从栈中恢复最近保存的状态。
  • 用法:用于隔离变换或样式,避免相互影响(必备技巧)。

七、像素操作:画布的「底层控制」

直接操作像素数据,实现滤镜、颜色处理等高级效果。

getImageData(x, y, w, h)putImageData(data, x, y)(ctx 方法)
  • 功能getImageData 获取 (x,y) 开始的 w×h 区域像素数据(ImageData 对象,data 属性为 [r,g,b,a,r,g,b,a,...] 数组);putImageData 将像素数据绘制到画布。
  • 示例:实现灰度滤镜
    // 假设画布已有图像,处理为灰度
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;
    
    for (let i = 0; i < data.length; i += 4) {
      const r = data[i];
      const g = data[i + 1];
      const b = data[i + 2];
      // 灰度公式:亮度 = 0.299r + 0.587g + 0.114b
      const gray = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
      data[i] = data[i + 1] = data[i + 2] = gray; // r=g=b=灰度值
    }
    
    ctx.putImageData(imageData, 0, 0); // 绘制处理后的像素
    
  • 注意:像素操作性能消耗大,避免在动画中频繁调用;跨域图片会导致 getImageData 报错(画布污染)。

八、合成与裁剪:图形的「混合魔法」

控制图形的叠加方式和绘制范围,实现复杂视觉效果。

1. globalCompositeOperation(ctx 属性)
  • 功能:定义新绘制图形与已有图形的混合模式(默认 source-over:新图形覆盖旧图形)。
  • 常用模式:
    • destination-over:新图形在旧图形下方;
    • lighter:新旧图形叠加,颜色相加(变亮);
    • xor:重叠区域透明。
  • 示例
    // 绘制红色圆形
    ctx.beginPath();
    ctx.arc(150, 150, 50, 0, Math.PI * 2);
    ctx.fillStyle = 'red';
    ctx.fill();
    
    // 切换合成模式:新图形在下方
    ctx.globalCompositeOperation = 'destination-over';
    
    // 绘制蓝色圆形(会显示在红色圆形下方)
    ctx.beginPath();
    ctx.arc(200, 150, 50, 0, Math.PI * 2);
    ctx.fillStyle = 'blue';
    ctx.fill();
    
2. clip()(ctx 方法)
  • 功能:将后续绘制限制在当前路径内(裁剪路径),超出路径的部分不显示。
  • 示例:圆形内显示图片
    // 创建圆形裁剪路径
    ctx.beginPath();
    ctx.arc(300, 200, 80, 0, Math.PI * 2);
    ctx.clip(); // 裁剪为圆形区域
    
    // 绘制图片(仅圆形区域可见)
    const img = new Image();
    img.src = 'photo.jpg';
    img.onload = () => {
      ctx.drawImage(img, 220, 120, 160, 160); // 图片大小与圆形匹配
    };
    

注意事项总结

  1. 宽高设置:必须通过 canvas.width/height 属性设置,而非 CSS,否则图形拉伸。
  2. 路径隔离:每次绘制新图形前用 beginPath(),避免路径关联导致意外描边。
  3. 图像加载drawImage 必须在图片 onload 后调用,跨域图片会污染画布。
  4. 性能优化:像素操作、复杂路径绘制耗时,动画中优先用 requestAnimationFrame 并减少重绘区域。
  5. 状态管理:变换或样式修改后,用 save()/restore() 隔离状态,避免影响后续绘图。

核心总结

HTML5 Canvas 的核心能力源于 CanvasRenderingContext2D 的方法与属性:通过路径定义图形骨架,样式控制外观,变换修改坐标系,像素操作实现底层控制,合成与裁剪创造复杂效果。掌握这些 API 后,可从简单图形扩展到动画、游戏、数据可视化等高级场景,核心是理解「画布即像素集合」,所有操作最终都是对像素的读写与计算。

第1章 基础知识 1 1.1 canvas元素 1 1.1.1 canvas元素的大小绘图表面的大小 4 1.1.2 canvas元素的api 5 1.2 canvas的绘图环境 6 1.2.1 2d绘图环境 6 1.2.2 canvas状态的保存恢复 8 1.3 本书程序清单的规范格式 9 1.4 开始学习html5 10 1.4.1 规范 10 1.4.2 浏览器 11 1.4.3 控制台调试器 11 1.4.4 性能 13 1.5 基本的绘制操作 15 1.6 事件处理 18 1.6.1 鼠标事件 18 1.6.2 键盘事件 22 .1.6.3 触摸事件 23 1.7 绘制表面的保存恢复 23 1.8 在canvas中使用html元素 25 1.9 打印canvas的内容 32 1.10 离屏canvas 35 1.11 基础数学知识简介 37 1.11.1 求解代数方程 37 1.11.2 三角函数 38 1.11.3 向量运算 39 1.11.4 根据计量单位来推导等式 42 1.12 总结 44 第2章 绘制 45 2.1 坐标系统 46 2.2 canvas的绘制模型 47 2.3 矩形的绘制 48 2.4 颜色透明度 50 2 .5 渐变色图案 52 2.5.1 渐变色 52 2.5.2 图案 54 2.6 阴影 57 2.7 路径、描边填充 60 2.7.1 路径子路径 63 2.7.2 剪纸效果 64 2.8 线段 69 2.8.1 线段像素边界 70 2.8.2 网格的绘制 71 2.8.3 坐标轴的绘制 72 2.8.4 橡皮筋式的线条绘制 74 2.8.5 虚线的绘制 79 2.8.6 通过扩展canvasrenderingcontext2d来绘制虚线 80 2.8.7 线段端点连接点的绘制 81 2.9 圆弧圆形的绘制 83 2.9.1 arc()方法的用法 83 2.9.2 以橡皮筋式辅助线来协助用户画圆 85 2.9.3 arcto()方法的用法 86 2.9.4 刻度仪表盘的绘制 88 2.10 贝塞尔曲线 93 2.10.1 二次方贝塞尔曲线 93 2.10.2 三次方贝塞尔曲线 95 2.11 多边形的绘制 97 2.12 高级路径操作 102 2.12.1 拖动多边形对象 102 2.12.2 编辑贝塞尔曲线 107 2.12.3 自动滚动网页,使某段路径所对应的元素显示在视窗中 115 2.13 坐标变换 116 2.13.1 坐标系的平移、缩放旋转 116 2.13.2 自定义的坐标变换 119 2.14 图像合成 123 2.15 剪辑区域 128 2.15.1 通过剪辑区域来擦除图像 128 2.15.2 利用剪辑区域来制作伸缩式动画 133 2.16 总结 135 第3章 文本 137 3.1 文本的描边填充 137 3.2 设置字型属性 141 3.3 文本的定位 144 3.3.1 水平垂直定位 144 3.3.2 将文本居中 146 3.3.3 文本的度量 147 3.3.4 绘制坐标轴旁边的文本标签 148 3.3.5 绘制数值仪表盘周围的文本标签 151 3.3.6 在圆弧周围绘制文本 152 3.4 实现文本编辑控件 154 3.4.1 指示文本输入位置的光标 154 3.4.2 在canvas中编辑文本 159 3.4.3 文本段的编辑 163 3.5 总结 174 第4章 图像视频 175 4.1 图像的绘制 176 4.1.1 在canvas之中绘制图像 176 4.1.2 drawimage()方法的用法 177 4.2 图像的缩放 179 4.3 将一个canvas绘制到另一个canvas之中 183 4.4 离屏canvas 186 4.5 操作图像的像素 189 4.5.1 获取图像数据 189 4.5.2 修改图像数据 195 4.6 结合剪辑区域来绘制图像 208 4.7 以图像制作动画 211 4.8 图像绘制的安全问题 216 4.9 性能 216 4.9.1 对比drawimage(htmlimage)、drawimage(htmlcanvas)putimagedata()的绘图效率 217 4.9.2 在canvas中绘制另一个canvas绘制普通图像之间的对比;在绘制时缩放图像保持原样之间的对比 217 4.9.3 遍历图像数据 218 4.10 放大镜 222 4.10.1 使用离屏canvas 224 4.10.2 接受用户从文件系统中拖放进来的图像 225 4.11 视频处理 227 4.11.1 视频格式 227 4.11.2 在canvas中播放视频 229 4.11.3 视频处理 230 4.12 总结 234 第5章 动画 235 5.1 动画循环 235 5.1.1 通过requestanimationframe()方法让浏览器来自行决定帧速率 237 5.1.2 internet explorer浏览器对requestanimationframe()功能的实现 241 5.1.3 可移植于各浏览器平台的动画循环逻辑 241 5.2 帧速率的计算 248 5.3 以不同的帧速率来执行各种任务 249 5.4 恢复动画背景 250 5.4.1 利用剪辑区域来处理动画背景 250 5.4.2 利用图块复制技术来处理动画背景 252 5.5 利用双缓冲技术绘制动画 253 5.6 基于时间的运动 254 5.7 背景的滚动 257 5.8 视差动画 261 5.9 用户手势 264 5.10 定时动画 266 5.10.1 秒表 266 5.10.2 动画计时器 269 5.11 动画制作的最佳指导原则 270 5.12 总结 271 第6章 精灵 272 6.1 精灵概述 273 6.2 精灵绘制器 275 6.2.1 描边填充绘制器 275 6.2.2 图像绘制器 279 6.2.3 精灵表绘制器 281 6.3 精灵对象的行为 284 6.3.1 将多个行为组合起来 285 6.3.2 限时触发的行为 287 6.4 精灵动画制作器 289 6.5 基于精灵的动画循环 293 6.6 总结 294 第7章 物理效果 295 7.1 重力 295 7.1.1 物体的下落 296 7.1.2 抛射体弹道运动 298 7.1.3 钟摆运动 307 7.2 时间轴扭曲 311 7.3 时间轴扭曲函数 315 7.4 时间轴扭曲运动 317 7.4.1 没有加速度的线性运动 319 7.4.2 逐渐加速的缓入运动 320 7.4.3 逐渐减速的缓出运动 322 7.4.4 缓入缓出运动 323 7.4.5 弹簧运动弹跳运动 324 7.5 以扭曲后的帧速率播放动画 326 7.6 总结 332 第8章 碰撞检测 333 8.1 外接图形判别法 333 8.1.1 外接矩形判别法 333 8.1.2 外接圆判别法 334 8.2 碰到墙壁即被弹回的小球 336 8.3 光线投射法 337 8.4 分离轴定理(sat)最小平移向量(mtv) 340 8.4.1 使用分割轴定理检测碰撞 340 8.4.2 根据最小平移向量应对碰撞 362 8.5 总结 373 第9章 游戏开发 374 9.1 游戏引擎 374 9.1.1 游戏循环 376 9.1.2 加载图像 382 9.1.3 同时播放多个声音 384 9.1.4 键盘事件 385 9.1.5 高分榜 386 9.1.6 游戏引擎源代码 387 9.2 游戏原型 395 9.2.1 游戏原型程序的html代码 396 9.2.2 原型程序的游戏循环 399 9.2.3 游戏原型程序的加载画面 400 9.2.4 暂停画面 402 9.2.5 按键监听器 404 9.2.6 游戏结束及高分榜 404 9.3 弹珠台游戏 407 9.3.1 游戏循环弹珠 408 9.3.2 弹珠精灵 410 9.3.3 重力摩擦力 411 9.3.4 弹板的移动 412 9.3.5 处理键盘事件 413 9.3.6 碰撞检测 416 9.4 总结 425 第10章 自定义控件 426 10.1 圆角矩形控件 427 10.2 进度条控件 433 10.3 滑动条控件 437 10.4 图像查看器控件 446 10.5 总结 454 第11章 移动平台开发 455 11.1 移动设备的视窗 456 11.2 媒体特征查询技术 461 11.2.1 媒体特征查询css 461 11.2.2 用javascript程序应对媒体特征的变化 462 11.3 触摸事件 464 11.3.1 touchevent对象 464 11.3.2 touchlist对象 465 11.3.3 touch对象 466 11.3.4 同时支持触摸事件鼠标事件 466 11.3.5 手指缩放 468 11.4 ios5 469 11.4.1 应用程序图标及启动画面 469 11.4.2 利用媒体特征查询技术设置ios5系统的应用程序图标及启动画面 470 11.4.3 以不带浏览器饰件的全屏模式运行应用程序 471 11.4.4 应用程序的状态栏 471 11.5 虚拟键盘 472 11.6 总结 485
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值