canvas画出简陋版随鼠标转动眼睛且会眨眼的可爱樱桃小丸子

嗯……本来还想截图眨眼睛的小丸子,可是眨眼快……难截图,就不截了,

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基础范围内哦,就不浪费口舌啦,不过眨眼睛那块可能有一丢丢难,如果需要的话可以留言,可以帮的话我尽量帮哦,不过相信聪明的你们肯定一看就会啦是吧哈哈哈

文件下载传送门

猜你喜欢

转载自blog.csdn.net/weixin_41046961/article/details/81783292