目录
成果展示设计规划代码展示知识点介绍总结与反思
成果展示
设计规划
不太擅长原创自画像,于是尝试了一下先在Ai软件里手绘。(如果是男生,可能还会好看一点) 基本上就是通过曲线、圆弧、椭圆圆弧来构成,再搭配一下色彩。最好再加一点交互互动?那么咱们开始吧!
代码展示
<canvas id=
"face" width=
"1600" height=
"800">不支持Canvas!</canvas>
<script type=
"text/javascript">
var canvas = document.
getElementById("face");
var c1 = canvas.
getContext("2d");
</script>
//背景
function background()
{
c1.fillStyle =
'#a1afc9';
c1.
fillRect(0,0,1600,800
);
}
//脸和头发
function faceandhairs()
{
//底色
//大面积头发
c1.lineWidth =
"10";
c1.fillStyle =
'#ffa07a';//填充
c1.strokeStyle=
"#dc143c";//边
c1.
beginPath();
c1.
ellipse(700,300,300,200,0,0,Math.PI*2
);
c1.
fill();
c1.
stroke();
//头发凸出来的左边
c1.lineWidth =
"10";
c1.fillStyle =
'#ffa07a';//填充
c1.strokeStyle=
"#dc143c";//边
c1.
beginPath();
c1.
ellipse(550,200,200,100,Math.PI*1.75,0,Math.PI*2
);
c1.
fill();
c1.
stroke();
//头发凸出来的右边
//省略
//遮盖物
c1.lineWidth =
"10";
c1.fillStyle =
'#ffa07a';
c1.
beginPath();
c1.
ellipse(700,160,200,100,0,0,Math.PI*2
);
c1.
ellipse(700,352,285,30,0,0,Math.PI*2
);
c1.
fill();
//白白的脸、眼睛、腮红、眉毛、鼻子、嘴巴
//省略
}
//蝴蝶结
function butterfly()
{
c1.lineWidth =
"30";//直线
c1.fillStyle =
'#ffa07a';//填充
c1.strokeStyle=
"#ffa07a";
c1.
beginPath();
c1.
moveTo(50,70
);
c1.
lineTo(200,150
);
c1.
lineTo(200,70
);
c1.
lineTo(50,150
);
c1.
lineTo(50,70
);
c1.
lineTo(125,110
);
c1.
fill();
c1.
stroke();
c1.lineWidth =
"6";//直线
c1.strokeStyle=
"#ffffff";
c1.
beginPath();
c1.
moveTo(75,100
);
c1.
lineTo(125,110
);
c1.
lineTo(75,120
);
c1.
moveTo(175,100
);
c1.
lineTo(125,110
);
c1.
lineTo(175,120
);
c1.
stroke();
c1.lineWidth =
"30";//直线
c1.strokeStyle=
"#ffffff";
c1.
beginPath();
c1.
moveTo(125,90
);
c1.
lineTo(125,130
);
c1.
stroke();
}
//铺就蝴蝶结
function manybutterfly()
{
for(var i=0
;i<1500
;i+=300)
{
for(var j=0
;j<800
;j+=160)
{
c1.
translate(i,j
);
butterfly();
c1.
translate(-i,-j
);
}
}
}
//调用
background();
manybutterfly();
faceandhairs();
//手势
function hand()
{
//食指
c1.lineWidth =
"6";
c1.fillStyle =
'#ffffff';//填充
c1.strokeStyle=
"#cb3a56";//边
c1.
beginPath();
c1.
moveTo(70,128
);
c1.
lineTo(52,55
);
c1.
ellipse(70,50,20,20,0,Math.PI*0.85,0
);
c1.
moveTo(90,50
);
c1.
lineTo(110,200
);
c1.
fill();
c1.
stroke();
//大拇指
c1.lineWidth =
"6";
c1.fillStyle =
'#ffffff';//填充
c1.strokeStyle=
"#cb3a56";//边
c1.
beginPath();
c1.
ellipse(100,150,30,20,0,0,Math.PI*2
);
c1.
fill();
c1.
stroke();
//中指无名指、小拇指
//省略
}
//鼠标决定手势的位置
window.οnlοad=function(){
document.οnmοusedοwn=function(ev){
var oEvent=ev||event
;
c1.
translate(oEvent.clientX-100,oEvent.clientY-100
);
//c1.
save();
hand();
c1.
translate(-oEvent.clientX+100,-oEvent.clientY+100
);
//c1.
translate(0,0
);
//c1.
restore();
}
}
知识点介绍
背景 本来是把底色,也就是背景,和“脸和头发”放在一个方法里的。后来决定要加个蝴蝶结背景,于是就把背景单独拎出来了。头发和脸 其实头发和脸算坐标真的算是很方便简单了!有的小伙伴计算圆弧的位置和角度算了很久,我就比较方便了,我直接用了含有描边的椭圆来描绘头发的形状,然后把多出来的没用的描边覆盖掉了。(嘘,看不出来的小把戏)
ellipse()画椭圆弧函数 功能: 函数ellipse()使用当前绘图色画一椭圆弧。 用法: 该函数调用方式为void ellipse(int x,int y,int startangle,int endangle, int xradius,int yradius); 说明: 参数x,y为椭圆中心坐标,startangle和endangle为给定的起始角和终止角,xradius与yradius为椭圆的x轴半径与y轴半径,如果startangle为0 ,endangle等于360度,那么画出的是个完整的椭圆。
注意:如果不重新写beginPath,线条就会连起来,一笔画到底。不过,在需要线条连接,或者一笔画更方便的时候,就可以省略beginPath了。
蝴蝶结 绘制蝴蝶结的代码这里就不赘述了,无非是线宽的调整、moveto和lineto的使用、填充描边的技巧。
好多好多蝴蝶结 本来打算直接算坐标,画几个蝴蝶结的,后来觉得太麻烦了吧!还是批量生成吧。 先画好一个蝴蝶结,装进一个function里,然后调用。这里是顺序排版,所以可以用简单的for循环来安排。 几个注意点: ①想要排版好看,i的循环间隔是300,而j的循环间隔是160。 ②一开始不知道怎么变换蝴蝶结的位置,毕竟刚刚已经一冲动 写好了坐标,算好了位置。好吧,那就按照定好的数值吧!只要改变坐标原点,不就是改变图像位置了吗?于是查资料,果然有改变坐标原点的方法,translate!! ③先通过translate把坐标原点移动到想要绘制的地方,然后绘制。可是如果继续在这个基础上定义新的坐标原点,那么最新的坐标原点的基准就是刚刚定义的坐标原点,这样偏移的位置就会越来越大,而且无法控制。 所以应该设置translate(0,0)吗?不对,这样是不正确的。设置translate(0,0)就等于没有变化呀! 由于我们的for循环中i和j的变化间隔是固定的,所以我们需要的坐标原点必须是最最最初的原点,也就是左上角那个点。应该是translate(-i,-j)。
调用function 注意顺序就可了!
鼠标点击出现“爱你”手势 码绘就不多说了,慢慢算坐标吧!技巧?多算算就知道了。主要还是介绍“鼠标点击位置出现图案”的方法吧。
//样例示范
window.οnlοad=function(){
document.οnmοusedοwn=function(ev){
var oEvent=ev||event
;
var oDiv=document.
createElement('div');
oDiv.style.left=oEvent.clientX+
'px'; // 指定创建的DIV在文档中距离左侧的位置
oDiv.style.top=oEvent.clientY+
'px'; // 指定创建的DIV在文档中距离顶部的位置
oDiv.style.border=
'1px solid #cb3a56'; // 设置边框
oDiv.style.position=
'absolute'; // 为新创建的DIV指定绝对定位
oDiv.style.width=
'200px'; // 指定宽度
oDiv.style.height=
'200px'; // 指定高度
document.body.
appendChild(oDiv
);
}
一开始使用的是如上的方法,这个方法是简单地画默认形状的,比如矩形圆形,对于自定义的function没有作用。 灵机一动,刚刚改变坐标原点绘图的方式不是很好吗?既然手势的绘图坐标都已经固定了数值,那么很显然,改变坐标原点仍然是个不错的方法。至于交互互动、指定位置,只要获取鼠标位置就可以了呀。 正确方法如下:
window.οnlοad=function(){
document.οnmοusedοwn=function(ev){
var oEvent=ev||event
;
c1.
translate(oEvent.clientX-100,oEvent.clientY-100
);
//c1.
save();
hand();
c1.
translate(-oEvent.clientX+100,-oEvent.clientY+100
);
//c1.
translate(0,0
);
//c1.
restore();
}
}
总结与反思
这次的绘图,简直是“一个c1走天下”。其实也无伤大雅,但是没有弄清楚canvas的作用和方法是真的。一直没有使用processing或者p5,感觉函数、方法的使用都差不多,但是习惯了html5的界面。下次试试p5吧。