HTML5 Canvas (2)

1,彩色字体

(结合字体和渐变)

  • fillText(text,x,y) - 绘制实心的文本
  • strokeText(text,x,y) - 绘制空心的文本
  • createLinearGradient(x,y,x1,y1) - 创建线条渐变
  • createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
  • var cxt = c.getContext("2d");
    var grd = cxt.createLinearGradient(10,10,120,10);
    grd.addColorStop(0,"purple");
    grd.addColorStop(0.25,"blue");
    grd.addColorStop(0.5,"green");
    grd.addColorStop(1,"red");
    
    cxt.strokeStyle = grd;
    cxt.font = "60px Arial";
    cxt.strokeText("smile!",10,120);

2,贝塞尔曲线

绘制贝塞尔曲线(贝济埃、bezier) context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y) 

   cp1x:第一个控制点x坐标

    cp1y:第一个控制点y坐标

    cp2x:第二个控制点x坐标

    cp2y:第二个控制点y坐标

    x:终点x坐标

    y:终点y坐标


 绘制二次样条曲线 context.quadraticCurveTo(qcpx,qcpy,qx,qy)

    qcpx:二次样条曲线控制点x坐标

    qcpy:二次样条曲线控制点y坐标

    qx:二次样条曲线终点x坐标

    qy:二次样条曲线终点y坐标

View Code
复制代码
 1         function draw24(id) {
 2             var canvas = document.getElementById(id);
 3             if (canvas == null) {
 4                 return false;
 5             }
 6             var context = canvas.getContext("2d");
 7 
 8             context.moveTo(50, 50);
 9             context.bezierCurveTo(50, 50,150, 50, 150, 150);
10             context.stroke();
11             context.quadraticCurveTo(150, 250, 250, 250);
12             context.stroke();
13         }
复制代码

var cxt = c.getContext("2d");
cxt.moveTo(10,10);
cxt.bezierCurveTo(10,10,100,50,60,150);
cxt.stroke();

cxt.quadraticCurveTo(60,170,180,200);
cxt.stroke();


3,图形变形


1、平移context.translate(x,y)

    x:坐标原点向x轴方向平移x

    y:坐标原点向y轴方向平移y

2、缩放context.scale(x,y)

    x:x坐标轴按x比例缩放

    y:y坐标轴按y比例缩放

3、旋转context.rotate(angle)

    angle:坐标轴旋转x角度(角度变化模型和画圆的模型一样)

var cxt = c.getContext("2d");
//0,初始
cxt.fillStyle = "blue";
cxt.strokeStyle = "green";
cxt.strokeRect(0,0,50,50);

//1,位移
cxt.translate(30,30);
cxt.fillRect(0,0,50,50);

//2,缩放
cxt.restore();
cxt.save();
cxt.fillStyle = "red";
cxt.scale(0.8,0.8);
cxt.fillRect(0,0,50,50);

//3,旋转
cxt.restore();
cxt.save();
cxt.fillStyle = "yellow";
cxt.translate(80,80);
cxt.rotate(Math.PI/4);
cxt.fillRect(0,0,50,50);

由上可见:

1,可将此看做是平移,缩放,旋转的坐标轴。

2,平移,缩放,旋转的顺序不同都将画出不同的效果。

简单平移,缩放,旋转先后顺序不同,坐标轴的变化图

4,矩阵变换 context.transform(m11,m12,m21,m22,dx,dy)


    所谓的矩阵变换其实是context内实现平移,缩放,旋转的一种机制

各参数意义对应如下表:

参数 意义
m11水平缩放(1)
m12水平倾斜(0)
m21垂直倾斜(0)
m22垂直缩放(1)
dx水平位移(0)
dy垂直位移(0)


调用translate()方法只是简单地将坐标原点进行上、下、左、右移动。
rotate()方法会将坐标轴根据指定角度里进行顺时针旋转。
scale()方法实现对x轴或由y轴上的距离进行延长和缩短。传递负值会实现
 
