嗯……本来还想截图眨眼睛的小丸子,可是眨眼快……难截图,就不截了,
html代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>水汪汪的小丸子</title>
<style>
*{
margin: 0;
padding: 0;
}
#canvas {
background-color: #fff;
display: block;
position: absolute;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="700"></canvas>
<script>
window.onload = function () {
let X1 = 165,Y1 = 172;
let X2 = 250,Y2 = 172;
let X3 = 250,Y3 = 400;
let X4 = 350,Y4 = 400;
let R_box=30;//眼圈半径
let R_box1=30;
let ball_route=10;//大圆半径
let r_b=20;
let r_a=20;//小圆半径
let r_b1=20;
let r_a1=20;//小圆半径
// time=0;//循环的次数
let TIMEOUT_OF_STOP_MOVE = 3000;
let cxt = document.getElementById('canvas').getContext('2d');
let offsetLeft = canvas.offsetLeft;
let offsetTop = canvas.offsetTop;
//声明左眼夹角a1、右眼夹角a2
let angle,angle1;//夹角
let angle3,angle4;//夹角
let flag = true;//眨眼判断
let flag1=true;
nochange(cxt);
cxt.fillStyle='#fff';
route(cxt,X1,Y1,R_box,R_box);
cxt.fill();
route(cxt,X2,Y2,R_box,R_box);
cxt.fill();
cxt.fillStyle='#000';
route(cxt,X1,Y1,r_a,r_b);//眼圈
cxt.fill();
route(cxt,X2,Y2,r_a,r_b);
cxt.fill();
cxt.fillStyle="white";
route(cxt,X1+10,Y1-10,4,4);//眼圈
cxt.fill();
route(cxt,X2+10,Y2-10,4,4);
cxt.fill();
useEyeblink(cxt,R_box,r_a,r_b,flag,flag1,X1,Y1,X2,Y2);
document.onmousemove = function(e){
e = e || event;
//获取鼠标坐标
let x = e.clientX;
let y = e.clientY;
let x1j=x-X1-offsetLeft;
let y1j=y-Y1-offsetTop;
let x2j=x-X2-offsetLeft;
let y2j=y-Y2-offsetTop;
//更新夹角a1、a2
angle = Math.atan2(x1j,y1j);
angle1 = Math.atan2(x2j,y2j);
cxt.clearRect(0,0,1024,768);
nochange(cxt);
cxt.fillStyle='#fff';
route(cxt,X1,Y1,R_box,R_box);
cxt.fill();
route(cxt,X2,Y2,R_box,R_box);
cxt.fill();
arcRoute(cxt,X1,Y1,ball_route,angle,r_a,true);
arcRoute(cxt,X2,Y2,ball_route,angle1,r_a,true);
// 获取系统时间,亦为目标最新鼠标移动事件触发时间
let now = new Date();
// this.lastMove == null
// 表示鼠标移动开始
// now - this.lastMove < TIMEOUT_OF_STOP_MOVE
// 表示距离上次触发鼠标移动事件不超过TIMEOUT_OF_STOP_MOVE毫秒
if(this.lastMove == null || (now - this.lastMove < TIMEOUT_OF_STOP_MOVE)){
// 更新最后移动时间
this.lastMove = now;
// 终止鼠标停止事件处理
clearInterval(this.timer);
// 重新绑定鼠标停止事件处理
this.timer = setInterval(function(){
cxt.clearRect(0,0,1024,768);
nochange(cxt);
cxt.fillStyle='#fff';
route(cxt,X1,Y1,R_box,R_box);
cxt.fill();
route(cxt,X2,Y2,R_box,R_box);
cxt.fill();
cxt.fillStyle='#000';
route(cxt,X1,Y1,r_a,r_b);
cxt.fill();
route(cxt,X2,Y2,r_a,r_b);
cxt.fill();
cxt.fillStyle="white";
route(cxt,X1+10,Y1-10,4,4);//眼圈
cxt.fill();
route(cxt,X2+10,Y2-10,4,4);
cxt.fill();
//centercircle(cxt);
useEyeblink(cxt,R_box,r_a,r_b,flag,flag1,X1,Y1,X2,Y2);
this.lastMove = null;
}, TIMEOUT_OF_STOP_MOVE);
}
}
};
function nochange(cxt) {
cxt.fillStyle = '#000000';
cxt.beginPath();
cxt.moveTo(51,196);
cxt.lineTo(5,196);
cxt.stroke();
cxt.beginPath();
cxt.moveTo(389,196);
cxt.lineTo(435,196);
cxt.moveTo(5,196);
cxt.bezierCurveTo(55,-55,385,-55,435,196);
cxt.stroke();
cxt.fill();
/* /!* 头部*!/*/
cxt.fillStyle = '#fffed7';
//let step = 1 / 200 ;
cxt.beginPath();
cxt.lineWidth = 2;//线宽度为1
cxt.strokeStyle = '#000';//笔触的颜色
cxt.moveTo(45,150);
cxt.bezierCurveTo(45,350,395,350,395,150);
cxt.stroke();
cxt.fill();
/* /!*刘海*!/*/
cxt.fillStyle = '#fffed7';
cxt.beginPath();
// cxt.fillStyle = '#fff';
cxt.moveTo(45,151);//将路径移到点(110,110),不创建线条
//cxt.quadraticCurveTo(-10, 200, 120, 315);//创建二次贝塞尔曲线,控制点(-10,200),结束点(120,315)
cxt.lineTo(70,151);//添加一个新点,然后在画布中创建从(110,110)到(280,315)的线条
// cxt.quadraticCurveTo(410, 210, 290, 110);
cxt.lineTo(82,120);
cxt.lineTo(110,138);
cxt.lineTo(120,100);
cxt.lineTo(161,120);
cxt.lineTo(188,88);
cxt.lineTo(215,125);
cxt.lineTo(262,99);
cxt.lineTo(272,124);
cxt.lineTo(306,109);
cxt.lineTo(319,137);
cxt.lineTo(353,124);
cxt.lineTo(363,151);
cxt.lineTo(395,151);
cxt.stroke();
cxt.fill();
/*耳朵*/
cxt.fillStyle = '#fffed7';
cxt.beginPath();
cxt.moveTo(45,173);
cxt.bezierCurveTo(30,173,43,196,50,196);
cxt.stroke();
//cxt.beginPath();
cxt.moveTo(395,173);
cxt.bezierCurveTo(412,173,399,196,390,196);
cxt.stroke();
cxt.fill();
/*嘴*/
cxt.fillStyle = '#ff0021';
cxt.beginPath();
cxt.moveTo(170, 234);
//cxt.quadraticCurveTo(207.5, 290, 245, 234);
cxt.bezierCurveTo(170,270,245,270,245,234);
cxt.moveTo(170, 234);
cxt.lineTo(245,234);
cxt.stroke();
cxt.fill();
/*上衣*/
cxt.beginPath();
cxt.lineWidth = 3;//线宽度为1
cxt.strokeStyle = '#000';
cxt.fillStyle = '#ff98d8';
// cxt.fillStyle = '#fff';
cxt.moveTo(207,301);//将路径移到点(110,110),不创建线条
//cxt.quadraticCurveTo(-10, 200, 120, 315);//创建二次贝塞尔曲线,控制点(-10,200),结束点(120,315)
cxt.lineTo(207,305);//添加一个新点,然后在画布中创建从(110,110)到(280,315)的线条
cxt.arc(211, 305, 4, 0, 1 * Math.PI);
cxt.moveTo(215,305);
cxt.lineTo(215,301);
cxt.moveTo(207,305);
cxt.lineTo(54,292);
cxt.lineTo(54,308);
cxt.lineTo(170,325);
cxt.moveTo(170,325);
cxt.quadraticCurveTo(165,358,173,394);
cxt.lineTo(260,394);
cxt.moveTo(260,394);
cxt.quadraticCurveTo(268,360,260,325);
cxt.lineTo(387,308);
cxt.lineTo(388,291);
cxt.lineTo(215,305);
cxt.stroke();
cxt.fill();
/*手*/
cxt.beginPath();
cxt.lineWidth = 3;//线宽度为1
cxt.strokeStyle = '#000';
cxt.fillStyle = '#fffed7';
cxt.arc(43, 298, 10, 0, 2 * Math.PI);
cxt.arc(400, 298, 10, 0, 2 * Math.PI);
cxt.stroke();
cxt.fill();
/*裙子*/
cxt.beginPath();
cxt.lineWidth = 3;//线宽度为1
cxt.strokeStyle = '#000';
cxt.fillStyle = '#fffb70';
cxt.moveTo(173,396);
cxt.lineTo(132,434);
cxt.lineTo(296,434);
cxt.lineTo(260,396);
cxt.stroke();
cxt.fill();
/*腿*/
cxt.beginPath();
cxt.lineWidth = 2;//线宽度为1
cxt.strokeStyle = '#000';
cxt.fillStyle = '#fffed7';
cxt.moveTo(202,436);
cxt.lineTo(202,486);
cxt.lineTo(180,494);
cxt.lineTo(212,489);
cxt.lineTo(212,436);
cxt.moveTo(235,436);
cxt.lineTo(235,486);
cxt.lineTo(254,494);
cxt.lineTo(225,489);
cxt.lineTo(225,436);
cxt.stroke();
cxt.fill();
}
//显示坐标
function useEyeblink(cxt,R_box,ball_route,r_b,flag,flag1,X1,Y1,X2,Y2) {
//let h=false;
let h=setTimeout(function () {
eyeblink(cxt,R_box,ball_route,r_b,flag,flag1,X1,Y1,X2,Y2);
clearInterval(h);
},5000);
}
function eyeblink(cxt,R_box,ball_route,r_b,flag,flag1,X1,Y1,X2,Y2) {
//let a=false;
let i=0;
let a=setInterval(function () {
cxt.clearRect(0,0,1024,768);
if(flag1){
if(flag){
r_b-=1;
if(r_b<=0){
flag=false;
}
}
else{
r_b+=1;
if(r_b>=20){
flag=true;
}
}
}
else{
r_b=20;
}
nochange(cxt);
cxt.fillStyle='#fff';
route(cxt,X1,Y1,R_box,R_box);
cxt.fill();
route(cxt,X2,Y2,R_box,R_box);
cxt.fill();
cxt.fillStyle='#000';
route(cxt,X1,Y1,ball_route,r_b);
cxt.fill();
route(cxt,X2,Y2,ball_route,r_b);
cxt.fill();
cxt.beginPath();
cxt.strokeStyle = '#ffffff';
cxt.fillStyle="white";
route(cxt,X1+10,Y1-10,4,4);//眼圈
cxt.fill();
cxt.stroke();
route(cxt,X2+10,Y2-10,4,4);
cxt.stroke();
cxt.fill();
i++;
if(i===40){
//flag1=false;
clearInterval(a);
}
},0);
}
function route(context,x,y,a,b){
let step = 1 / 20 ;
context.beginPath();
context.moveTo(x + a, y); //从椭圆的右端点开始绘制
for (let i = 0; i < 2 * Math.PI; i += step)
{
context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
}
context.closePath();
context.stroke();
}
//椭圆上小球运动的实现
function arcRoute(context,x,y,a,angle,b){
// centercircle(context);
//let step = 1 / 200 ;
context.fillStyle='#000';
/* if(time==0){
context.beginPath();
context.arc(x,y,R_box,0,2*Math.PI,true);
context.closePath();
context.fill();
}else{*/
context.beginPath();
context.arc(x+a*Math.sin(angle),y+a*Math.cos(angle),b,0,2*Math.PI,true);
context.closePath();
context.fill();
context.fillStyle="white";
route(context,x+a*Math.sin(angle)+5,y+a*Math.cos(angle)-10,4,4);//眼圈
context.fill();
route(context,x+a*Math.sin(angle)+5,y+a*Math.cos(angle)-10,4,4);
context.fill();
}
</script>
</body>
</html>
代码上大多都有解释,而且都是知识都是属于canvas基础范围内哦,就不浪费口舌啦,不过眨眼睛那块可能有一丢丢难,如果需要的话可以留言,可以帮的话我尽量帮哦,不过相信聪明的你们肯定一看就会啦是吧哈哈哈