引言:2022年是世界杯赛事年,世界杯是一项非常受全世界欢迎的大赛事,一到世界杯赛事期间,各大平台热搜就一直是世界杯相关的话题,在这期间,即使你不了解足球,也能耳濡目染,因为身边到处都充斥着世界杯元素,各种广告、话题都会围绕着你。对于那些热爱足球的人士来说,肯定想方设法地参加到各种世界杯相关活动中,能让自己更深地融入到世界杯中,虽然不能现场观看或者成为比赛的运动员,但是这样能让他们觉得与世界杯的距离更近了。那么,我们程序员能够做些什么,来拉近与世界杯的距离呢?嘻嘻~~,我的话,则是用代码绘制世界杯元素,来更加融入到世界杯赛事中。

1.构思阶段

  • 思考想要绘制什么样的图案?
  • 图案能不能表达出世界杯相关信息?
  • 图案是不是过于复杂,难以通过技术实现?
  • 构思出简易图案:FIFA 国际球联旗帜,加上足球元素

2. 作出设计图

  • 旗帜很容易绘制,用蓝色矩形代替,在旗帜中间再加上 FIFA 文案即可。
  • 难点在于足球绘制(亦可用足球图标代替,但本人想要有一点点的挑战性,就自己绘制实现),需要先作出足球的设计图,否则大脑很难边写代码边联想出对应图形的绘制数据。
  • 草图如下:(不是精确地设计足球,有个大致样子即可)
    在这里插入图片描述

3.技术实现
由于本人从事的是前端开发,所以这里就通过使用 javascript + canvas 技术来实现图形绘制。

  • 步骤1:创建画布
var canvas = document.createElement('canvas')
canvas.id = "myCanvas"
canvas.width = 480
canvas.height = 250
canvas.style.border = "1px solid #d3d3d3"
document.body.style.textAlign = "center"
document.body.appendChild(canvas)

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
  • 步骤2:绘制旗帜背景
// 绘制渐变矩形(作为旗帜轮廓)
var grd=ctx.createLinearGradient(0,0,800,0);
grd.addColorStop(0,"#438fff");
grd.addColorStop(1,"white");
ctx.fillStyle=grd;
ctx.fillRect(0,0,480,250);

在这里插入图片描述

  • 步骤3:绘制足球轮廓
// 球形
ctx.beginPath();
ctx.arc(40,40,40,0,2*Math.PI);
ctx.fillStyle="white"; // 用白色填充球形
ctx.fill()
ctx.stroke();

在这里插入图片描述

  • 步骤4:绘制足球内部图案
// 绘制球形中间的大五边型
ctx.beginPath();
ctx.moveTo(40,20); // 起点
ctx.lineTo(20,40);
ctx.lineTo(30,60);
ctx.lineTo(50,60);
ctx.lineTo(60,40);
ctx.closePath();  // 回到起点
ctx.fillStyle = "black";  //颜色
ctx.fill(); //用黑色填充当前绘图(路径)
ctx.stroke(); //绘制已定义的路径

// 分别绘制和中间大五边形连接的五个小三角及连接线,填充颜色为黑色
ctx.moveTo(20,40)
ctx.lineTo(8,35)
ctx.stroke()
ctx.beginPath();
ctx.moveTo(4,24)
ctx.lineTo(8,35)
ctx.lineTo(0,40)
ctx.closePath();
ctx.fillStyle = "black";
ctx.fill();
ctx.stroke()
	
ctx.moveTo(40,20)
ctx.lineTo(40,8)
ctx.stroke()
ctx.beginPath();
ctx.moveTo(48,1)
ctx.lineTo(40,8)
ctx.lineTo(32,1)
ctx.closePath();
ctx.fillStyle = "black";
ctx.fill();
ctx.stroke()
	
ctx.moveTo(60,40)
ctx.lineTo(72,35)
ctx.stroke()
ctx.beginPath();
ctx.moveTo(80,40)
ctx.lineTo(72,35)
ctx.lineTo(76,24)
ctx.closePath();
ctx.fillStyle = "black";
ctx.fill();
ctx.stroke()
	
ctx.moveTo(50,60)
ctx.lineTo(58,68)
ctx.stroke()
ctx.beginPath();
ctx.moveTo(54,78)
ctx.lineTo(58,68)
ctx.lineTo(68,68)
ctx.closePath();
ctx.fillStyle = "black";
ctx.fill();
ctx.stroke()
	
ctx.moveTo(30,60)
ctx.lineTo(22,68)
ctx.stroke()
ctx.beginPath();
ctx.moveTo(12,68)
ctx.lineTo(22,68)
ctx.lineTo(28,78)
ctx.closePath();
ctx.fillStyle = "black";
ctx.fill();
ctx.stroke()

在这里插入图片描述

  • 步骤5:绘制旗帜文案
