Canvas学习笔记

2021-06-06

vscode默认不支持canvas代码提示,添加这句话后就有语法提示了:
/** @type {HTMLCanvasElement} */

 

let oC = document.getElementById(“c1”);
let gd = oC.getContext(“2d”); //获取上下文环境,有了这个对象后,就可以使用canvas提供的方法和属性了;

//画线
gd.moveTo(100, 100); //移动到某个位置
gd.lineTo(300, 300); //画线到某个位置
gd.strokeStyle = “green”; //描边的颜色
gd.lineWidth = 10; //描边的线条粗细
gd.stroke(); //最后一定要加上stroke(),才会画线

gd.beginPath(); //如果需要同时画多条不同颜色的线段,一定要先加beginPath()才能正常绘制。它会清除之前的路径,开始新的路径。
gd.strokeStyle = “red”; //描边的颜色
gd.stroke(); //最后一定要加上stroke(),才会画线

 

//闭合一个路径,要使用: closePath()

gd.moveTo(100, 100);
gd.lineTo(300, 300);
gd.lineTo(100, 300);
//gd.lineTo(100, 100);
gd.closePath(); //闭合一个路径,要用closePath(),而不是lineTo()到起始位置。区别如下图:
gd.strokeStyle = “green”;
gd.stroke();

//填充颜色

gd.fillStyle = “yellow”; //填充的颜色
gd.fill(); //最后要加上填充,才会起作用

 

//矩形
1.先绘制路径,再描边或者填充:
gd.rect(100, 100, 300, 200); //rect(x,y,w,h) x,y:起点坐标, w:宽度,h:高度
//gd.stroke();
gd.fill();

2.直接画:
gd.strokeRect(100, 100, 300, 200)
gd.fillRect(100, 100, 300, 200)

//画弧
// arc(cx, cy, r, startAng, endAng, 是否逆时针)
cx,cy:圆心坐标; r:半径; startAng,endAng:起始角度和终止角度,单位为弧度;最后一个参数:true-逆时针,false-顺时针
gd.arc(500, 300, 150, 0, Math.PI * 0.5, true);
gd.stroke();

以下代码是一个画饼图的例子:

//角度转化为弧度
        function d2a(d){
            return d * Math.PI/180
        }
        //弧度转化为角度
        function a2d(a){
            return a * 180/Math.PI
        }
        let oC = document.querySelector(“#c1”);
        let gd = oC.getContext(“2d”);
        let cx = 500, cy = 300, r = 150;
        let data = [300, 360, 240, 100];
        let colors = [“yellow”, “red”, “pink”, “purple”]
        let total = 0;
        let beginAng = 0;
        // 计算每个数据所占的角度
        // 原始做法:
        // function sum(data){
        //     for(let i=0; i<data.length; i++){
        //         total = total + data[i]
        //     }
        // }
        // sum(data);
        // 使用es6的reduce方法,看起来简洁一些:
        total = data.reduce((tmp,item) => tmp+item)
        newData = data.map((item) => {
            return (item/total) * 360
        })
        // 画弧
        function pie(startAng, endAng, color){
            let x = cx + Math.sin(d2a(startAng)) * r;
            let y = cy – Math.cos(d2a(startAng)) * r
            gd.beginPath();
            gd.moveTo(cx, cy);
            // 数学上的角度0度是从y轴朝上方向开始的,而arc的0度是从x轴朝右方向开始的,所以下面有个-90度的换算。-90度后,饼图的0度从y轴朝上方向开始画起。
            gd.lineTo(x, y);
            gd.arc(cx, cy, r, d2a(startAng – 90), d2a(endAng – 90), false);
            gd.closePath();
            gd.fillStyle = color;
            gd.fill();
            // gd.stroke();
        }
        newData.forEach((item,index) => {
            pie(beginAng, (beginAng + item), colors[index])
            beginAng += item
        })

// 旋转、平移等类似于css3的transform操作:

用canvas画一个旋转的矩形:

/** @type {HTMLCanvasElement} */
        let oC = document.querySelector(“#c1”);
        let gd = oC.getContext(“2d”);
        let rotate = 0;
        function d2a(n){
            return n*Math.PI/180;
        }
        // gd.strokeRect(100, 100, 300, 200);
        // 变换操作,起作用顺序是反着的,写在前面的反而后执行。跟css3的transform类似。
        // gd.translate(250, 200);
        // gd.rotate(d2a(30));
        // gd.fillStyle=”rgba(255, 0, 0, 0.3)”;
        // gd.fillRect(0,0,oC.width,oC.height);
        // gd.strokeRect(-150, -100, 300, 200);
        setInterval(function(){
            gd.clearRect(0,0,oC.width,oC.height);
            rotate++;
            //使用变换之前要先用save(),结束后要使用restore()才能正常显示。
            gd.save();
            gd.translate(250, 200);
            gd.rotate(d2a(rotate));
            gd.strokeRect(-150, -100, 300, 200);
            gd.restore();
        }, 100)

// 绘制图片

        let oImg = new Image();
        oImg.src=”sprite.png”;
        // Image()对象一定要onload后,再写canvas方法才会起作用!
        oImg.onload = function (){
            // 简化版: drawImage(img, x, y)-图片,放到画布的x,y坐标。
            // gd.drawImage(oImg, 100, 20);
            // 完整版:(主要用于从一张大图中截取一部分放到画布中)
            // drawImage(img,sx,sy,sw,sh,dx,dy,dw,dh)
            // img:图片
            // sx,sy,sw,sh -s:source,从源图片的起始x,y坐标开始,选择sw,sh的宽高
            // dx,dy,dw,dh -d:destination,放到画布中的x,y坐标处,以及dw,dh的宽高
            gd.drawImage(oImg,35,128,28,32,100,100,56,64);
        }

一个例子(行走的小人):

发表评论

邮箱地址不会被公开。 必填项已用*标注