前言
身为一个程序员竟然沉迷游戏,wtf??? 都怪腾讯前几天出了一款叫做寻仙的手游,作为曾经的资深玩家,小v君犹豫再三还是忍不住入坑了。入坑了怎么不去打游戏,还在这里发文章? 不不不,小v君今天在这里可不是要跟大家讨论游戏,作为一个好好学习,天天向上的有位少年,游戏嘛,只是业余的,码代码才是王道!!!所以小v君今天给大家分享一下怎么使用canvas来绘制一个游戏登录界面的人物属性图!
先上一波图片,怎么样? 人物是不是很帅,很中国风???小v君当年可是花了四年时间来玩这个人物哦。。。
一. 什么是canvas?
canvas 元素用于在网页上绘制图形。html5 的 canvas 元素使用 javascript 在网页上绘制2d图像。 在矩形区域的画布上,控制其每一像素,javascript 来绘制 2d图形,逐像素进行渲染。可以通过多种方法使用canvas 元素绘制路径、矩形、圆形、字符以及添加图像。
注意!!!
canvas 标签本身是不具备绘图功能,只能使用 javascript 在网页上绘制图像哦。
二. 任务分析
为了简洁明了,小v君没有在页面上花什么时间,希望大家不要介意,毕竟js才是今天的主角哦。
首先,我们来简单分析一下。这个人物的属性图是由六个内嵌的正六边形组成的,再由六根线从连接这个正六边形的中心,最后根据人物的属性进行颜色的填充。怎么样?是不是很简单,只要三步就可以绘制出这个游戏人物属性图哦。可能大家会觉得小v君说起来容易,实际又该怎么操作呢?各位看官大爷别着急,小的这就送上代码。
三. 代码部分
var mw = 400, mh = 400, mctx = null, mcount = 6, mcenter = mw/2, mradius = mcenter - 50, mangle = math.pi*2/mcount, mcolorpolygon = '#000000', mdata = [ ['爆发', 100], ['防御', 60], ['治疗', 50], ['控制', 60], ['辅助', 30], ['机动', 70] ], mcolortext = '#000000', canvas = document.createelement('canvas'); document.body.appendchild(canvas); canvas.width = mw; canvas.height = mh; mctx = canvas.getcontext('2d');
首先,我们需要指定一个id属性 (脚本中经常引用), 再使用width 和 height 属性定义的画布的大小.在这里我将画布的宽和高都设置为400,六边形嘛,数量当然是6,图形的中心等于它自身宽度的一半,线条的颜色就使用黑色,在利用一个数组写上自定义的数据就可以开始绘画啦。
细心的朋友可能会问mradius为什么等于mcenter减50呢?在这里,请允许小v君卖个关子,大家看完就自然知道结果啦~~~
绘制六个内嵌的六边形
function drawpolygon(ctx) { ctx.save(); // save the default state ctx.strokestyle = mcolorpolygon; var r = mradius / mcount; for(var i = 0; i < mcount; i ) { ctx.beginpath(); //开始路径 var currr = r * (i 1); for(var j = 0; j < mcount; j ) { var x = mcenter currr*math.cos(mangle*j); var y = mcenter currr*math.sin(mangle*j); ctx.lineto(x, y); } ctx.closepath(); //闭合路径 ctx.stroke() // restore to the default state } ctx.restore(); }
为了代码整体的美观和复用性,我们定一个名为drawpolygon的函数,再使用一个for循环来完成六边形的绘制。看到这里,大家可能会问怎么还使用了sin和cos函数了,想当年学数学那可是一个受罪,怎么现在还要受它的折磨。。。小v君也深表无奈,代码跟数学本来就是一家,代码里面很多地方都要运用math函数,所以在数学这个坑上小v君与大家同在(┬_┬)。(ps:js中需要用到的数学公式很多网上都有,不需要自己手写,只要增加点印象,一个复制就可以拉过来用了,啦啦啦,小v君也很会偷懒的,哈哈哈~~~)
绘制直线
function drawlines(ctx) { ctx.save(); ctx.beginpath(); ctx.strokestyle = mcolorpolygon; for( var i = 0; i< mcount; i ){ var x = mcenter mradius * math.cos(mangle*i); var y = mcenter mradius * math.sin(mangle*i); ctx.moveto(mcenter, mcenter); ctx.lineto(x, y); } ctx.stroke(); ctx.restore(); }
同理,定义一个名为drawlines的函数来实现这部分功能。canvas画线相对来说比较简单,比较难理解的估计还是在这个for循环的函数里面,对于六边形的绘制大家可以参考一下这篇博文 ?
绘制覆盖区域
function drawregion(ctx) { ctx.save(); ctx.beginpath(); for(var i = 0; i< mcount; i ){ var x = mcenter mradius*math.cos(mangle*i)*mdata[i][5]/100; var y = mcenter mradius*math.sin(mangle*i)*mdata[i][6]/100; ctx.lineto(x, y); } ctx.closepath(); ctx.fillstyle = 'rgba(255,0,0,.5)'; ctx.fill(); ctx.store(); }
写到这里,我们的属性图差不多就绘制完成了。但是,图形内的颜色具体是怎么进行填充的呢?在这里我们使用了fill语法进行填充,在代码中只需要使用ctx.fill()就可以实现了。
解释:填充,是将闭合的路径的内容填充具体的颜色,在这里我设置了透明度为0.5的红色,默认颜色黑色。如果所有的描点没有构成封闭结构,也会自动构成一个封闭图形。
绘制文本
function drawtext(ctx) { ctx.save(); var fontsize = mcenter/12; ctx.font = fontsize 'px microsoft yahei'; ctx.fillstyle = mcolortext; for(var i = 0; i< mcount; i ){ var x = mcenter mradius*math.cos(mangle*i); var y = mcenter mradius*math.sin(mangle*i); //通过不同的位置,调整文本的显示位置 if( mangle * i >= 0 && mangle * i <= math.pi / 2 ){ ctx.filltext(mdata[i][0], x, y fontsize); }else if(mangle * i > math.pi / 2 && mangle * i <= math.pi){ ctx.filltext(mdata[i][0], x - ctx.measuretext(mdata[i][0]).width, y fontsize); }else if(mangle * i > math.pi && mangle * i <= math.pi * 3 / 2){ ctx.filltext(mdata[i][0], x - ctx.measuretext(mdata[i][0]).width, y); }else{ ctx.filltext(mdata[i][0], x, y); } } ctx.restore(); }
至此,我们的人物属性图就绘制好了。不知道各位看完之后有没有想明白前面小v君埋下的问题呢?50px,对的,mradius等于mcenter减50中的那50px就是给我们的文本留出来的位置,代码中的if语句就是通过不同的位置来调整文本的显示位置。
四. 小结
综上所述,简单说明了如何使用canvas来绘制一个人物属性图,以上内容属个人理解和网上学习总结,如有错误,欢迎指正共勉。关于canvas这个元素,它应用的领域可是非常的广阔哦。比如在游戏方面,canvas在基于web的图像显示方面比flash更加立体、更加精巧,canvas游戏在流畅度和跨平台方面更牛。在可视化数据方面,百度的echart、d3.js、three.js等等用运用到了canvas。如果你以为canvas的运用只有这些,那就打错特错了,在现在以及未来的智能机时代,html5技术能够在banner广告上发挥巨大作用,而使用canvas来实现动态的广告效果再合适不过。