canvas

0、教程

canvas1

1、canvas 概述

画布<canvas>元素是 HTML5 中的新元素,可以通过JavaScript 在页面中指定的区域绘制图形

<canvas id="canvas" width="400px" height="500px">画布,你的浏览器不支持canvas,请更新浏览器</canvas>

canvas 需要设置 width 和 height 属性,如果没有设置这两个属性,width 和 height 有默认值(300,150)。如果通过style 设置 width 、height,则图形有可能会拉伸变形,参见该文章

使用canvas的步骤:1、取得canvas元素对象 ;2、通过canvas 元素对象的 getContext("2d") 取得绘图2d上下文对象的引用;3、使用上下文的各种属性和方法来绘制图片。

2d上下文的坐标起始于 canvas 的左上角,原点坐标是 (0 , 0) 。

let imgURL = canvas.toDataURL("image/png");  //toDataURL() 是canvas对象的方法,导出画布上的图像
let img = document.createElement("img");
img.src = imgURL;
imgDiv.appendChild(img);

2、绘图上下文对象的属性和方法

fillStyle:该属性指定填充的样式(颜色,渐变对象,图像),值可以是字符串,渐变对象,模式对象,默认值是 “#000000”。如果是指定颜色的字符串,可以是任何CSS中指定颜色的格式

strokeStyle:该属性指定描边的样式,值可以是字符串,渐变对象,模式对象,默认值是 “#000000”。如果是指定颜色的字符串,可以是任何CSS中指定颜色的格式

 

fillRect( x, y, w, h):填充一个矩形,并指定坐标 (x , y),宽高 w 、h。其填充的颜色是通过 fillStyle 属性设置的

strokeRect( x, y, w, h):绘制一个矩形,没有填充

clearRect( x, y, w, h):将画布上的指定矩形区域清空,可以去掉之前绘制的图形

lineWidth:指定线条的宽度,可以是任何整数

lineCap:指定线条末端的形状,可以是 "butt"(平头),"round"(圆头),"square"(方头)

lineJoin:指定线条相交的方式,可以是 "round"(圆交),"bevel"(斜交),"miter"(斜接)

 

beginPath():表示开始绘制路径,在绘制路径之前必须先调用该方法

arc( x, y, radius, startAngle, endAngle, counterclockwise):以 (x , y) 为圆心绘制一条半径为 radius 的弧线,弧线的起始、截止角度分别是 startAngle,endAngle(角度是以弧度表示的),

counterclockwise表示是否按逆时针方向开始绘制(false是顺时针方向),角度的零弧度在x轴右侧

arcTo( x1, y1, x2, y2, radius):绘制一条 半径为 radius 的弧线 穿过 (x1 , y1) ,(x2 , y2)两个点

bezierCurveTo(c1x, c1y, c2x, c2y, x, y):绘制三次贝塞尔曲线,(c1x, c1y),(c1x, c1y) 是控制点1,控制点2的 坐标,(x, y) 是终点的的坐标

quadraticCurveTo(c1x, c1y, x, y):绘制二次贝塞尔曲线,(c1x, c1y),控制点的 坐标,(x, y) 是终点的的坐标

moveTo(x , y):把画笔移动到指定的坐标(x, y)。相当于设置路径的起始点坐标。

lineTo(x , y):绘制直线,从上一点开始到点 (x , y)

rect( x, y, w, h):绘制矩形路径,(不是独立的形状)

closePath():闭合路径,绘制一条连接路径起点和终点的直线,闭合路径之后,图形绘制命令又重新指向到上下文中

stroke():通过线条来绘制图形轮廓

fill():通过填充路径的内容区域生成实心的图形

clip():可以在路径上创建一个剪切区域,剪切区的大小是之前路径的范围。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域),被剪切区域内图形部分是可见的。

可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)

 

font:该属性用于设置绘制文本的字体、大小、样式,用css中字体格式设置方式,"bold 14px Arial"

textAlign:设置文本你的水平对齐方式,可选值:"start","end","left","right","center"

textBaseline:表示文本的基线,设置垂直对齐方式,可选值:"top","hanging","middle","alphabetic","ideographic","bottom"

fillText(string, x, y [,maxWidth]):填充式绘制文本(实体的)

strokeText(string, x, y [,maxWidth]):描边式绘制文本(中空的)

measureText(string):辅助确定文本大小,接受一个要绘制的文本,返回TextMetrics对象,该对象有一个 width 属性,表示在当前文本字体样式下,文本绘制时需要的宽度

 

rotate(angle):变换矩阵,围绕远点旋转 angle 弧度

scale(scaleX, scaleY):缩放图像,在x,y方向上分别乘以缩放比例,默认缩放比例是1.0

translate(x , y):变换矩阵,将坐标原点移动到(x, y)

transform(m1_1, m1_2, m2_1, m2_2, dx, dy):直接变换修改变换矩阵,修改方式是,乘以矩阵 

m1_1     m1_2    dx

m2_1     m2_2    dy

0            0           1

setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy):将变换矩阵重置为默认状态,然后再调用 transform()

 

save():保存当前所有设置,然后可进行新的设置,绘制新样式的图形

restore():恢复之前保存的设置,使用之前的设置绘图,save() 和 restore() 可以嵌套配合使用

 

drawImage(image, targetX, targetY [, targetW, targetH] ):将图像绘制到画布中,参数:图像对象,画布中图像的起点的 x 坐标,图像起点的 y 坐标,图像的高度,图像的宽度;最后两个参数可以不用设置,这样绘制出来的图像的高度和高度和原图一样

drawImage(image,sourceX, sourceY, sourceW, sourceH, targetX, targetY, targetW, targetH ):绘制图像,可以将原图中的一部分绘制到画布上,

