欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

HTML5 新特性之三---canvas绘图 ----- 重点&难点

程序员文章站 2022-05-11 10:00:30
...

目录

使用Canvas绘制--矩形,矩形定位点在自己的左上角

Canvas绘图--文本

Canvas绘图--渐变对象

Canvas绘图--路径

Canvas绘图--图像

Canvas绘图--进行变形操作


网页中的绘图技术

(1)SVG绘图,2D矢量图技术,2000年出现,后纳入H5标准

(2)Canvas绘图,2D位图技术,H5提出绘图技术

(3)WebGL绘图,3D绘图,尚未纳入H5标准

 

canvas: 画布,是H5提供2D绘图技术

<canvas width="500" height="400">
    您的浏览器版本太低,请更新
</canvas>

canvas标签在浏览器中默认300*150的inline-block,

画布的宽度和高智能使用html/js属性来赋值,不能用css样式来赋值

每个画布上有且只有一个“画笔”对角,对对象进行绘图

 

var ctx=canvas.getContext("2d")

 

使用Canvas绘制--矩形,矩形定位点在自己的左上角

ctx.lineWidth = 1; 描边宽度(空心)

ctx.fillStyle = "#000" 填充样式/颜色(实心)

ctx.strokeStyle = "red"; 描边样式(空心)

ctx.fillRect(x,y,w,h) ; 填充一个矩形

ctx.strokeRect(x,y,w,h); 描边一个矩形

ctx.clearRect(x,y,w,h); 清除一个矩形范围内所有绘图

 

Canvas绘图--文本

ctx.textBaseline="top/bottom/alphabetic";

#文本基线:(垂直对齐方式)

ctx.font="12px sans-serif"; #字体大小和字体

ctx.fillText(str,x,y); 填充一段文本

ctx.strokeText(str,x,y) 描边一段文本

ctx.measureText(str) 测量文本宽度,返回对象{width:x}

 

Canvas绘图--渐变对象

线性渐变:linearGradient

径向渐变:radialGradient

(1)创建渐变对象

        var g=ctx.createLinearGradient(x1,y1,x2,y2);

(2)设置颜色点

        g.addColorStop(0,"blue");

        g.addColorStop(0.5,"red");

        g.addColorStop(1,"green");

(3)将渐变对象应用填充或描边样式

         ctx.fillStyle=g;

(4)画矩形画文本

         ctx.fillRect(0,0,500,100);

 

Canvas绘图--路径

ctx.beginPath(); 开始一条新路径

ctx.closePath(); 闭合当前路径

ctx.moveTo(x,y) 移动指定点

ctx.lineTo(x,y) 从当前点到指定点画一条直线

ctx.arc(cx,cy,r,start,end); 绘制拱形路径

ctx.stroke(); 对当前路径描边

ctx.fill(); 对当前路径填充

ctx.clip() 对当前路径裁剪

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body{
            text-align: center;
        }
        canvas{
            background-color: #ddd;
        }
    </style>
</head>
<body>
<canvas id="c2" width="500" height="400">
    您的浏览器版本太低不能显示canvas,请更新
</canvas>

<script>
    //1.获取画布
    //2.依据画布获取画笔
    var c2=document.getElementById("c2");
    var ctx=c2.getContext("2d");
    
    function closeMouth() {
        //1.绘制外围轮廓
        ctx.beginPath();
        ctx.arc(250,200,100,0,2*Math.PI);
        ctx.lineTo(255,200);
        ctx.stroke();
        //2.填充眼球
        ctx.beginPath();
        ctx.arc(250,150,25,0,2*Math.PI);
        ctx.fillStyle="#38f";
        ctx.fill();
        //3.填充眼神光
        ctx.beginPath();
        ctx.arc(263,135,3,0,2*Math.PI);
        ctx.fillStyle="#fff";
        ctx.fill();
    };
    
    function openMouth() {
        ctx.beginPath();
        ctx.arc(250,200,100,30*Math.PI/180,-30*Math.PI/180);
        ctx.lineTo(255,200);
        ctx.closePath()
        ctx.stroke();


        //2.填充眼球
        ctx.beginPath();
        ctx.arc(250,150,25,0,2*Math.PI);
        ctx.fillStyle="#38f";
        ctx.fill();
        //3.填充眼神光
        ctx.beginPath();
        ctx.arc(263,135,3,0,2*Math.PI);
        ctx.fillStyle="#fff";
        ctx.fill();

    }

    // closeMouth()
    // openMouth()
    var idx=0;
    var timer=setInterval(function () {
        ctx.clearRect(0,0,500,400);
        idx++;
        if(idx%2==0){
            openMouth()
        }else{
            closeMouth()
        }
    },500)

</script>

</body>
</html>

 

Canvas绘图--图像

canvas属于客户端技术,图片在服务器上,所有浏览器必须先下载绘制图片,且等待图片加载成功后再绘制图片

