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

Canvas画布

程序员文章站 2022-04-25 19:56:58
...

Canvas(位图)是通过js脚本来进行绘制,而svg(矢量图)是通过标签来绘制的。

首先在body中加入canvas标签,且宽高属性要写在行内,加ID为了在js中获取画布,并进行相关操作。并且浏览器不支持canvas时,会直接显示标签内容。

HTML代码

<canvas id="canvas" width="500px" height="500px">
    您的浏览器不支持Canvas!!!
</canvas>

然后在JS中回去canvas画布,并且获取绘制环境:

JS代码

//第一步,获取画布
var canvas = document.querySelector("#canvas");
//第二步,获取绘制环境
//getContext("2d")获取  canvas 绘制环境,参数必须传入且为2D
var ctx = canvas.getContext("2d");

然后就可以进行相关操作。

1、线段的绘制

/*
         * moveTo(X,Y)  起始位置(将画笔移到):用于表示开始一条新线的绘制
         * lineto(X,Y)  绘制线段到指定点,
         * 如果为第一条线可以不使用moveTo,否则画新线时需要先moveTo
         * stroke()  描边     
        */
        ctx.lineTo(50,50);
        ctx.lineTo(100,100);
        ctx.stroke();

2、设置线段相关属性的方法

        //设置线宽
        ctx.lineWidth = 10;
        //设置描边样式  接收所有颜色类型  red  #ccc  rgb rgba HSL?
        ctx.strokeStyle = "red";
        //设置线段交汇处样式  接收 bevel:斜角   round:圆角    miter:尖角(默认值)
        ctx.lineJoin = "bevel";
        //设置线帽  只在端点出有效  接收 round:圆帽  square:方帽  butt(屁股):无  默认
        ctx.lineCap = "square";
        
        ctx.moveTo(50,50);
        ctx.lineTo(150,50);
        ctx.lineTo(150,150);
        ctx.lineTo(50,150);
        ctx.lineTo(50,50);
        //填充
        ctx.fill();
        //填充颜色
        ctx.fillStyle = "cadetblue"
        ctx.stroke();
        
        //开始一条新路径的绘制,与closePath 没有关系,他仅仅是闭合线段
        ctx.beginPath();
        ctx.fillStyle = "cyan";
        ctx.strokeStyle = 'blue';
        ctx.moveTo(300,150);
        ctx.lineTo(50,300);
        ctx.lineTo(300,300);
        //闭合路径  将当前正在绘制的路径闭合
        ctx.closePath();        
        ctx.stroke();
        ctx.fill();

3、矩形的绘制

        /*       
         * fillRect(x,y,w,h)  填充矩形
         * strokeRect(x,y,w,h) 描边矩形
         * clearRect(x,yw,h)  擦除指定的区域
         * rect(x,y,w,h)  定义矩形路径,之后必须调用绘制方法
         * */
        //绘制矩形的三种方法
        ctx.fillStyle = "blue";
        ctx.fillRect(50,50,100,100);
        ctx.strokeRect(200,50,100,100);
        
        ctx.beginPath();
        ctx.fillStyle = "red";
        ctx.rect(350,50,100,100);
        ctx.fill();
        //ctx.stroke();
        
        ctx.beginPath();
        ctx.fillStyle = "green";
        ctx.fillRect(50,200,100,100);
        ctx.strokeRect(200,200,100,100);
        ctx.beginPath();
        ctx.fillStyle = "#ccc";
        ctx.rect(350,200,100,100);
        ctx.fill();
        
        ctx.clearRect(100,100,300,150);
        
        //清空画布
        ctx.clearRect(0,0,canvas.width,canvas.height);

4、弧形的绘制

        /** 
         * arc:弧
         * arc(cx,cy,radius,startAngle,endAngle,[是否逆时针])
         * 绘制圆弧
         * cx | cy 圆心坐标
         * radius  半径
         * startRadian  |  endRadian  开始 | 结束  弧度
         * 
         * */
        ctx.arc(250,250,100,0,Math.PI/2,true);
        ctx.fill();
        //ctx.stroke();

5、文字的绘制

/**
         * fillText(string,x,y)  填充文字
         * strokeText(string,x,y)  描边文字
         * 
         * 文字属性:
         * font  设置字体样式
         * textAlign  设置文字水平对齐方式
         * textBaseline(基线)  设置文字垂直对齐方式
         * */
        var str = "Hello Canvas!!!";
        var a = "你好画布"
        ctx.font = "40px 宋体";
        ctx.textAlign = "start";
        ctx.textBaseline = "middle";
        ctx.fillText(str,50,50);
        
        
        ctx.strokeText(a,50,150);

6、图片的绘制和设置图片像素的相关信息

/**
         * 绘制图片  要求必须在图片加载完成之后
         * drawImage(img,x,y);  图片有多大绘多大
         * drawImage(img,x,y,iw,ih);  将图片绘制在指定大小内,会压缩或拉伸图片
         * drawImage(img,ix,iy,iw,ih,cy,cy,cw,ch) 
         * 前四个由原图上剪下指定位置指定大小的图,重新绘制到画布的指定位置和指定大小
         * */
        var img = new Image();
        img.src = "./images/girl.png";
        img.onload = function () {
            //图片加载完毕
            //console.log("加载完成");
            ctx.drawImage(this,0,0);
            //ctx.drawImage(this,0,0,200,200);
            //ctx.drawImage(this,150,100,50,50,400,250,50,50);
            
            /**
             * getImageData(x,y,w,h)  获取指定范围内的像素信息
             * putImageData(imgData,x,y)  向指定范围内绘制像素信息 
             * */
            var data = ctx.getImageData(0,0,500,500);
            //console.log(data);
            var arr = data.data;
            for (var i=0;i<arr.length;i+=4) {               
                //反色  底片色
//              arr[i] = 255 - arr[i];
//              arr[i+1] = 255 - arr[i+1];
//              arr[i+2] = 255 - arr[i+2];
                
                
                //灰度
                arr[i]=arr[i+1]=arr[i+2] = (arr[i]+arr[i+1]+arr[i+2])/3;
            }
            ctx.putImageData(data,0,0);
            
        }

