【面向HTML5--Canvas绘图】

来源:互联网 发布:mac系统更新安装失败 编辑:程序博客网 时间:2024/05/16 01:13

Web绘图可以实现的效果:

(1)实时走势图(2)统计图(3)在线画图板(4)网页游戏(2D、3D)

目前可以使用Web绘图技术:

(1)Canvas绘图:2D位图绘图技术(2)SVG绘图:2D矢量图绘图技术(3)WebGL绘图:2D/3D绘图技术,还不是H5标准技术

Canvas绘图技术

HTML5新提供的一种2D位图绘图技术。

<canvas width="500" height="400">    您的浏览器不支持canvas标签</canvas>

canvas 标签默认是一个300*150px的 inline-block。注意:画布的宽和高不能用CSS来声明!

使用“画笔(绘图上下文对象)”来在画布上绘图(JS实现):

var ctx = canvas.getContext('2d')  //画笔对象

画笔对象的常用成员:

(1)绘制矩形(2)绘制文本(3)绘制路径(4)绘制图像

1、使用Canvas进行绘图——绘制矩形

说明:矩形的定位点在自己的左上角ctx.lineWidth = 1           描边的线宽ctx.strokeStyle = '#000'    描边样式ctx.fillStyle = '#000'      填充样式ctx.strokeRect(x, y, w, h)      描边一个矩形ctx.fillRect(x, y, w, h)        填充一个矩形ctx.clearRect(x, y, w, h)       清除一个矩形范围内的所有内容

2、使用Canvas进行绘图——绘制文本

说明:一段文字的定位点默认在文本基线的最左侧ctx.textBaseline = "alphabetic"   文件基线ctx. font ="12px sans-serif"      文本大小和字体ctx.strokeText( txt, x, y )     描边一段文本ctx.fillText( txt, x, y )       填充一段文本ctx.measureText(txt).width      基于当前字体设置,测量指定的文本宽度

3、使用Canvas绘制图形 —— 矩形

定位点:矩形左上角ctx.lineWidth = 1ctx.strokeStyle = '#000'ctx.fillStyle = '#000'ctx.strokeRect(x, y, w, h)ctx.fillRect(x, y, w, h)ctx.clearRect(x, y, w, h)

4、使用Canvas绘制图形 —— 文本

定位点:在文本基线的最左侧ctx.textBaseline = 'alphabetic'ctx.font = '12px sans-serif'ctx.fillText(txt, x, y)ctx.strokeText(txt, x, y)ctx.measureText(txt).width

5、使用渐变对象绘制图形

1)创建渐变对象必须指定用在画布上的起点和终点坐标:    var g = ctx.createLinearGradient(x1,y1,x2,y2);2)为渐变对象添加两个以上的颜色点    g.addColorStop( offset,  color );3)绘制图形时应用渐变对象    ctx.fillStyle = g;    ctx.strokeStyle = g;

6、使用Canvas绘制图形 —— 绘制路径(Path)

提示:Canvas中的路径概念与PS中的钢笔工具的含义一样的。可以绘制任意的直线、折线、曲线。路径本身是不可见的,有三个用途:描边、填充、裁剪
ctx.beginPath( )        开始一条新路径ctx.closePath( )        闭合路径(自动连接终点和起点)ctx.moveTo(x, y)        移动到指定点ctx.lineTo(x, y)        到指定点绘制直线ctx.arc(x, y, r, startAngle, endAngle)        绘制圆拱路径ctx.ellipse(x, y, rx, ry, startAngle, endAngle) 绘制椭圆拱路径ctx.bezierCurveTo(....) 绘制贝塞尔曲线ctx.stroke( )           对当前路径进行描边ctx.fill( )         对当前路径进行填充ctx.clip( )         对当前路径进行裁切

7、使用Canvas绘制图形 —— 绘制图像

提示:图像的定位点在自己的左上角。必须等待服务器端的图片下载完成,才能开始绘制图像!
var img = new Image();img.src = 'x.png';          //浏览器会立即异步请求该图片img.onload = function(){    //图片加载完成事件    ctx.drawImage(img, x, y)            //原始大小绘制图像    ctx.drawImage(img, x, y, w, h)  //绘制拉伸后的图像}

