HTML5中的canvas详述

来源:互联网 发布:战术无线通信与网络 编辑:程序博客网 时间:2024/06/05 17:40

canvas概述

canvas标签非常的简洁,常用的就width和height两个属性

大多数 canvas 绘图 API 都没有定义在 <canvas> 元素本身上,而是定义在通过画布的 getContext() 方法获得的一个“绘图环境”对象上

复制代码
        var tCanvas = document.getElementById("canvasOne");        var ct = tCanvas.getContext("2d");        //因此可以通过该方法来检测浏览器是否支持canvas:        function canvasSupport() {            //检测是否支持canvas            return !!document.createElement("canvas").getContext;        }
复制代码

绘制矩形

界面html如下所示:

复制代码
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    <title></title></head><body onload="draw('canvas');">    <canvas id="canvas" width="400" height="300"></canvas>    <script src="script.js"></script></body></html>
复制代码

JavaScript如下所示:

复制代码
    function draw(id) {        var canvas = document.getElementById(id);        if (canvas == null) {            return false;        }        var context = canvas.getContext('2d');//取得上下文对象        context.fillStyle = '#EEEEFF';//填充样式        context.fillRect(0, 0, 400, 300);//填充矩形        context.fillStyle = 'red';        context.strokeStyle = 'blue';//图形边框的样式        context.lineWidth = 1;//设置图形边框的宽度        context.fillRect(50, 50, 100, 100);//填充矩形          context.strokeRect(50, 50, 100, 100);//绘制矩形边框    }
复制代码

效果图如下所示:


使用路径绘制圆形

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#EEEEFF';            context.fillRect(0, 0, 400, 300);            for (var i = 0; i < 10; i++) {                context.beginPath();//开始创建路径                //创建圆形路径                 context.arc(i * 25,//绘制圆形的起点横坐标                    i * 25,//绘制圆形的起点纵坐标                    i * 10,//圆形半径                    0,//开始角度                    Math.PI * 2,//结束角度                     true/*是否按顺时针方向进行绘制*/);                              context.closePath();//关闭路径                context.fillStyle = 'rgba(255,0,0,0.25)';//设置绘制样式                context.fill();//进行图形绘制            }        }
复制代码

 

效果图如下所示:


未关闭路径绘制圆形

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#EEEEFF';            context.fillRect(0, 0, 400, 300);            for (var i = 0; i < 10; i++) {                context.arc(i * 25, i * 25, i * 10, 0, Math.PI * 2, true);                context.fillStyle = 'rgba(255,0,0,0.25)';                context.fill();            }                    }
复制代码

 

效果图如下所示:


使用moveTo和LineTo方法绘制复杂线条

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#EEEEFF';            context.fillRect(0, 0, 400, 300);            var dx = 150,                dy = 150,                s = 100,                x = Math.sin(0),                y = Math.cos(0),                dig = Math.PI / 15 * 11;            context.beginPath();//需要使用moveTo将光标移动到所指定的直线起点            context.fillStyle = 'rgb(100,255,100)';            context.strokeStyle = 'rbg(0,0,100)';            for (var i = 0; i < 30; i++) {                x = Math.sin(i * dig);                y = Math.cos(i * dig);                context.lineTo(dx + x * s, dy + y * s);//绘制一条直线  (在直线起点和直线终点绘制)            }            context.closePath();            context.fill();            context.stroke();        }
复制代码

 

效果图如下所示:


使用bezierCurveTo绘制贝济埃曲线

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#EEEEFF';            var dx = 150,             dy = 150,             s = 100,             x = Math.sin(0),             y = Math.cos(0),             dig = Math.PI / 15 * 11;            context.beginPath();            context.globalCompositeOperation = 'red';            context.fillStyle = 'rgb(100,255,100)';            context.moveTo(dx, dy);//将光标移动到指定坐标点            for (var i = 0; i < 30; i++) {                x = Math.sin(i * dig);                y = Math.cos(i * dig);                //绘制贝济埃曲线   将当前坐标点到指定坐标点中间的贝济埃曲线追加到路径中                context.bezierCurveTo(dx + x * s,//第一个控制点的横坐标                    dy + y * s - 100,//第一个控制点的纵坐标                    dx + x * s + 100,//第二个控制点的横坐标                    dy + y * s,//第二个控制点的纵坐标                    dx + x * s,//贝济埃曲线的终点横坐标                    dy + y * s);//贝济埃曲线的终点纵坐标            }            context.closePath();            context.fill();            context.stroke();        }
复制代码

 

效果图如下所示:


绘制线性渐变

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            //创建线性渐变            var g1 = context.createLinearGradient(0,//渐变起始地点的横坐标                0,//渐变起始地点的纵坐标                0,////渐变结束地点的横坐标                300);//渐变结束地点的纵坐标            //追加渐变的颜色            g1.addColorStop(0,//设定颜色离开渐变起始点的偏移量  该参数的值是一个范围在0到1之间的浮点数  渐变起始点的偏移量为0  渐变结束点的偏移量为1                'rgb(255,255,0)');//颜色值            //因为是渐变   所以至少使用两次addColorStop            g1.addColorStop(1, 'rgb(0,255,255)');            context.fillStyle = g1;            context.fillRect(0, 0, 400, 300);                      var g2 = context.createLinearGradient(0, 0, 300, 0);            g2.addColorStop(0, 'rgba(0,0,255,0.5)');            g2.addColorStop(1, 'rgba(255,0,0,0.5)');            for (var i = 0; i < 10; i++) {                context.beginPath();                context.fillStyle = g2;//设置为渐变LinearGradient对象                context.arc(i * 25, i * 25, i * 10, 0, Math.PI * 2, true);                context.closePath();                context.fill();            }        }
复制代码

 

效果图如下所示:


绘制径向渐变

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            //绘制径向渐变            var g1 = context.createRadialGradient(400,//渐变开始圆的圆心横坐标                0,//渐变开始圆的圆心纵坐标                0,//渐变开始圆的半径                400,//渐变结束圆的圆心横坐标                0,//渐变结束圆的圆心纵坐标                400);//渐变结束圆的半径            g1.addColorStop(0.1, 'rgb(255,255,0)');            g1.addColorStop(0.3, 'rgb(255,0,255)');            g1.addColorStop(1, 'rgb(0,255,255)');            context.fillStyle = g1;            context.fillRect(0, 0, 400, 300);                       var g2 = context.createRadialGradient(250, 250, 0, 250, 250, 250, 300);            g2.addColorStop(0.1, 'rgba(255,0,0,0.5)');            g2.addColorStop(0.7, 'rgba(255,255,0,0.5)');            g2.addColorStop(1, 'rgba(0,0,255,0.5)');            for (var i = 0; i < 10; i++) {                context.beginPath();                context.fillStyle = g2;                context.arc(i * 25, i * 25, i * 10, 0, Math.PI * 2, true);                context.closePath();                context.fill();            }        }
复制代码

 

效果图如下所示:


利用坐标变换来绘制类似扑克牌的变形图形

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#eef';            context.fillRect(0, 0, 400, 300);            //移动坐标轴原点             context.translate(200,//将坐标轴原点向左移动多少个单位                50); //将坐标轴原点向下移动多少个单位                        context.fillStyle = 'rgba(255,0,0,0.25)';            for (var i = 0; i < 50; i++) {                context.translate(25, 25);                //将图形放大                context.scale(0.95,//水平方向的放大倍数                    0.95);//垂直方向的放大倍数                context.rotate(Math.PI / 10);//将图形进行旋转                context.fillRect(0, 0, 100, 50);            }        }
复制代码

 

效果图如下所示:


利用坐标变换与路径结合使用来绘制星形图形

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#eef';            context.fillRect(0, 0, 400, 300);            context.translate(200, 50);            for (var i = 0; i < 50; i++) {                context.translate(25, 25);                context.scale(0.95, 0.95);                context.rotate(Math.PI / 10);                create5Star(context);                context.fill();            }        }        function create5Star(context) {            var dx = 100,                dy = 0,                s = 50;            context.beginPath();            context.fillStyle = 'rgba(255,0,0,0.5)';            var x = Math.sin(0),                y = Math.cos(0),                dig = Math.PI / 5 * 4;            for (var i = 0; i < 5; i++) {                 x = Math.sin(i * dig);                 y = Math.cos(i * dig);                context.lineTo(dx + x * s, dy + y * s);            }            context.closePath();        }
复制代码

 

效果图如下所示:


利用矩阵变换来绘制彩虹

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            //定义颜色            var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'navy', 'purple'];            context.lineWidth = 10;//定义线宽            context.transform(1, 0, 0, 1, 100, 0);//矩阵转换            for (var i = 0; i < colors.length; i++) {//循环绘制圆弧                context.transform(1, 0, 0, 1, 0, 10);//定义每次向下移动10个像素的变换矩阵                context.strokeStyle = colors[i];//设定颜色                context.beginPath();                context.arc(50, 100, 100, 0, Math.PI, true);//绘制圆弧                context.stroke();            }        }
复制代码

 

效果图如下所示:


使用setTransform方法绘制变形图形

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            //绘制红色长方形            context.strokeStyle = 'red';            context.strokeRect(30, 10, 60, 20);            //绘制顺时针旋转45度的蓝色长方形            var rad = 45 * Math.PI / 180;            context.setTransform(Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), 0, 0);//定义顺时针旋转45的变换矩阵                       context.strokeStyle = 'blue';            context.strokeRect(30, 10, 60, 20);//绘制图形            //绘制放大2.5倍后的绿色长方形            context.setTransform(2.5, 0, 0, 2.5, 0, 0);//定义放大2.5倍的变换矩阵            context.strokeStyle = 'green';            context.strokeRect(30, 10, 60, 20);//绘制图形            //将坐标原点向左移动40像素,向下移动80像素后绘制灰色长方形            context.setTransform(1, 0, 0, 1, 40, 80);//定义将坐标原点向右移动40像素,向下移动80像素的矩阵            context.strokeStyle = 'gray';            context.strokeRect(30, 10, 60, 20);//绘制图形        }
复制代码

 

效果图如下所示:


图形结合的不同选项讲解

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            var oprtns = [                'source-atop',//只绘制新图形中与原有图形重叠的部分与未被重叠覆盖的原有图形,新图形的其它部分变成透明                'source-in',//只显示新图形中与原有图形相重叠的部分,新图形与原有图形的其它部分均变成透明                'source-out',//只显示原图形与新图形不重叠的部分,新图形与原有图形的其它部分均变成透明                'source-over',//新图形覆盖在原有图形之上                'destination-atop',//只绘制原有图形中被新图形重叠覆盖的部分与新图形的其它部分,原有图形中的其它部分变成透明 ,不绘制新图形中与原有图形相重叠的部分                'destination-in',//只显示原有图形中与新图形相重叠的部分,新图形与原有图形的其它部分均变成透明                'destination-out',//只显示原有图形中与新图形不重叠的部分,新图形与原有图形的其它部分均变成透明                'destination-over',//在原有图形之下绘制图形                'lighter',//原有图形与新图形均绘制,重叠部分做加色处理                'copy',//只绘制新图形,原有图形中未与新图形重叠的部分变成透明                'xor'];//只绘制新图形中与原有图形不重叠的部分,重叠部分变成透明            i = 7;//在原有图形之下绘制图形  (这里大家可以自己去试下其它选项  方便自己深入理解)            context.fillStyle = 'blue';            context.fillRect(10, 10, 60, 60);            context.globalCompositeOperation = oprtns[i];            context.beginPath();            context.fillStyle = 'red';            context.arc(60, 60, 30, 0, Math.PI * 2, false);            context.fill();        }
复制代码

 

效果图如下所示:


给图形绘制阴影

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#eef';            context.fillRect(0, 0, 400, 300);            context.shadowOffsetX = 10;//阴影的横向位移量            context.shadowOffsetY = 10;//阴影的纵向位移量            context.shadowColor = 'rgba(100,100,100,0.5)';//阴影的颜色            context.shadowBlur = 7.5;//阴影的模糊范围            context.translate(0, 50);            for (var i = 0; i < 3; i++) {                context.translate(50, 50);                create5Star(context);                context.fill();            }        }        function create5Star(context) {            var dx = 100,                dy = 0,                s = 50,                x = Math.sin(0),                y = Math.cos(0),                dig = Math.PI / 5 * 4;            context.beginPath();            context.fillStyle = 'rgba(255,0,0,0.5)';            for (var i = 0; i < 5; i++) {                x = Math.sin(i * dig);                y = Math.cos(i * dig);                context.lineTo(dx + x * s, dy + y * s);            }            context.closePath();        }
复制代码

 

效果图如下所示:


绘制图像

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#eef';            context.fillRect(0, 0, 400, 300);            var image = new Image();            image.src = 'img/ctrip.gif';            image.onload = function () {                              for (var i = 0; i < 7; i++) {                    context.drawImage(image,//img元素                        0 + i * 50,//绘制时的图像的宽度                        0 + i * 25,//绘制时的图像的高度                        100,//绘制该图像在画布中的x坐标                        100);//绘制该图像在画布中的y坐标                }            }        }
复制代码

 

效果图如下所示:


绘制图像时放大局部图像

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#eef';            context.fillRect(0, 0, 400, 300);            var image = new Image();            image.src = 'img/ctrip.gif';//设置图像路径            image.onload = function () {//绘制图像的函数                var i = 0;                //绘制原始图像                context.drawImage(image,//img元素                    0,//绘制时的图像的宽度                    0,//绘制时的图像的高度                    100,//绘制该图像在画布中的x坐标                    100);//绘制该图像在画布中的y坐标                //绘制将局部区域进行放大后的图像                context.drawImage(image,//img元素                    0,//源图像被复制区域在画布中的起始画布中的起始横坐标                    0,//源图像被复制区域在画布中的起始画布中的起始纵坐标                    50,//被复制区域的宽度                    80,//被复制区域的高度                    110,//复制后的目标图像在画布中的起始横坐标                    0,//复制后的目标图像在画布中的起始纵坐标                    100,//复制后的目标图像的宽度                    100);//复制后的目标图像的高度            }        }
复制代码

 

效果图如下所示:


图像平铺

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            var image = new Image();            image.src = 'img/ctrip.gif';//设置图像路径            image.onload = function () {                var scale = 5,                    n1 = image.width / scale,                    n2 = image.height / scale,                    n3 = canvas.width / n1,                    n4 = canvas.height / n2;                for (var i = 0; i < n3; i++) {                    for (var j = 0; j < n4; j++) {                        context.drawImage(image, i * n1, j * n2, n1, n2);                    }                }            }        }
复制代码

 

效果图如下所示:


利用createPattern方法平铺图像

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            var image = new Image();            image.src = 'img/ctrip.gif';//设置图像路径            image.onload = function () {                //no-repeat 不平铺                //repeat-x  横方向平铺                //repeat-y  纵方向平铺                //repeat   全方向平铺                var ptrn = context.createPattern(image, 'repeat');//创建填充样式,全方向平铺                context.fillStyle = ptrn;//指定填充样式                context.fillRect(0, 0, 400, 300);//填充画布            }        }
复制代码

 

效果图如下所示:


图像裁剪

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            var gr = context.createLinearGradient(0, 400, 300, 0);            gr.addColorStop(0, 'rgb(255,255,0)');            gr.addColorStop(1, 'rgb(0,255,255)');            context.fillStyle = gr;            context.fillRect(0, 0, 400, 300);            var image = new Image();            image.src = 'img/ctripLogo.png';//设置图像路径            image.onload = function () {                var n = 0,                    dx = 100,                    dy = 0,                    s = 150,                    x = Math.sin(0),                    y = Math.cos(0),                    dig = Math.PI / 5 * 4;                context.beginPath();                context.translate(100, 150);                for (var i = 0; i < 5; i++) {                    x = Math.sin(i * dig);                    y = Math.cos(i * dig);                    context.lineTo(dx + x * s, dy + y * s);//创建一个五角星的路径                }                context.clip();//设置裁剪图像                context.drawImage(image, -50, -150, 300, 300);            }        }
复制代码

 

效果图如下所示:


将图像进行反显操作

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            var image = new Image();            image.src = 'img/ctrip.gif';//设置图像路径            image.onload = function () {                context.drawImage(image, 0, 0);                //获得图像中的像素                var imageData = context.getImageData(0,//起点横坐标                    0,//起点纵坐标                    image.width,//获取区域的宽度                    image.height);//获取区域的高度                for (var i = 0,n=imageData.data.length; i < n; i+=4) {                    imageData.data[i + 0] = 255 - imageData.data[i + 0];//red                    imageData.data[i + 1] = 255 - imageData.data[i + 2];//red                    imageData.data[i + 2] = 255 - imageData.data[i + 1];//red                }                //将像素的数据重新放置到图像中                context.putImageData(imageData,//像素数组                    0,//重绘图像的起点横坐标                    0);//重绘图像的起点纵坐标            }        }
复制代码

 

效果图如下所示:


绘制文字

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.fillStyle = '#00f';            context.font = 'italic 30px sans-serif';//设置文字字体            context.textBaseline = 'top';//设置文字垂直对齐方式            context.fillText('示例文字', 0, 0);            context.font = 'bold 30px sans-serif';            context.strokeText('示例文字', 0, 50);        }
复制代码

 

效果图如下所示:


测量文字宽度

JavaScript如下所示:

复制代码
        function draw(id) {            var canvas = document.getElementById(id);            if (canvas == null) {                return false;            }            var context = canvas.getContext('2d');            context.font = 'italic 20px sans-serif';            var txt = '字符串的宽度为';//定义绘制文字            var tml = context.measureText(txt);//获得文字宽度            context.fillText(txt, 10, 30);//绘制文字             context.fillText(tml.width, tml.width + 10, 30);            context.font = 'bold 30px sans-serif';//改变字体            var tm2 = context.measureText(txt);//重新获得文字宽度            context.fillText(txt, 10, 70);//重新绘制文字            context.fillText(tm2.width, tm2.width + 10, 70);        }
复制代码

效果图如下所示:

1 0