成品图:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
canvas{
border: 1px solid #ccc;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
</style>
</head>
<body>
<canvas width="600" height="600"></canvas>
<script>
var canvas=document.querySelector("canvas")
var ctx=canvas.getContext("2d")
//身体底层蓝色
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#04a3e7"
ctx.moveTo(210,320)
ctx.quadraticCurveTo(150, 430, 145, 530);
ctx.quadraticCurveTo(300, 500, 450, 530);
ctx.quadraticCurveTo(450, 430, 385, 320);
ctx.lineTo(385,320)
ctx.closePath()
ctx.fill()
ctx.stroke()
//肚子白
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#fff"
ctx.moveTo(225,320)
ctx.bezierCurveTo(120, 550, 480, 550, 370, 320)
ctx.fill()
ctx.stroke()
//头部底层蓝色
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#04a3e7"
ctx.ellipse(300,200,192,175,0,0,2*Math.PI)
ctx.fill()
ctx.stroke()
//脸白
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#fff"
ctx.ellipse(300,232,162,142.5,0,0,2*Math.PI)
ctx.fill()
ctx.stroke()
//左眼框
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#fff"
ctx.ellipse(264,100,35,50,-Math.PI/180*2,0,2*Math.PI)
ctx.fill()
ctx.stroke()
//左眼
ctx.beginPath()
ctx.fillStyle="#000"
ctx.ellipse(280,110,10,17,0,0,2*Math.PI)
ctx.fill()
//左眼珠
ctx.beginPath()
ctx.fillStyle="#fff"
ctx.ellipse(281,113,3,5,0,0,2*Math.PI)
ctx.fill()
//右眼框
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#fff"
ctx.ellipse(336,100,35,50,Math.PI/180*2,0,2*Math.PI)
ctx.fill()
ctx.stroke()
//右眼
ctx.beginPath()
ctx.fillStyle="#000"
ctx.ellipse(320,110,10,17,0,0,2*Math.PI)
ctx.fill()
//右眼珠
ctx.beginPath()
ctx.fillStyle="#fff"
ctx.ellipse(319,113,3,5,0,0,2*Math.PI)
ctx.fill()
//脸部中线
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.moveTo(300,170)
ctx.lineTo(300,318)
ctx.stroke()
//鼻子
ctx.beginPath()
ctx.lineWidth=2
ctx.strokeStyle="#000"
ctx.fillStyle="#e7040f"
ctx.ellipse(300,150,22,22,0,0,2*Math.PI)
ctx.fill()
ctx.stroke()
//鼻子高光
ctx.beginPath()
ctx.fillStyle="#fff"
ctx.ellipse(293,145,6,6,0,0,2*Math.PI)
ctx.fill()
//嘴
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.moveTo(180,220)
ctx.bezierCurveTo(200, 350, 400, 350, 420, 220)
ctx.stroke()
//胡子
//左1
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#111"
ctx.moveTo(155,140)
ctx.lineTo(255,175)
ctx.stroke()
//左2
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#111"
ctx.moveTo(145,210)
ctx.lineTo(255,210)
ctx.stroke()
//左3
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#111"
ctx.moveTo(155,280)
ctx.lineTo(255,245)
ctx.stroke()
//右1
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#111"
ctx.moveTo(445,140)
ctx.lineTo(345,175)
ctx.stroke()
//右2
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#111"
ctx.moveTo(455,210)
ctx.lineTo(345,210)
ctx.stroke()
//右3
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#111"
ctx.moveTo(445,280)
ctx.lineTo(345,245)
ctx.stroke()
//铜锣烧
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#f0eac7"
ctx.ellipse(300,350,75,55,0,0,2*Math.PI)
ctx.fill()
ctx.stroke()
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.moveTo(225,350)
ctx.bezierCurveTo(250, 405, 350, 405, 375, 350);
ctx.stroke()
ctx.beginPath()
ctx.fillStyle='#a27064'
ctx.moveTo(225,350)
ctx.bezierCurveTo(254, 385, 350, 385, 375, 350);
ctx.bezierCurveTo(365, 278, 235, 278, 225, 350);
ctx.fill()
// 次元口袋
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.moveTo(235,415)
ctx.bezierCurveTo(225, 500, 375, 500, 365, 415)
ctx.closePath()
ctx.stroke()
//左胳膊
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#04a3e7"
ctx.moveTo(190,330)
ctx.bezierCurveTo(100, 380, 160, 445, 210, 375)
ctx.closePath()
ctx.fill()
ctx.stroke()
//左手
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#fff"
ctx.ellipse(215,350,33,33,0,0,2*Math.PI)
ctx.fill()
ctx.stroke()
//右胳膊
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#04a3e7"
ctx.moveTo(410,330)
ctx.bezierCurveTo(500, 380, 440, 445, 390, 375)
ctx.closePath()
ctx.fill()
ctx.stroke()
//右手
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#fff"
ctx.ellipse(385,350,33,33,0,0,2*Math.PI)
ctx.fill()
ctx.stroke()
//左脚
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#fff"
ctx.ellipse(164,475,55,70,0,0,2*Math.PI)
ctx.fill()
ctx.stroke()
//右脚
ctx.beginPath()
ctx.lineWidth=3
ctx.strokeStyle="#000"
ctx.fillStyle="#fff"
ctx.ellipse(434,475,55,70,0,0,2*Math.PI)
ctx.fill()
ctx.stroke()
</script>
</body>
</html>
主要使用的canvas方法:
.beginPath() 一个新的绘制开始
.moveTo(x,y) 从一个点(x,y)开始
.lineTo(x,y) 从上一个点开始到点(x,y)结束,前边可以是点或线
.quadraticCurveTo(x1, y1, x, y) 二次贝塞尔曲线,从上一个点开始到点(x,y)结束,点(x1,y1)为控制点,前边可以是点或线
.bezierCurveTo(x1, y1, x2, y2, x, y) 三次贝塞尔曲线,从上一个点开始到点(x,y)结束,点(x1,y1)(x2,y2)为控制点,前边可以是点或线
.closePath() 结束该次绘制,线封口,即最后一个点连接回第一个点,组成封闭图形
.lineWidth=num 设置边框宽度
.strokeStyle="色值" 设置边框颜色 色值可以写 # red... rgba rgb 形式
以上两个需要配合 .stroke() 使用,绘制边框,如不写 .stroke()则上边两个无效,如果只写 .stroke()
则显示默认样式(黑色 宽度为1)
.fillStyle="色值" 填充颜色 配合 .fill() 使用,绘制边框,如不写 .fill()则上边两个无效,如果只写 .fill() 则显示默认样式 (黑色)
.fillRect(x,y,width,height) 绘制矩形 x,y 左上角坐标点 width 宽度 height 高度
arc(x,y,r,startAngle,endAngle,counterclockwise) 绘制圆 x,y圆心坐标 r 半径 startAngle,endAngle起始角度,结束角度 注意:起始角度0度在右侧 counterclockwise表示绘线方向,true表示逆时针,false表示顺时针 可以不写,默认为顺时针
贝塞尔曲线理解参考:用Javascript+Canvas画N阶贝塞尔曲线 - 知乎