// 绘制文本
var text="FIFA"
ctx.font="80px Arial";
var txtWidth=ctx.measureText(text).width
var x = ~~(c.width-txtWidth)/2-40
ctx.fillStyle="white"
for(let i=0;i<text.length;i++){
	ctx.fillText(text[i],x+60*i,150);
}

在这里插入图片描述

完整代码(足球元素有缩小和移动处理):

// 向当前页面中添加画布元素
var canvas = document.createElement('canvas')
canvas.id = "myCanvas"
canvas.width = 480
canvas.height = 250
canvas.style.border = "1px solid #d3d3d3"
document.body.style.textAlign = "center"
document.body.appendChild(canvas)

// 获取画布 DOM 元素,对画布操作
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
// 保存初始绘图状态设置,将保存的设置压入栈中,可通过 restore() 弹出
ctx.save()

// 绘制渐变矩形(作为旗帜轮廓)
var grd=ctx.createLinearGradient(0,0,800,0);
grd.addColorStop(0,"#438fff");
grd.addColorStop(1,"white");
ctx.fillStyle=grd;
ctx.fillRect(0,0,480,250);

// 绘图状态设置为画布从(10,10)开始绘制,并且作绘图缩小处理
// 注:这里设置后会对以下所有绘图内容产生影响
ctx.translate(10,10);
ctx.scale(0.6,0.6)
	
// 球形
ctx.beginPath();
ctx.arc(40,40,40,0,2*Math.PI);
ctx.fillStyle="white"; // 用白色填充球形
ctx.fill()
ctx.stroke();

// 绘制球形中间的大五边型
ctx.beginPath();
ctx.moveTo(40,20); // 起点
ctx.lineTo(20,40);
ctx.lineTo(30,60);
ctx.lineTo(50,60);
ctx.lineTo(60,40);
ctx.closePath();  // 回到起点
ctx.fillStyle = "black";  //颜色
ctx.fill(); //用黑色填充当前绘图(路径)
ctx.stroke(); //绘制已定义的路径

// 分别绘制和中间大五边形连接的五个小三角及连接线,填充颜色为黑色
// 注:这里做了代码优化处理
const pointList = [
  [
    { x: 20, y: 40 },
    { x: 8, y: 35 },
    { x: 4, y: 24 },
    { x: 8, y: 35 },
    { x: 0, y: 40 },
  ],
  [
    { x: 40, y: 20 },
    { x: 40, y: 8 },
    { x: 48, y: 1 },
    { x: 40, y: 8 },
    { x: 32, y: 1 },
  ],
  [
    { x: 60, y: 40 },
    { x: 72, y: 35 },
    { x: 80, y: 40 },
    { x: 72, y: 35 },
    { x: 76, y: 24 },
  ],
  [
    { x: 50, y: 60 },
    { x: 58, y: 68 },
    { x: 54, y: 78 },
    { x: 58, y: 68 },
    { x: 68, y: 68 },
  ],
  [
    { x: 30, y: 60 },
    { x: 22, y: 68 },
    { x: 12, y: 68 },
    { x: 22, y: 68 },
    { x: 28, y: 78 },
  ],
]
for(let i = 0; i < pointList.length; i++) {
	ctx.moveTo(pointList[i][0].x,pointList[i][0].y)
	ctx.lineTo(pointList[i][1].x,pointList[i][1].y)
	ctx.stroke()
	ctx.beginPath();
	ctx.moveTo(pointList[i][2].x,pointList[i][2].y)
	ctx.lineTo(pointList[i][3].x,pointList[i][3].y)
	ctx.lineTo(pointList[i][4].x,pointList[i][4].y)
	ctx.closePath();
	ctx.fillStyle = "black";
	ctx.fill();
	ctx.stroke()
}

// 弹出初始绘图状态设置(这里文本不做缩小处理)
ctx.restore()
// 绘制文本
var text="FIFA"
ctx.font="80px Arial";
var txtWidth=ctx.measureText(text).width
var x = ~~(c.width-txtWidth)/2-40
ctx.fillStyle="white"
for(let i=0;i<text.length;i++){
	ctx.fillText(text[i],x+60*i,150);
}
// 将画布内容转成 base64 格式图片
var imgUrl = c.toDataURL('image/png');

// 将绘制的内容呈现到当前页面
document.body.innerHTML = `<img src=${imgUrl}>`![在这里插入图片描述](https://img-blog.csdnimg.cn/5f0d03a76e954e5daf34d082173de0c5.gif)

最终效果图:
在这里插入图片描述

4.代码使用方式

  • 拷贝完整代码
  • 打开任意浏览器(注:不要使用太旧的浏览器,推荐谷歌浏览器
  • 在任意标签页面下,按下 F12 键打开浏览器控制台,在控制台粘贴代码,然后按下回车键(Enter)
  • 代码将会清空当前页面内容,在当前页面绘制图案
    可见下图动图展示过程:
    在这里插入图片描述
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