所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

HTML5 Canvas绘制图形从入门到精通:超详细实操教程,新手一看就会

HTML5 Canvas绘制图形从入门到精通:超详细实操教程,新手一看就会 一

文章目录CloseOpen

从0到1:先把Canvas的“地基”打牢

想画好Canvas,第一步不是学怎么画圆,而是先把“画布”和“画笔”搞明白——这俩是所有操作的基础,我之前跳过这步直接画,结果折腾了俩小时没出结果,后来才发现是漏了最关键的“拿画笔”步骤。

你得在HTML里“搭个画布”:用标签,比如 。注意!width和height一定要写在标签里,别用CSS设——我之前犯过傻,用CSS把画布设成400×300,结果画的圆变成椭圆,查了MDN文档(https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/canvasnofollow)才知道:CSS会拉伸画布的“像素格子”,而标签里的width/height是原始尺寸,就像你在A4纸上画画,别把纸揉皱了再画。

要“拿画笔”——用JavaScript获取“2D上下文”(也就是2D的绘图环境)。代码很简单:const ctx = document.getElementById('myCanvas').getContext('2d');。这里的ctx就是你的“画笔”,之后所有的画直线、画圆都是用它来操作。我第一次帮朋友做动画时,漏了这行代码,结果ctx.fillRect()写了半天没反应,还以为是浏览器坏了,现在想起来都觉得好笑。

再强调个小细节:每次画新图形前,最好用beginPath()——这就像你画完一幅画,换张新纸再画,不然之前的路径会和新路径混在一起,比如你先画了个红圆,没写beginPath()就画蓝方,结果蓝方会带着红边,我之前就犯过这错,把客户要的“清新图标”画成了“花脸”。

从简单到复杂:一步步画出能“拿得出手”的图形

等你把地基打牢,就能开始画“像样”的图形了——我把这个过程分成三步,跟着走保证不迷路。

第一步:先画最基础的形状,搞定“基本功”