7、视频的绘制(需要在页面里加入一个视频标签)

var video = document.querySelector("video");
                
        video.oncanplaythrough = function () {
            //代表视频无缓冲播放         
            function _run () {
                //利用requestAnimationFrame不断的重绘图片
                ctx.drawImage(video,0,0);
                var data = ctx.getImageData(0,0,500,500);
                //console.log(data);
                var arr = data.data;
                for (var i=0;i<arr.length;i+=4) {
                    
                    //反色  底片色
    //              arr[i] = 255 - arr[i];
    //              arr[i+1] = 255 - arr[i+1];
    //              arr[i+2] = 255 - arr[i+2];
                    
                    
                    //灰度
                    arr[i]=arr[i+1]=arr[i+2] = (arr[i]+arr[i+1]+arr[i+2])/3;
                }
                ctx.putImageData(data,0,0);
                requestAnimationFrame(_run);
            }
            _run();
        }

8、pattern绘制平铺的对象

/**
         * createPattern(img,repeatType)  创建平铺对象
         * repeatTypr : 平铺类型  repeat-X  repeat-Y  repeat  no-repeat
         * */
        var img = new Image();
        img.src = "images/1.jpg"
        img.onload = function () {
            //创建平铺(pattern:样品)对象
            var pattern = ctx.createPattern(this,"repeat");
            ctx.fillStyle = pattern;
            ctx.fillRect(0,0,200,200);
            
            ctx.arc(350,350,100,0,Math.PI*2);
            ctx.fill();
        }

9、clip裁剪图片

/**
         * clip() 裁剪
         * 1.必须有一条封闭的路径
         * 2.路径必须在 clip 之前创建
         * 3.clip 必须放在drawImage 之前调用
         * */
        var img = new Image();
        img.src = "./images/girl.png";
        img.onload = function () {
            //图片加载完毕
            ctx.arc(200,150,50,0,Math.PI*2);
            ctx.rect(50,50,100,100);
            ctx.clip();
            ctx.drawImage(this,0,0);            
        }

10、组合-----绘制多个样式设计

/**
         * 
         * ctx.globalCompositeOperation  全部混合运算
         * source  新图形  destination  旧图形  
         * source-over//默认值  新图行在上
         * destination-over  旧图形在上
         * source-in  只显示重叠部分  新图在上
         * destination-in  只显示重叠部分  新图在上
         * source-out   显示新图不重叠的部分
         * destination-out   显示旧图不重叠部分
         * source-atop  显示旧图  重叠部分显示新图
         * destination-atop  显示新图  重叠部分显示旧图
         * lighter  颜色覆盖
         * xor  重叠部分不显示
         * copy  只显示新图形
         * */
        ctx.fillStyle = "red";
        ctx.fillRect(100,100,150,150);  
        
        ctx.globalCompositeOperation = "source-atop";
        
        ctx.beginPath();
        ctx.fillStyle = "blue";
        ctx.arc(250,250,100,0,Math.PI*2);
        ctx.fill();

11、平移和旋转坐标轴

//      ctx.fillRect(0,0,200,100);
//      
//      ctx.rotate(Math.PI/4);
//      ctx.translate(250,250); //设置坐标原点    
//      ctx.fillRect(0,0,200,100);
        
        ctx.fillStyle = "blue";
        ctx.fillRect(0,0,50,50);
        
        //保存状态
        ctx.save();
        ctx.translate(250,250);
        
        ctx.fillStyle = "red";
        ctx.fillRect(0,0,100,100);
        
        //回复状态
        ctx.restore();

12、shadow设置阴影

        ctx.shadowColor = "blue";
        ctx.shadowOffsetX = -5;
        ctx.shadowOffsetY = 5;
        //模糊距离
        ctx.shadowBlur = 20;
        ctx.fillRect(200,200,100,50);
        ctx.font = "bold 60px 宋体";
        ctx.fillText("Hello Canvas!!!",100,300);

13、贝塞尔曲线

        ctx.moveTo(100,150);
        ctx.lineTo(350,50);
        ctx.lineTo(450,150);
        ctx.stroke();
        
        ctx.moveTo(100,400);
        ctx.lineTo(150,300);
        ctx.lineTo(350,250);
        ctx.lineTo(450,400);
        ctx.stroke();
        
        //二次贝斯尔
        ctx.moveTo(100,150);
        ctx.quadraticCurveTo(350,50,450,150);
        ctx.stroke();
        
        //三次贝塞尔
        ctx.moveTo(100,400);
        ctx.bezierCurveTo(150,300,350,250,450,400);
        ctx.stroke();

14、渐变

//        线性渐变
//      var lg = ctx.createLinearGradient(0,0,100,100);
//      lg.addColorStop(0,"red");
//      lg.addColorStop(0.5,"yellow");
//      lg.addColorStop(1,"blue");
//      
//      ctx.fillStyle = lg;
//      ctx.fillRect(0,0,100,100);
        
        //径向渐变
        //var rg = ctx.createRadialGradient(100,250,50,350,250,150);
        var rg = ctx.createRadialGradient(250,250,50,250,250,150);
        
        rg.addColorStop(0,"red");
        rg.addColorStop(0.5,"yellow");
        rg.addColorStop(1,"blue");
        
        ctx.fillStyle = rg;