初学Canvas,我画了只小猪佩奇来耍耍

1,698 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

Hello,这里是mouche,当然你也可以叫我某车,反正大家都爱这么叫😁

今天看到了在收藏榜看到了这篇文章 案例+图解带你一文读懂Canvas🔥🔥(2W+字) - 掘金 (juejin.cn),想着我对于canvas的了解还局限在知道它是什么东西的程度上,于是我就来整活了

为了去熟练地使用一些canvas常用操作,我决定画只小猪佩奇,也不知道是谁给我的勇气😅😅😅,当然,实操到一半我就后悔了55555🥲,不过我还是把它完成了就是说 ,还挺丑

跟着我,带你一步一步走进猪的世界

一、准备工作

  • 先找个放猪的容器canvas,这里宽设置了1200,高设置了600
  <canvas width="1200" height="600" id="canvas">
    当前浏览器不支持canvas元素
  </canvas>
  • 然后获取它进行操作
const canvas = document.getElementById('canvas');
if(canvas.getContext) {
 // 获取绘图上下文
 var ctx = canvas.getContext('2d');
 //然后就可以咔咔咔咔进行操作了
}
  • 这里我顺便还设置了一下样式
 ctx.fillStyle = 'pink'; //填充的颜色为粉红色
 ctx.strokeStyle = "#f95a75"; //描线的颜色
 ctx.lineWidth = 4; //描线的厚度

前面会详细一点,后面就阿巴阿巴了

二、吹风机头

  • 这个我一直不知道要怎么处理比较好,最后调啊调啊,采用两个半圆加上一个椭圆完成
  • 下面先绘制一个半圆
    • 每一次绘画前都要用ctx.beginPath()开启绘画,防止跟前面的藕断丝连
    • 画圆的操作:ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise)
      • x,y为圆的圆心坐标
      • radius为半径
      • startAngle,endAngle 分别为圆弧或圆的开始位置,结束位置
      • anticlockwise是绘画方向,默认false为顺时针方向
 ctx.beginPath();
 ctx.arc(300, 200, 80, 0, Math.PI, false);
 ctx.fill();
  • 右上角也是一个半圆,一样的操作
 ctx.beginPath();
 ctx.arc(310, 200, 70, 0 , Math.PI,true);
 ctx.fill();
  • 左上角为一个椭圆
    • 椭圆操作:ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
      • x,y为椭圆圆心坐标
      • radiusx为椭圆的在x轴和y轴的半径
      • rotation:椭圆自身旋转的方向
      • startAngle,endAngle 分别为圆弧的开始位置,结束位置
      • anticlockwise是绘画方向,默认false为顺时针方向
 ctx.beginPath();
 ctx.ellipse(250, 160, 120, 60, Math.PI*0.1, 0, 2 * Math.PI);
 ctx.fill();

image.pngimage.pngimage.png

这样看好丑,我们快搞个猪鼻子来遮遮丑

三、五官

👉鼻子

  • 先召唤鼻子出来把那个椭圆的前面挡掉,它太圆啦
  • 鼻子也是采用了一个椭圆
  • 设置了 ctx.globalCompositeOperation = 'source-over',目的是为了它能够在最前面不被遮挡
  • 把描线的宽度改为3ctx.lineWidth = 3
 ctx.beginPath();
 ctx.ellipse(162, 127, 22, 32, Math.PI*0.12, 0,2*Math.PI, true);
 ctx.globalCompositeOperation = 'source-over'
 ctx.lineWidth = 3;
 ctx.fill();
 ctx.stroke();

image.png

👉耳朵

  • 耳朵大概让它看起来更像一个头吧
  • 耳朵采用了两个小椭圆
  • 注意这里采用了: ctx.globalCompositeOperation = 'destination-over',就是表示它要当缩头乌龟了,跟其他重叠的地方它要隐藏,不然我们这里椭圆下面描线外露就会很丑就是说
  • 这里的椭圆我也给他倾斜了,不是直挺挺立着的
 ctx.beginPath();
 ctx.ellipse(250, 100, 15, 40, Math.PI*0.05, 0, 2 * Math.PI, true);
 ctx.ellipse(300, 115, 15, 40, Math.PI*0.1, 0, 2 * Math.PI, true);
 ctx.globalCompositeOperation = 'destination-over'
 ctx.fill();
 ctx.stroke();

image.png

很好,现在已经很有猪感

👉眼睛

  • 眼睛是灵魂,我们来画猪点睛
  • 眼睛这里是采用外面用白色的填充,里面填充一个小黑点,左右眼的操作是一样的,下面是左眼的操作,右眼就不废话啦
 ctx.beginPath();
 ctx.arc(235,125,12,0,Math.PI*2); //这里是外面的白色的那个圆
 ctx.fillStyle = '#fff'
 ctx.globalCompositeOperation = 'source-over' //注意这里也是让它不要被遮挡
 ctx.fill();
 ctx.stroke();
 ctx.beginPath();
 ctx.arc(232,123,4,0, Math.PI*2); //这里画中间的小黑眼珠
 ctx.fillStyle = 'black';
 ctx.fill();

image.png

很好,不愧是灵魂的存在,我已经要爱上这只猪了