参数:图像对象,原图像的起点的 x 坐标,原图像起点的 y 坐标,原图像的高度,原图像的宽度,目标图像的起点的 x 坐标,目标图像起点的 y 坐标,目标图像的高度,目标图像的宽度;

 

shadowColor:设置阴影颜色,css颜色格式,默认黑色

shadowOffsetX:x 轴方向的阴影偏移量,默认为0

shadowOffsetY:y 轴方向的阴影偏移量,默认为0

shadowBlur:模糊的像素度,默认为0(不模糊)

 

createLinerGradient(startX, startY, endX, endY):创建线性的渐变对象,参数:起点x坐标,起点y坐标,终点x坐标,终点y坐标

createRadialGradient(x0, y0, r0, x1, y1, r1):创建径向渐变对象,参数:起点圆心坐标x0,y0,半径r0,终点圆心坐标x1,y1,半径r1

得到渐变对象后,需要使用渐变的对象的 addColorStop(flag, colorString)方法,设置渐变开始和结束的颜色,flag只能是0 或 1 ,0表示开始,1表示结束。然后将渐变对象赋给 上下文的 fillStyle 或者 strokeStyle 属性,最后绘制图形

 

createPattern(image, repeat):创建模式对象,表示如何重复图像。参数:img对象/video对象/另一个canvas对象(HTML的元素),图像重复模式(和css 的 background-repeat 属性一样,"repeat","repeat-x","repeat-y","no-repeat");

得到模式对象后,将它赋给 fillStyle 属性,然后开始绘制区域

 

getImageData(x, y, w, h):返回一个ImageData对象的实例,参数:要取得数据画面区域的坐标和宽高。ImageData对象有三个属性:width,height,data。data是一个数组,保存着所选的区域的每个像素的数据(rgba,连续四个),data中每个像素的数据时依次排列的,数值大小介于0-255之间

globalAlpha:设置所有绘制图像的透明度,值[0,1],默认是0

globalCompositionOperation:表示后绘制的图形怎么样与先绘制的图形结合,可能的值:

"source-over":默认值,后绘制的图形位于先绘制的图形的上方

"source-in":后绘制的图形与先绘制的图形重叠的部分可见,两者其他部分完全透明

"source-out":后绘制的图形与先绘制的图形不重叠的部分可见,先绘制的图形完全透明

"source-atop":后绘制的图形与先绘制的图形重叠部分可见,新绘制的图形不受影响

"destination-over":后绘制的图形位于先绘制的图形的下方,只有之前透明像素下的部分可见

"destination-in":后绘制的图形位于先绘制的图形下方,两者不重叠部分完全透明

"destination-out":后绘制的图形擦除与先绘制的图形的重叠部分

"destination-atop":后绘制的图形位于先绘制图形的下方,在两者不重叠的地方,先绘制的图形变透明

"ligher":后绘制的图形与先绘制的图形重叠部分的值相加,使该部分变亮

"copy":后绘制的图形完全替代与之重叠的先绘制的图形

"xor":后绘制的图形与先绘制的图形的重叠部分执行”异或“操作

 

 <img src="img/next.png" alt="ss">
    <canvas id="canvas" width="500" height="400">画布,你的浏览器不支持canvas,请更新浏览器</canvas>
    <div id="imgDiv"></div>


    let canvas = document.querySelector("#canvas");
    let imgDiv = document.querySelector("#imgDiv");


    let ctx = canvas.getContext("2d");

    ctx.fillStyle="red";
    ctx.strokeStyle="blue";
   // ctx.strokeRect(10,10,50,50);
    ctx.fillRect(10,10,50,50);
    ctx.clearRect(25,25,10,10);



    let imgURL = canvas.toDataURL("image/png")
    let img = document.createElement("img");
    img.src = imgURL;
    imgDiv.appendChild(img);

    ctx.beginPath();
    ctx.arc( 150, 150, 40, 0, 0.5*Math.PI, false);
    ctx.closePath();
    ctx.stroke();

    ctx.font = "bold 20px Arial";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText("hello",100,100,50);
    ctx.strokeText("hello",140,140,50);


    var gradient = ctx.createLinearGradient(150,20,150,90);
    gradient.addColorStop(0,"#FFFF00");
    gradient.addColorStop(1,"#000000");

    ctx.fillStyle = gradient;
    ctx.fillRect(130,20,40,70);

    gradient = ctx.createRadialGradient(230,60,15,230,60,35);

    gradient.addColorStop(0,"#FFFF00");
    gradient.addColorStop(1,"#000000");

    ctx.fillStyle = gradient;
    ctx.fillRect(180,10,100,100);

    var pattern = ctx.createPattern(document.images[0],"repeat");
    ctx.fillStyle = pattern;
    ctx.fillRect(290,10,160,155);

   drawImg();
    function drawImg() {  // 简单的灰阶过滤
        let ctx = canvas.getContext("2d");
        let img = document.images[0];
        let imgData,data;

        ctx.drawImage(img,0,0);

        imgData = ctx.getImageData(0,0,img.width,img.height);
        data = imgData.data;

        for(let i=0,len = data.length; i<len; i+=4){
            let red = data[i];
            let green = data[i+1];
            let blue =  data[i+2];
            let alpha = data[i+3];

            let average = Math.floor((red + green + blue)/3);

            data[i] = average;
            data[i+1] = average;
            data[i+2] = average;
        }

        imgData.data = data;
        ctx.putImageData(imgData,0,0);
    }

 

posted @ 2019-05-31 17:47  zhanglw  阅读(236)  评论(0)    收藏  举报