scale以坐标原点做参照点将坐标轴进行翻转。就好像镜子中的镜像。
translate用来将坐标原点移动到画布最左下角,然后scale方法用于实现将y轴进行翻转,这样的就变成了越往上y轴越大。

从数学角度来理解坐标系变换:
translate、rotate和scale方法想象成对坐标轴的变换,就很容易理解了。


建议使用transform()的时候,可以在如下几个情况下使用:

1.使用context.transform (1,0,0,1,dx,dy)代替context.translate(dx,dy)
2.使用context.transform(sx,0,0,sy,0,0)代替context.scale(sx, sy)
3.使用context.transform(0,b,c,0,0,0)来实现倾斜效果(最实用)。

不用再使用它去实现旋转了,另外也没有也不用全记这些结论,直接记下abcdef六个参数的意义,效果是一样的。

//0,初始
var ctx = c.getContext("2d");
ctx.strokeStyle = "red";
ctx.lineWidth = 10; //设置stroke的线宽度
ctx.strokeRect(10,10,50,50);

ctx.strokeStyle = "green";
ctx.fillStyle = "yellow";
ctx.save();

//1,位移(80,0) ==》 ctx.translate(80,0);
ctx.transform(1,0,0,1,80,0);
ctx.fillRect(10,10,50,50);
ctx.strokeRect(10,10,50,50);

//2,缩放(1.2,1.2) ==》 ctx.scale(1.2,1.2)同时位移
ctx.transform(1.2,0,0,1.2,80,0);
ctx.fillRect(10,10,50,50);
ctx.strokeRect(10,10,50,50);

//3,倾斜(0.2,0.2) 同时位移
ctx.transform(1,0.2,0.2,1,80,0);
ctx.fillRect(10,10,50,50);
ctx.strokeRect(10,10,50,50);


5,setTransform()方法

transform()方法的行为相对于由 rotate(),scale(), translate(), or transform() 完成的其他变换。例如:如果我们已经将绘图设置为放到两倍,则 transform() 方法会把绘图放大两倍,那么我们的绘图最终将放大四倍。这一点和之前的变换是一样的。

但是setTransform()不会相对于其他变换来发生行为。它的参数也是六个,context.setTransform(a,b,c,d,e,f),与transform()一样。

//0,初始
var ctx = c.getContext("2d");
ctx.strokeStyle = "red";
ctx.lineWidth = 10; //设置stroke的线宽度
ctx.strokeRect(10,10,80,80);

ctx.fillStyle = "yellow";
ctx.save();

//1,位移(80,0) ==》 ctx.translate(80,0);
ctx.transform(1,0,0,1,100,0);
ctx.fillRect(10,10,80,80);

//2,缩放(0.8,0.8) ==》 在0,初始的基础的上缩放
ctx.setTransform(0.8,0,0,0.8,0,0);
ctx.fillRect(10,10,50,50);


6,图形组合 

context.globalCompositeOperation=type


    图形组合就是两个图形相互叠加了图形的表现形式,是后画的覆盖掉先画的呢,还是相互重叠的部分不显示等等,至于怎么显示就取决于type的值了

source:最新绘制的图案    destination:原图案

    type:

        source-over(默认值):在原有图形上绘制新图形(最新绘制图案在上)

        destination-over:在原有图形下绘制新图形(原图案在上)

        source-in:显示原有图形和新图形的交集,新图形在上,所以颜色为新图形的颜色(后绘制图案重叠部分)

        destination-in:显示原有图形和新图形的交集,原有图形在上,所以颜色为原有图形的颜色(原图案重叠部分)

        source-out:只显示新图形非交集部分(后绘制图案非重叠部分)

        destination-out:只显示原有图形非交集部分(原图案非重叠部分)

        source-atop:显示原有图形和交集部分,新图形在上,所以交集部分的颜色为新图形的颜色(后绘制图案重叠部分(上)与原图案)

        destination-atop:显示新图形和交集部分,新图形在下,所以交集部分的颜色为原有图形的颜色(原图案重叠部分(上)与后绘制图案)

        lighter:原有图形和新图形都显示,交集部分做颜色叠加(重叠部分颜色叠加)

        xor:重叠飞部分不显示

        copy:只显示新图形