新手先从直线、矩形、圆开始,这些是所有复杂图形的“积木”。

  • 画直线:用moveTo(x1,y1)(笔移到起点)和lineTo(x2,y2)(笔拉到终点),最后用stroke()(描边)或者fill()(填充)。比如画一条从(50,50)到(350,50)的横线,代码是:ctx.beginPath(); ctx.moveTo(50,50); ctx.lineTo(350,50); ctx.strokeStyle = 'blue'; ctx.stroke();。我之前画直线总忘加stroke(),结果“笔”动了但没痕迹,后来才明白:moveTolineTo是“规划路线”,stroke是“实际下笔”。
  • 画矩形:有两个方法——fillRect(x,y,width,height)(填充矩形)和strokeRect(x,y,width,height)(描边矩形)。比如画一个红色填充的100×100矩形,代码是:ctx.fillStyle = 'red'; ctx.fillRect(150,100,100,100);。注意fillStyle要写在fillRect前面,不然颜色不会生效——我之前总把顺序搞反,画了个“默认黑色”的矩形,还以为颜色代码错了。
  • 画圆:用arc(x,y,r,startAngle,endAngle,anticlockwise)。参数里的“角”是弧度制,比如画一个完整的圆,startAngle是0,endAngle2Math.PI(也就是360度)。我之前总记不住弧度和角度的换算,后来用“偷懒法”:直接用Math.PI代替180度,比如画半圆就用Math.PI当结束角,再也没算错过。
  • 给你个“偷懒表格”,我把常用方法整理成了“傻瓜版”,直接抄就能用:

    方法名 作用 基础参数 我的“偷懒”技巧
    fillRect() 画填充矩形 x,y,宽,高 先设fillStyle,再画
    arc() 画圆/圆弧 x,y,半径,起始角,结束角,是否逆时针 用2Math.PI画整圆,不用算弧度
    lineTo() 画直线 终点x,y 先moveTo起点,再lineTo

    第二步:进阶!用路径画复杂图形(比如五角星)

    等你会画基础形状,就能用“路径(Path)”画复杂图形了——比如五角星、爱心,这些都是用moveTolineTo连出来的。我第一次画五角星时,查了坐标公式:五角星的顶点坐标是(rMath.cos(angle), rMath.sin(angle)),其中angle是每个顶点的角度(比如第一个顶点在0度,第二个在72度,因为360/5=72)。

    给你个“能直接复制”的五角星代码:

    ctx.beginPath();
    

    const r = 100; // 五角星半径

    const x0 = 200; // 中心x坐标

    const y0 = 150; // 中心y坐标

    for (let i = 0; i < 5; i++) {

    const angle = (i 2 Math.PI) / 5

  • Math.PI / 2; // 调整到12点方向开始
  • const x = x0 + r Math.cos(angle);

    const y = y0 + r Math.sin(angle);

    if (i === 0) {

    ctx.moveTo(x, y); // 第一个点用moveTo

    } else {

    ctx.lineTo(x, y); // 后面的点用lineTo

    }

    }

    ctx.closePath(); // 闭合路径

    ctx.fillStyle = 'orange';

    ctx.fill(); // 填充颜色

    我第一次写这段代码时,把angle的起始值写错了,结果五角星“倒着”,后来把

  • Math.PI / 2
  • 加上,才让顶点对准12点方向——你要是画的时候方向不对,调这个数值就行。

    第三步:加特效!让图形“活”起来

    光画对形状还不够,加渐变阴影能让图形更生动——我帮电商客户做产品图时,就用这俩技巧把“普通的产品图标”变成了“有质感的卖点图”。

  • 渐变:分线性渐变(linearGradient)和径向渐变(radialGradient)。比如做一个“从蓝到粉”的线性渐变矩形,代码是:
  • javascript

    const gradient = ctx.createLinearGradient(0, 0, 400, 0); // 从左到右渐变

    gradient.addColorStop(0, ‘blue’); // 起点颜色

    gradient.addColorStop(1, ‘pink’); // 终点颜色

    ctx.fillStyle = gradient;

    ctx.fillRect(50, 50, 300, 100);

    我之前调渐变方向时,总搞混createLinearGradient的参数,后来记“前两个是起点坐标,后两个是终点坐标”,比如从下到上渐变就是(200, 300, 200, 0),这样就不会错了。

  • 阴影:用shadowColor(阴影颜色)、shadowBlur(模糊程度)、shadowOffsetX/Y(阴影偏移量)。比如给圆加个“软阴影”:
  • javascript

    ctx.shadowColor = ‘rgba(0,0,0,0.3)’;

    ctx.shadowBlur = 10;

    ctx.shadowOffsetX = 5;

    ctx.shadowOffsetY = 5;

    ctx.beginPath();

    ctx.arc(200, 150, 80, 0, 2*Math.PI);

    ctx.fillStyle = ‘yellow’;

    ctx.fill();

    注意!阴影会增加渲染负担,别给太多图形加——我之前给一个有10个图形的动画加阴影,结果页面卡成“幻灯片”,后来只给主图形加,才变流畅。

    现在你按这些步骤走,应该能画出第一个“拿得出手”的Canvas图形了——我当初学的时候,用了3天画出一个旋转的五角星,朋友看到都说“你居然会写代码画这个?”。其实真没那么难,关键是“多练+踩坑”——你要是画的时候遇到问题,比如图形不显示、颜色不对,先检查这几点:有没有getContext?有没有stroke/fill?是不是漏了beginPath?

    对了,如果你按这些方法画了第一个图形,欢迎在评论区发张截图——我帮你看看有没有可以优化的小细节,比如渐变方向能不能调得更自然,或者阴影的模糊度是不是刚好~


    为什么用CSS设置Canvas尺寸后,画的图形会变形?

    因为Canvas标签里的width/height是它的“原始像素尺寸”,就像你在A4纸上画画,纸本身的大小是固定的;但用CSS设置尺寸,相当于把这张纸拉伸或压缩,比如你把400×300的Canvas用CSS设成800×600,像素格子会被“拉大”,画的圆就会变成椭圆。我之前就犯过这错,查了MDN文档才搞明白,现在都直接在标签里写width和height。

    为什么我写了画图形的代码,却看不到任何效果?

    先检查两个关键点:第一,有没有用JavaScript获取“2D上下文”?就是那句const ctx = document.getElementById(‘myCanvas’).getContext(‘2d’);,这步是“拿画笔”,没拿画笔自然画不了;第二,有没有加stroke()或fill()?比如你用了fillRect但没写fill(),或者lineTo后没写stroke(),相当于“规划了路线但没下笔”,我第一次帮朋友做动画时就漏了这两步,折腾半天没反应。

    画多个图形时,为什么之前的颜色会蹭到新图形上?

    因为你没写beginPath()!这就像你画完一幅画,没换纸就接着画下一幅,之前的“路径”会和新路径混在一起。比如你先画了个红圆,没写beginPath()就画蓝方,蓝方的边会带着红颜色——我之前给客户画图标时就犯过这错,把“清新图标”画成了“花脸”,后来每次画新图形前都加beginPath(),就再也没乱过。

    怎么调整线性渐变的方向?比如想做从下到上的渐变?

    线性渐变的方向是由createLinearGradient的四个参数决定的,前两个是“渐变起点”的坐标,后两个是“渐变终点”的坐标。比如你想从下到上渐变,就把起点设成画布下方(比如x=200,y=300),终点设成画布上方(x=200,y=0),代码就是createLinearGradient(200, 300, 200, 0);如果想从左到右,就用(0,0,400,0)——我之前总搞混参数,后来记“起点到终点的连线就是渐变方向”,就再也没调错过。

    给图形加阴影后页面变卡,有什么解决办法吗?

    阴影会增加浏览器的渲染负担,就像你画水彩画时,每加一层阴影都要等干,加太多肯定慢。我之前给一个有10个图形的动画加了阴影,结果页面卡成“幻灯片”,后来改成只给主图形(比如核心图标)加阴影,次要图形不加,页面就流畅了。 你优先给最显眼的图形加阴影,别贪多。

    原文链接:https://www.mayiym.com/49910.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码