var p3 = new lmage();	//1.创建图片对象
p3.src="img/p3.png";	//2.发送请求并且下载图片
p3.οnlοad=function(){	//3.图片下载完成,触发事件 onload
    console.log(p3.width);
    ctx.drawImage(p3,x,y);	 //原始大小绘图
    ctx.drawImage(p3,x,y,w,h);    //拉升绘图
}

Canvas绘图--绘制多张图片

Canvas绘图中若需要多张图片,他们都异步加载,无法预测哪一张先加载完成

AJAX(异步 javascript and xml)

 

Canvas绘图--进行变形操作

Canvas绘图中也变形技术,可以针对一个图像/图形绘制过程进行变形,rotate;translate

ctx.rotate(弧度) 旋转绘图对象,轴点画布原点(0,0)

ctx.translate(x,y) 整个画布的原点平移到指定的点

ctx.save(); 保存画笔所有的变形状态值

ctx.restore()j; 恢复画布变形状态值到最近一次保存

<script>
    //1.获取画布
    //2.依据画布获取画笔
    var c2=document.getElementById("c2");
    var ctx=c2.getContext("2d");

    var p3 = new Image();
    p3.src="img/p4.png";
    p3.onload = function () {
        //2.创建要旋转角度
        var deg1 = 15;
        var deg2 = 30;
        //3.创建定时器
        var timer = setInterval(function () {
            //4.清除画布[?,?]
            ctx.save();          //保存状态
            ctx.clearRect(-250,-200,1000,800);
            //1.平移原点
            ctx.translate(100,150);
            //5.旋转角度
            ctx.rotate(deg1*Math.PI/180);    //角度旋转会保持
            //6.绘图
            ctx.drawImage(p3,-100,-50);
            ctx.restore();      //恢复到上一次保存
            // ctx.rotate(-deg1*Math.PI/180);
            // ctx.translate(-100,-150);
            deg1+=15;

            //1.平移原点
            ctx.save();
            ctx.translate(300,150);
            //5.旋转角度
            ctx.rotate(deg2*Math.PI/180);
            //6.绘图
            ctx.drawImage(p3,-100,-50);
            ctx.restore();
            // ctx.rotate(-deg2*Math.PI/180);
            // ctx.translate(-300,-150);
            deg2+=30;

        },50)
    }
</script>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas绘制验证码</title>
    <style>
        body{
            text-align: center;
        }
        canvas{
            /*background: #ddd;*/
            border:1px solid red;
        }

    </style>
</head>
<body>
    <h1>h5-canvas验证码</h1>
    <canvas id="c2" width="120" height="40"></canvas>
    <script>
        //创建函数返回指定范围内的随机数
        function rn(min,max) {
            var n = Math.random()*(max-min) + min
            return Math.floor(n)
        }
        // console.log(rn(5,10));
        // console.log(rn(5,10));
        // console.log(rn(5,10));
        //创建函数返回指定范围内的随机颜色
        function rc(min,max) {
            var r = rn(min,max);
            var g = rn(min,max);
            var b = rn(min,max);
            return `rgb(${r},${g},${b})`;
        }
        console.log(rc(1,100));
        console.log(rc(1,100));

        //1.填充背景颜色(淡色)
        var ctx=c2.getContext("2d");
        var w = 120;
        var h = 40;
        ctx.fillStyle = rc(200,240);
        ctx.fillRect(0,0,w,h);
        //2.随机产生字符
        var pool = "ABCDEFGHIJKLMNO1234567890";
        for (var i=0;i<4;i++){
            var c=pool[rn(0,pool.length)];  //随机文字
            var fs = rn(18,40);     //随机大小
            var deg = rn(-45,45);   //随机旋转角度
            ctx.font = fs+"px SimHei";
            ctx.fillStyle = rc(80,150); //随机颜色
            ctx.textBaseline="top";     //设置基线
            ctx.save();             //保存旋转状态
            ctx.translate(30*i+15,15);  //设置圆点
            ctx.rotate(deg*Math.PI/180);    //设置旋转角度
            ctx.fillText(c,-10,-15);       //填充文字
            ctx.restore();      //恢复到保存点
        }
        //3.绘制5条干扰线
        for(var i=0;i<5;i++){
            ctx.strokeStyle = rc(0,255);    //随机干扰颜色
            ctx.beginPath();
            ctx.moveTo(rn(0,w),rn(0,h));    //干扰线起始点
            ctx.lineTo(rn(0,w),rn(0,h));    //干扰线
            ctx.stroke();
        }
        //4.绘制100个干扰点
        for(var i=0;i<100;i++){
            ctx.fillStyle=rc(0,250);
            ctx.beginPath();
            ctx.arc(rn(0,w),rn(0,h),1,0,2*Math.PI);
            ctx.fill();
        }
    </script>
</body>
</html>