<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/icon-min.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="博客-柒书" />
<title>Canvas 2D-博客-柒书</title>
</head>
<body>
<canvas id="canvasRef" width="280px" height="340px">
该浏览器暂不支持canvas标签
</canvas>
</body>
<script>
// 计算角度
const Deg = (Number) => {
if (typeof Number === "number") {
return (Math.PI / 180) * Number;
}
return Number;
};
const draw = (ctx, x = 0, y = 0) => {
// 脸轮廓
ctx.beginPath();
ctx.fillStyle = "rgb(88,160,232)";
ctx.arc(140 + x, 100 + y, 90, Deg(0), Deg(360), false);
ctx.fill();
ctx.stroke();
// 项圈
ctx.beginPath();
ctx.fillStyle = "rgb(215,42,47)";
ctx.moveTo(82 + x, 170 + y);
ctx.quadraticCurveTo(140 + x, 175 + y, 199 + x, 170 + y);
ctx.quadraticCurveTo(204 + x, 174 + y, 199 + x, 178 + y);
ctx.quadraticCurveTo(140 + x, 183 + y, 82 + x, 178 + y);
ctx.quadraticCurveTo(78 + x, 174 + y, 82 + x, 170 + y);
ctx.fill();
ctx.stroke();
// 身体轮廓
ctx.beginPath();
ctx.fillStyle = "rgb(88,160,232)";
ctx.moveTo(90 + x, 178 + y);
ctx.quadraticCurveTo(65 + x, 155 + y, 40 + x, 140 + y);
ctx.lineTo(20 + x, 160 + y);
ctx.quadraticCurveTo(50 + x, 200 + y, 80 + x, 220 + y);
ctx.quadraticCurveTo(76 + x, 250 + y, 80 + x, 300 + y);
ctx.quadraticCurveTo(105 + x, 304 + y, 130 + x, 300 + y);
ctx.lineTo(133 + x, 285 + y);
ctx.lineTo(150 + x, 275 + y);
ctx.moveTo(133 + x, 285 + y);
ctx.lineTo(135 + x, 300 + y);
ctx.quadraticCurveTo(162 + x, 305 + y, 190 + x, 295 + y);
ctx.quadraticCurveTo(200 + x, 240 + y, 199 + x, 178 + y);
ctx.quadraticCurveTo(140 + x, 183 + y, 90 + x, 178 + y);
ctx.moveTo(199 + x, 178 + y);
ctx.quadraticCurveTo(215 + x, 190 + y, 230 + x, 220 + y);
ctx.lineTo(210 + x, 235 + y);
ctx.quadraticCurveTo(202 + x, 232 + y, 199 + x, 224 + y);
ctx.fill();
ctx.stroke();
// 手
ctx.beginPath();
ctx.fillStyle = "#fff";
ctx.arc(24 + x, 144 + y, 17, Deg(0), Deg(360), true);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(227 + x, 235 + y, 17, Deg(0), Deg(360), true);
ctx.fill();
ctx.stroke();
// 右脚
ctx.beginPath();
ctx.moveTo(135 + x, 300 + y);
ctx.quadraticCurveTo(162 + x, 305 + y, 190 + x, 295 + y);
ctx.bezierCurveTo(205 + x, 295 + y, 205 + x, 308 + y, 200 + x, 313 + y);
ctx.quadraticCurveTo(162 + x, 322 + y, 136 + x, 316 + y);
ctx.fill();
ctx.stroke();
// 左脚
ctx.beginPath();
ctx.moveTo(80 + x, 300 + y);
ctx.quadraticCurveTo(105 + x, 304 + y, 130 + x, 300 + y);
ctx.bezierCurveTo(143 + x, 300 + y, 143 + x, 314 + y, 130 + x, 320 + y);
ctx.quadraticCurveTo(105 + x, 326 + y, 72 + x, 320 + y);
ctx.bezierCurveTo(65 + x, 316 + y, 70 + x, 300 + y, 80 + x, 300 + y);
ctx.fill();
ctx.stroke();
// 尾巴
ctx.beginPath();
ctx.fillStyle = "rgb(215,42,47)";
ctx.arc(62 + x, 268 + y, 10, Deg(0), Deg(360), true);
ctx.moveTo(78 + x, 260 + y);
ctx.lineTo(70 + x, 265 + y);
ctx.fill();
ctx.stroke();
// 腹部
ctx.beginPath();
ctx.fillStyle = "#fff";
ctx.moveTo(115 + x, 180 + y);
ctx.bezierCurveTo(90 + x, 200 + y, 85 + x, 268 + y, 160 + x, 260 + y);
ctx.bezierCurveTo(205 + x, 255 + y, 204 + x, 200 + y, 182 + x, 180 + y);
ctx.quadraticCurveTo(146 + x, 181 + y, 115 + x, 180 + y);
ctx.fill();
ctx.stroke();
// 口袋
ctx.beginPath();
ctx.arc(150 + x, 215 + y, 36, Deg(0), Deg(180), false);
ctx.closePath();
ctx.stroke();
// 铃铛
ctx.beginPath();
ctx.fillStyle = "rgb(245,215,103)";
ctx.arc(160 + x, 188 + y, 11, Deg(0), Deg(360), false);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(147 + x, 188 + y);
ctx.quadraticCurveTo(161 + x, 180 + y, 172 + x, 183 + y);
ctx.quadraticCurveTo(174 + x, 185 + y, 172 + x, 187 + y);
ctx.quadraticCurveTo(161 + x, 185 + y, 147 + x, 192 + y);
ctx.quadraticCurveTo(145 + x, 190 + y, 147 + x, 188 + y);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.arc(162 + x, 192 + y, 2.5, Deg(0), Deg(360), false);
ctx.moveTo(162 + x, 192 + y);
ctx.lineTo(162 + x, 200 + y);
ctx.fill();
ctx.stroke();
// 脸部轮廓
ctx.beginPath();
ctx.fillStyle = "#fff";
ctx.moveTo(90 + x, 170 + y);
ctx.bezierCurveTo(x - 30, y, 334 + x, y - 4, 200 + x, 170 + y);
ctx.quadraticCurveTo(140 + x, 175 + y, 90 + x, 170 + y);
ctx.fill();
ctx.stroke();
// 嘴角
ctx.beginPath();
ctx.moveTo(205 + x, 110 + y);
ctx.quadraticCurveTo(220 + x, 110 + y, 230 + x, 90 + y);
ctx.arc(214 + x, 85 + y, 16, Deg(30), Deg(-160), true);
ctx.fill();
ctx.stroke();
// 嘴
ctx.beginPath();
ctx.fillStyle = "rgb(222,43,42)";
ctx.moveTo(90 + x, 100 + y);
ctx.quadraticCurveTo(140 + x, 110 + y, 205 + x, 110 + y);
ctx.bezierCurveTo(190 + x, 180 + y, 100 + x, 180 + y, 85 + x, 105 + y);
ctx.quadraticCurveTo(82 + x, 98 + y, 90 + x, 100 + y);
ctx.fill();
ctx.stroke();
// 舌头
ctx.beginPath();
ctx.fillStyle = "rgb(229,122,30)";
ctx.moveTo(98 + x, 135 + y);
ctx.bezierCurveTo(118 + x, 105 + y, 170 + x, 120 + y, 173 + x, 155 + y);
ctx.bezierCurveTo(155 + x, 168 + y, 108 + x, 160 + y, 98 + x, 135 + y);
ctx.fill();
ctx.stroke();
// 左眼框
ctx.beginPath();
ctx.fillStyle = "#fff";
ctx.moveTo(116 + x, 46 + y);
ctx.bezierCurveTo(116 + x, 76 + y, 158 + x, 76 + y, 152 + x, 42 + y);
ctx.bezierCurveTo(146 + x, 10 + y, 118 + x, 10 + y, 116 + x, 46 + y);
ctx.fill();
ctx.stroke();
// 右眼框
ctx.beginPath();
ctx.fillStyle = "#fff";
ctx.moveTo(152 + x, 42 + y);
ctx.bezierCurveTo(158 + x, 72 + y, 182 + x, 74 + y, 182 + x, 46 + y);
ctx.bezierCurveTo(172 + x, 10 + y, 147 + x, 10 + y, 152 + x, 42 + y);
ctx.fill();
ctx.stroke();
// 眼睛
ctx.beginPath();
ctx.lineWidth = 3;
ctx.arc(140 + x, 46 + y, 8, Deg(0), Deg(180), true);
ctx.moveTo(174 + x, 46 + y);
ctx.arc(166 + x, 46 + y, 8, Deg(0), Deg(180), true);
ctx.stroke();
// 鼻子
ctx.beginPath();
ctx.lineWidth = 1;
ctx.fillStyle = "rgba(218,42,46)";
ctx.arc(158 + x, 68 + y, 10, Deg(0), Deg(360), true);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = "#fff";
ctx.arc(156 + x, 66 + y, 3, Deg(0), Deg(360), true);
ctx.fill();
// 胡子
ctx.beginPath();
ctx.moveTo(158 + x, 78 + y);
ctx.quadraticCurveTo(160 + x, 93 + y, 160 + x, 108 + y);
ctx.moveTo(182 + x, 76 + y);
ctx.lineTo(220 + x, 50 + y);
ctx.moveTo(184 + x, 86 + y);
ctx.lineTo(232 + x, 82 + y);
ctx.moveTo(182 + x, 96 + y);
ctx.lineTo(226 + x, 105 + y);
ctx.moveTo(129 + x, 78 + y);
ctx.lineTo(75 + x, 58 + y);
ctx.moveTo(127 + x, 88 + y);
ctx.lineTo(65 + x, 85 + y);
ctx.moveTo(129 + x, 98 + y);
ctx.lineTo(75 + x, 115 + y);
ctx.stroke();
};
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
draw(ctx, 0, 0);
</script>
</html>