案例:

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title>绘制飞机</title>    <style>        canvas{            background:#efefef;        }    </style></head><body>    <canvas id="can1" width="500px" height="500px"></canvas>    <canvas id="can2" width="500px" height="500px"></canvas>    <canvas id="can3" width="500px" height="500px"></canvas></body><script>    var ctx1=can1.getContext('2d');    ctx1.lineWidth=5;    ctx1.lineJoin="round";    ctx1.beginPath();    ctx1.arc(250,250,100,Math.PI,3*Math.PI);//3点方向为0度,顺时针转    ctx1.strokeStyle="#999";    ctx1.stroke();    ctx1.strokeStyle="#0f0";    ctx1.fillStyle="#0f0";    var i=0;    var time1=setInterval(function(){        if(i<720){            ctx1.clearRect(200,220,100,60);            i+=36;            ctx1.beginPath();            ctx1.arc(250,250,100,Math.PI,(1+i/360)*Math.PI);            ctx1.stroke();            var txt=i*10/72+"%";            ctx1.textBaseline="top";            ctx1.font="60px SimHei";            var twid=ctx1.measureText(txt).width;            ctx1.fillText(txt,250-twid/2,220);        }else            clearInterval(time1);    },200);    ctx1.strokeStyle="";</script><script>    var ctx2=can2.getContext('2d');    ctx2.lineWidth=5;    ctx2.lineJoin="round";    var x= 1,y= 7,mi= 0,mj=0;    setInterval(function(){        ctx2.clearRect(0,0,500,500);        x=x==1?0:1;        y=y==7?8:7;        path(mi,mj,x,y);    },200);    function path(i,j,x,y){        ctx2.beginPath();        ctx2.arc(250+i,250+j,100,x*Math.PI/4,y*Math.PI/4);//3点方向为0度,顺时针转        ctx2.lineTo(250+i,250+j);        ctx2.closePath();//闭合        ctx2.stroke();        ctx2.beginPath();        ctx2.arc(250+i,200+j,25,0,2*Math.PI);        ctx2.fillStyle="#0f0";        ctx2.fill();        ctx2.beginPath();        ctx2.arc(262+i,200+j,8,0,2*Math.PI);        ctx2.fillStyle="#fff";        ctx2.fill();        ctx2.beginPath();        ctx2.arc(250+i,188+j,5,0,2*Math.PI);        ctx2.fillStyle="#fff";        ctx2.fill();    }    //移动事件 37 38 39 40    window.onkeydown=function(e){       // e.preventDefault();       //console.log(e.keyCode);        switch (e.keyCode){            case 37: e.preventDefault();mi-=10;break;            case 38: e.preventDefault();mj-=10;break;            case 39: e.preventDefault();mi+=10;break;            case 40: e.preventDefault();mj+=10;break;        }    }</script><script>    var ctx3=can3.getContext('2d');    var img1=new Image();    img1.src="img/p3.png";    img1.onload=function(){        /*ctx3.translate(50,25);        ctx3.drawImage(img1,0-50,0-25,100,50);        ctx3.drawImage(img1,400-50,0-25,100,50);        ctx3.drawImage(img1,0-50,450-25,100,50);*/        var i=1;        setInterval(function(){            i++;            (i==36)&&(i=1);            //飞机1            ctx3.translate(50,25);//平移            ctx3.rotate(10*i*Math.PI/180);//旋转            ctx3.drawImage(img1,-50,-25,100,50);//绘图            ctx3.rotate(-10*i*Math.PI/180);//复位            ctx3.translate(-50,-25);//复位            //飞机2            ctx3.drawImage(img1,400,0,100,50);//绘图            //飞机3            ctx3.translate(50,475);//平移            ctx3.rotate(10*i*Math.PI/180);//旋转            ctx3.drawImage(img1,-50,-25,100,50);//绘图            ctx3.rotate(-10*i*Math.PI/180);//复位            ctx3.translate(-50,-475);//复位            //飞机4            ctx3.save();//保存画笔当前状态            ctx3.translate(250,50);//平移            ctx3.rotate(10*i*Math.PI/180);//旋转            ctx3.drawImage(img1,-50,-25,100,50);//绘图            ctx3.restore();//复位画笔之前的状态            //飞机5,测试封装函数            fly(ctx3,img1,250,200,i*10,100,50);        },100);    }    //封装小飞机旋转    function fly(obj,img,x,y,i,wid,hei){        //x,x:坐标 i:一次旋转的度数 wid,hei:图片绘画的宽高        obj.save();//保存画笔当前状态        obj.translate(x,y);//平移        obj.rotate(i*Math.PI/180);//旋转        obj.drawImage(img,-wid/2,-hei/2,wid,hei);//绘图        obj.restore();//复位画笔之前的状态    }</script></html>

图形/图像的变形问题

  Canvas绘图中一般不使用CSS的变形属性——CSS变形只能用于HTML元素-Canvas技术中只有一个<canvas>。

若只针对某个图形/图像做变形,需要使用画笔的变形相关方法:

ctx.rotate( deg )   旋转画笔,所绘的图形图像都会旋转ctx.scale( x, y )       缩放ctx.translate( x, y )   平移整个画布的原点到一个新的点ctx.save()          保存画笔的当前变形状态ctx.restore()       恢复最近一次保存的画笔的所有状态

注意:
(1)画笔旋转默认的轴点是画布的原点(0,0),而不是图形/图像的定位点
(2)画笔的旋转有累加效果
(3)可以通过ctx.translate()修改画布原点的位置,一旦修改,所有点的坐标值全部改变

第三方提供的绘制统计图的工具

(1)Chart.js(2)FusionCharts(3)EChart.js(4)HighCharts
原创粉丝点击