👉嘴巴

  • 嘴巴我们要求的是《微笑唇》
  • 不过它相当简单,给他加个圆弧就好了,不过这里是歪嘴巴哦,所以我调了一下数据
 ctx.beginPath();
 ctx.arc(280,215, 35, Math.PI*0.2, Math.PI);
 ctx.stroke();

image.png

因为我对它逐渐喜爱,所以它害羞了,来给它加点腮红

👉腮红

  • 加个填充圆就好了
 ctx.beginPath();
 ctx.arc(325, 200, 30, 0, Math.PI*2);
 ctx.fillStyle = '#ff9cc1'
 ctx.fill();

image.png

头到这里就搞定了,堂堂佩奇大丈夫当然要有身子

四、身体

👉衣服

  • 先上衣服遮遮羞,大家都知道,咱们小猪当然是穿裙子最好啦(Bushi,是因为最方便画)
  • 这里采用了画线(梯形)填充 + 二次贝塞尔线填充,让裙子更有感觉
  • 这里依旧使用了 ctx.globalCompositeOperation = 'destination-over' ,不清楚为啥用的回看耳朵那里
  • 二次贝塞尔线:quadraticCurveTo(cp1x, cp1y, x, y)
 ctx.beginPath();
 ctx.globalCompositeOperation = 'destination-over'  //不会有人到这里都不知道它是干嘛的吧
 ctx.fillStyle = '#ff6464';
 ctx.moveTo(240,245);
 ctx.lineTo(200,400);
 ctx.lineTo(400,400);
 ctx.lineTo(350,245); //到这里目的是给它传上了一件程梯形形状的裙子
 ctx.moveTo(240, 245);  //给裙子左边加点弧度
 ctx.quadraticCurveTo(177, 350, 200, 400);
 ctx.moveTo(350, 245);  //给裙子右边加点弧度
 ctx.quadraticCurveTo(448, 350, 400, 400);
 ctx.fill();

image.png

这裙子不能买,显胖

👉手

  • 手这里我们就简简单单过了,使用的东西我们之前基本都用过
  • 下面的代码为左手,右手的我忽略了
 ctx.beginPath();
 ctx.moveTo(230, 290);
 ctx.lineTo(150, 320);
 ctx.stroke();
 ctx.beginPath();
 ctx.moveTo(175, 312);
 ctx.lineTo(145, 310);
 ctx.moveTo(175, 312);
 ctx.lineTo(170, 330);
 ctx.stroke();

image.png

👉脚

  • 脚就更简单了哈哈,把线调粗一点,画两条线即可
  • 依旧是左脚代码
 ctx.beginPath();
 ctx.strokeStyle = '#f08181';
 ctx.lineWidth = 10;
 ctx.moveTo(260,400);
 ctx.lineTo(260,450);
 ctx.stroke();

image.png

俗话说,赤脚不怕穿鞋的,但是我们猪猪哪里需要那么凶,就要鞋就要鞋

👉皮鞋

  • 先来双破鞋
  • 又一看,感觉这个鞋子,四四方方,那里像双鞋子的样子
 ctx.beginPath();
 ctx.strokeStyle = 'black';
 ctx.globalCompositeOperation = 'source-over'
 ctx.lineWidth = 15;
 ctx.moveTo(260,450);
 ctx.lineTo(240,450);
 ctx.stroke();

image.png

  • 来加点料
  • 我们可以通过 lineCap设置线条的样式
    • butt:默认的就是它,方方正正,端点是垂直于线段边缘的平直边缘
    • round:这个就是我们皮鞋的正宗用料了,端点是在线段边缘处以线宽为直径的半圆
    • square:端点是在线段边缘处以线宽为长,以一半线宽为宽的矩形
  • 所以我们给他设置 ctx.lineCap='round',就相当于给它穿上高级鞋子了 image.png

五、文字

  • 既然本意是来熟练操作的,那么自然不能放过文字啦
  • 文本也是两种方式,分别为填充和描边,我们这里使用的是填充
  • 填充文字:ctx.fillText(text, x, y, maxWidth)
    • text:绘制的文案
    • xy:文本的起始位置
    • maxWidth:可选参数,最大宽度
 ctx.beginPath();
 ctx.fillStyle = 'pink'
 ctx.ellipse(550, 150, 150, 100, 0, 0, 2 * Math.PI);
 ctx.fill();
 ctx.beginPath();
 ctx.font = "50px serif"; // 设置文案大小和字体
 ctx.fillStyle = "#ee7934"; //  设置填充颜色
 ctx.fillText('不准再说我丑了', 450, 160, 200); //这里去填充文字

六、码上掘金

  • 老规矩,上代码

七、絮絮念

  • 恭喜你见证了一只猪的诞生,但是鬼知道我调它的坐标调了多久......................😵‍💫
  • 但是还是恭喜你通过一只猪,熟练了一些canvas常用操作🤭
    • 使用了用直线绘制形状,填充形状,设置线条样式
    • 使用了圆,椭圆,二次贝塞尔线
    • 使用了文字,设置文字样式
    • 使用了合成,去解决绘制顺序带来的限制

到这里就都完成啦, 觉得还不错的点个赞吧🥰