7,图形绘制阴影


    context.shadowOffsetX :阴影的横向位移量(默认值为0)
    context.shadowOffsetY :阴影的纵向位移量(默认值为0)
    context.shadowColor :阴影的颜色
    context.shadowBlur :阴影的模糊范围(值越大越模糊)

var ctx = c.getContext("2d");
var grd = ctx.createLinearGradient(10,10,200,10);
grd.addColorStop(0,"purple");
grd.addColorStop(0.25,"yellow");
grd.addColorStop(0.5,"orange");
grd.addColorStop(1,"red");

ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowColor = "rgba(0,0,0,0.3)";
ctx.shadowBlur = 2.0;

ctx.font = "40px Arial";
ctx.fillStyle = grd;
ctx.fillText("hello word!",10,60);//ctx.fillText("hello word!",x,y);x,y开始绘制文本的点


8,绘制图像 

绘图:context.drawImage

图像平铺:context.createPattern(image,type)

图像裁剪:context.clip()

像素处理:var imagedata=context.getImageData(sx,sy,sw,sh)


绘图 context.drawImage

    context.drawImage(image,x,y)

        image:Image对象var img=new Image(); img.src="url(...)";

        x:绘制图像的x坐标

        y:绘制图像的y坐标

    context.drawImage(image,x,y,w,h)

        image:Image对象var img=new Image(); img.src="url(...)";

        x:绘制图像的x坐标

        y:绘制图像的y坐标

        w:绘制图像的宽度

        h:绘制图像的高度

    context.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh):

    选取图像的一部分矩形区域进行绘制

        image:Image对象var img=new Image(); img.src="url(...)";

        sx:图像上的x坐标

        sy:图像上的y坐标

        sw:矩形区域的宽度

        sh:矩形区域的高度

        dx:画在canvas的x坐标

        dy:画在canvas的y坐标

        dw:画出来的宽度

        dh:画出来的高度

    最后一个方法可能比较拗,还是上图吧

var img =new Image();
img.src = "../images/11.png";
ctx.drawImage(img,0,0);

图像平铺 context.createPattern(image,type)

    type:
        no-repeat:不平铺

        repeat-x:横方向平铺

        repeat-y:纵方向平铺

        repeat:全方向平铺

图像裁剪:context.clip()

    context.clip()只绘制封闭路径区域内的图像,不绘制路径外部图像,用的时候

        先创建裁剪区域

create5StarClip(ctx);
var img =new Image();
img.src = "../images/11.png";
ctx.drawImage(img,0,0);

function create5StarClip(context) {
     var n = 0;
     var dx = 100;
     var dy = 100;
     var s = 100;
     context.beginPath();
     //context.strokeStyle ="red";
     var x = Math.sin(0);
     var y = Math.cos(0);
     var dig = Math.PI / 5 * 4;
     for (var i = 0; i < 5; i++) {
             var x = Math.sin(i * dig);
             var y = Math.cos(i * dig);
             context.lineTo(dx + x * s, dy + y * s);
         }
     context.closePath();
     context.clip();
 }

9,像素处理:

获取像素颜色数组: var imagedata=context.getImageData(sx,sy,sw,sh)

    sx:cavas的x轴坐标点

    sy:canvas的y轴坐标点

    sw:距离x的宽度

    sh:距离y的高度

可以利用context.getImageData返回的一个像素颜色数组,顺序是所取像素范围的从左到右,从上到下,数组的元素是(所有图形,包括图片,和绘制的图形)每个像素的rgba

[r1,g1,b1,a1,r2,g2,b2,a2...]

 

