我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛
前言
最近在申请微信红包封面
的时候,突发奇想就来写篇文章吧,刚好掘金也有个兔了个兔
的创意活动。
可惜申请了好多个都被驳回了,还有两个在申请中,如果审核通过了,就在文章最后放出来几个给 JYM 当做福利吧。
本篇文章主要是使用canvas
绘制掘金兔年礼盒
上面的Logo,由于版权
限制,不能直接申请为微信红包封面
。所以就画出来看看吧。
此处顺便
@优弧
赶紧把微信红包封面提上日程
先来看一眼新年礼盒上的logo吧
准备工作
由于掘金直接提供了代码编辑器码上掘金
,所以就不用自己去新建项目之类的操作了,直接在码上掘金上完成这个项目吧。
先来一个canvas
标签
<canvas id="canvas-red-packet"></canvas>
同时在js里面获取到canvas的ID,并设置canvas的宽高
var canvas = document.getElementById("canvas-red-packet");
var ctx = canvas.getContext('2d');
canvas.width = 957;
canvas.height = 1278;
由于是canvas
画的,所以基本上没有样式,全部在JS里面完成。
开始画兔耳朵
左耳
ctx.beginPath();
ctx.moveTo(250, 400);
ctx.arcTo(180, 300, 250, 200, 20);
ctx.lineTo(250, 200);
ctx.stroke();
- beginPath:新路径开始绘画
- moveTo:确定第一个绘画点(X、Y)
- arcTo:给路径添加圆弧(x1、y1、x2、y2、r)
- lineTo:确定最后一个点并绘制直线
- stroke:对路径进行描边
这里需要注意一点的就是最后这条斜着的直线,我在画出来的时候还在草稿纸上一直在确定坐标点。
ctx.beginPath();
ctx.moveTo(250, 200);
ctx.arcTo(270, 180, 280, 200, 20);
ctx.lineTo(320, 400);
ctx.stroke();
- 这里的第一个绘画点就是上一条线的结束点
- 其他点点坐标的确定都是通过上一条结束点去计算出来的
ctx.lineWidth = 10
- 为了让线条更加接近,可以在绘画路径前给一个线条宽度值
右耳
右侧的线条和左侧的线条坐标大致上差不多,只是方向不一致而已,那么计算的时候,根据X、Y坐标来看的话,左侧是加法计算,右侧是减法计算
ctx.beginPath();
ctx.moveTo(440, 400);
ctx.arcTo(510, 300, 440, 200, 20);
ctx.lineTo(440, 200);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(440, 200);
ctx.arcTo(420, 180, 300, 440, 20);
ctx.lineTo(370, 400);
ctx.stroke();
红色区域
用肉眼看到的红色区域其实像是一个鸡蛋的形状,上窄下宽的,所以我们不能使用画圆的方式去画这个区域。
我在canvas文档中尝试了很多种方法,最终确定了使用贝塞尔曲线
来绘制两条线并拼接在一起。
// 上半部分圆
ctx.beginPath();
ctx.moveTo(150, 450);
ctx.bezierCurveTo(270, 250, 400, 250, 520, 450);
ctx.strokeStyle = '#f3411b';
ctx.stroke();
// 下半部分圆
ctx.beginPath();
ctx.moveTo(150, 450);
ctx.bezierCurveTo(-30, 800, 700, 800, 520, 450);
ctx.strokeStyle = '#f3411b';
ctx.stroke();
- strokeStyle:设置线条颜色,默认是黑色的
给贝塞尔曲线
填充颜色的时候,也是找了几种方式,差点就拆分成多个canvas
标签来做了。
ctx.fillStyle = 'red';
ctx.fill();
- fillStyle:设置填充颜色
- fill:根据路径填充
填充的时候,也是分为上下部分的,和线条填充是一样的写法哦!!!
层级修改
- 由于我们现在看到的是红色区域盖住了耳朵区域,所以我们要把耳朵的代码移动到红色区域下方
- 并且设置线条填充色为黑色
ctx.strokeStyle = '#000';
- 这个代码只需要和设置线条宽度的代码写在一起就行了,不需要每条线都写一遍的。
文字和椭圆
ctx.font = 'normal 500 100px sans-serif';
ctx.fillStyle = '#000'
ctx.fillText('{WARM}兔', 70, 720);
ctx.font = 'normal 400 100px sans-serif';
ctx.fillStyle = '#000'
ctx.fillText('YOU', 200, 820);
ctx.lineWidth = 3
ctx.beginPath();
ctx.ellipse(310, 800, 120, 40, Math.PI / 1, 0, 2 * Math.PI);
ctx.stroke();
- 字体是随意给的,和图上肯定是不一样的。
三角
红色区域的三角形属实是没有循环画出来,有知道怎么画的可以一起研究一下!!!
总结
这是花了两天左右时间画出来的,本来想好好画,但是由于利用上班时间,没有太多的精力了,只是用于研究一下canvas里面的几个属性。