设置像素颜色:context.putImageData(imagedata,dx,dy,dirtyX,dirtyY,dirtyWidth,dirtyHeight) 
    对imagedata数组中的各个像素的r、g、b、a值进行修改,再调用putImageData方法进行绘制

        imagedata:修改后的imagedata

        dx:重绘图像的起点横坐标(重绘的起点和原来的图像一致的话就会把原来的图形覆盖掉,看起来就像是原来的图像变成现在的图像一样)

        dy:重绘图像的起点纵坐标

        //以下可选参数,设置重绘的矩形范围,如果缺省,默认会重绘所有的imegedata

        dirtyX:矩形左上角x轴坐标

        dirtyY:矩形左上角y轴坐标

        dirtyWidth:矩形长度

        dirtyHeight:矩形高度

 

View Code
复制代码
 1         function draw16(id) {
 2             var canvas = document.getElementById(id);
 3             if (canvas == null)
 4                 return false;
 5             var context = canvas.getContext("2d");
 6             context.fillStyle = 'red'
 7             //在右下角画一个正方形
 8             context.fillRect(250,250,150,50);
 9             var image = new Image();
10             image.src = "Image/html5.jpg";
11 
12             image.onload = function () {
13                 //在左上角画一幅图片
14                 context.drawImage(image, 0, 0,200,200);
15 
16                 //实验证明imagedata取的是canvas所在范围画的图形,不止是图片
17                 //不会取该区域内是空白的canvas的像素
18                 var imagedata = context.getImageData(0, 0, 400, 300);
19 
20                 //修改imagedata
21                 for (var i = 0, n = imagedata.data.length; i < n; i += 4) {
22           
23                     imagedata.data[i + 0] = 255 - imagedata.data[i + 0]; //red;
24                     imagedata.data[i + 1] = 255 - imagedata.data[i + 1]; //green
25                     imagedata.data[i + 2] = 255 - imagedata.data[i + 2]; //blue
26                     //imagedata.data[i + 3] = 255 - imagedata.data[i + 3]; //a
27                 }
28                 context.putImageData(imagedata, 0, 0);
29             }
30         }
复制代码

10,保存和恢复状态 

保存:context.save()

恢复:context.restore()


    在上面的裁剪图片提过,一旦设定了裁剪区域,后来绘制的图形都只显示裁剪区域内的内容,要“取消”这个裁剪区域才能正常绘制其他图形,其实这个“取消”是利用save()方法和restore()方法来实现的。

    context.save():调用该方法,会保存当前context的状态、属性(把他理解成游戏存档)

    context.restore():调用该方法就能恢复到save时候context的状态、属性(游戏回档)

View Code
复制代码
 1    function draw18(id) {
 2             var canvas = document.getElementById(id);
 3             if (canvas == null)
 4                 return false;
 5             var context = canvas.getContext("2d");
 6             context.fillStyle = "red";
 7             context.save(); //保存了当前context的状态
 8             context.fillStyle = "black";
 9             context.fillRect(0, 0, 100, 100);
10             context.restore();//恢复到刚刚保存的状态
11             context.fillRect(0,120,100,100);
12         }
复制代码

顶部

11,保存文件  canvas.toDataURL(MIME)


      在canvas中绘出的图片只是canvas标签而已,并非是真正的图片,是不能右键,另存为的,我们可以利用canvas.toDataURL()这个方法把canvas绘制的图形生成一幅图片,生成图片后,就能对图片进行相应的操作了。

View Code
复制代码
 1         function draw19(id) {
 2             var canvas = document.getElementById(id);
 3             if (canvas == null)
 4                 return false;
 5             var context = canvas.getContext("2d");
 6             context.fillStyle = "rgb(0,0,225)";
 7             context.fillRect(0, 0, canvas.width, canvas.height);
 8             context.fillStyle = "rgb(255,255,0)";
 9             context.fillRect(10, 20, 50, 50);
10             //把图像保存到新的窗口
11             var w=window.open(canvas.toDataURL("image/jpeg"),"smallwin","width=400,height=350");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值