网页中的实时走势图,抢红包,网页游戏,地图应用..
(1)SVG 绘图 2D矢量绘图技术,2000年出现,后纳入h5
(2)Canvas绘图 2D位图绘图技术,H5提出
(3)WebGL绘图 3D绘图技术,尚未纳入H5标准
Canvas绘图难点所在:
(1)坐标系
(2)单词比较多
Canvas画布:画布是H5提供的绘图基础
<canvas width=”500” height=”400”>
您的浏览器版本太低,请升级
</canvas>
Canvas标签在浏览器中默认是300*150的inine-block,画布宽度高度属性只能用js/属性来赋值.
不能用CSS样式赋值.
每个画布上有且只有一个”画笔”对象—使用该对象来绘图
var ctx = canvas.getContext(“2d”); 得到画布的画笔对象
(1)使用canvas绘制矩形(长方形)
矩形定位点在自己左上角
ctx.lineWidth = 1; 描边宽度(边线宽度)
ctx.fillStyle = “#999”; 填充样式
ctx.strokeStyle = “#000”; 描边样式
ctx.fillRect(x,y,w,h); 填充矩形
ctx.strokeRect(x,y,w,h); 描边矩形
ctx.clearRect(x,y,w,h); 清除矩形范围内所有图形
练习:左上角 右上角 左下角 右下角 居中
绘制5个矩形,大小100*80 填充,颜色不同
ex:不断碰撞移动的方块
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> </style> </head> <body> <canvas id="ca" width="600px" height="600px"> </canvas> <script> //获取画布 var ca=document.getElementById("ca") //获取画笔 var ctx=ca.getContext("2d") //绘制矩形 ctx.fillStyle="red"; ctx.fillRect(0,0,100,80) ctx.fillStyle="black" ctx.fillRect(600-100,0,100,80) ctx.fillStyle="#ddd" ctx.fillRect(0,600-80,100,80) ctx.fillStyle="#ccc" ctx.fillRect(600-100,600-80,100,80) ctx.fillStyle="#aff" ctx.fillRect(300-50,300-40,100,80); ctx.clearRect(0,0,600,600); ctx.strokeStyle="#000"; //控制物体左右移动 var x=0 var y=0 //设置一个变量来控制物体的移动方向 var xdirection=1 var ydirection=1 var time=setInterval(function () { ctx.clearRect(0,0,600,600) x+=1*xdirection y+=1*ydirection ctx.strokeRect(x,y,100,80) if(x>500){ xdirection=-xdirection }else if(x<0){ xdirection=-xdirection } if(y>520){ ydirection=-ydirection; }else if(y<0){ ydirection=-ydirection } },0.01) //控制物体上下移动 // var y=0 // var ydirection=1 // var time2=setInterval(function () { // ctx.clearRect(0,0,600,600); // y+=1*ydirection; // ctx.strokeRect(0,y,100,80) // if(y>520){ // ydirection=-ydirection; // }else if(y<0){ // ydirection=-ydirection // } // },1) </script> </body> </html>(2)使用canvas绘制文本
ctx.textBaseline = “alphabetic” 文本基线(默认值)
ctx.font = “12px sans-serif”; 文本大小和字体
ctx.fillText(str,x,y); 填充一段文本
ctx.strokeText(str,x,y) 描边一段文本
如图,绘制文本是空心的,而填充是实心的
ctx.measureText(str); 测量文本宽度
ex:更改文本基线为top(可以使得字母可见)(常用)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <canvas id="c2" width="600px" height="600px" style="background-color: yellow"> 您的浏览器版本太低,请及时升级 </canvas> <script> var str="abcxyz" var c2=document.getElementById("c2") var ctx=c2.getContext("2d") //设置基准线 ctx.textBaseline="top" ctx.font="39px sans-serif" //绘制填充矩形 ctx.fillText(str,0,0) </script> </body> </html>
练习:左上角 右上角 左下角 右下角 居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <canvas id="c2" width="600px" height="600px" style="background-color: yellow"> 您的浏览器版本太低,请及时升级 </canvas> <script> var str="abcxyz" var c2=document.getElementById("c2") var ctx=c2.getContext("2d") //设置基准线 ctx.textBaseline="top" ctx.font="39px sans-serif" //读取文本的宽 var w=ctx.measureText(str).width //绘制填充矩形 ctx.fillText(str,0,0) //右上角 ctx.fillText(str,600-w,0) //右下角 ctx.fillText(str,600-w,600-39) //左下角 ctx.fillText(str,0,600-39) //中间 ctx.fillText(str,300-w/2,300-39/2) </script> </body> </html>
左右移动文字
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <canvas id="c2" width="600px" height="600px" style="background-color: yellow"> 您的浏览器版本太低,请及时升级 </canvas> <script> var str="abcxyz" var c2=document.getElementById("c2") var ctx=c2.getContext("2d") //设置基准线 ctx.textBaseline="top" ctx.font="39px sans-serif" //读取文本的宽 var w=ctx.measureText(str).width var x=0; var xdirection=1; var timer=setInterval(function(){ //清除画布 ctx.clearRect(0,0,600,600) //修改x x+=1*xdirection //绘制文本 ctx.fillText(str,x,0) //判断 if(x>600-w){ xdirection=-xdirection }else if(x<0){ xdirection=-xdirection } },10) </script> </body> </html>
path:由多个坐标点组成任意形状,路径不可见,可用于“描边”,”填充”.
#复杂图形依靠路径
ctx.beginPath(); 开始一条新路径
ctx.closePath(); 闭合当前路径
ctx.moveTo(x,y); 移动到指定点
ctx.lineTo(x,y); 从当前点到指定点画直线
ctx.lineWidth=n 设置线的宽度
ctx.arc(cx,cy,r,start,end); 绘制圆拱型
cx,cy 圆心
r 半径
start,end 开始角度和结束角度
#圆弧度 0~2*Math.PI
#角度=>弧度 n*Math.PI/180=>弧度
ctx.stroke(); 描边
ctx.fill(); 填充
ex:画一个x-y坐标轴
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <canvas width="600px" height="600px" id="c1" style="background-color: #4cae4c"> 您的浏览器版本太低请及时升级 </canvas> <script> var c1=document.getElementById("c1") var ctx=c1.getContext("2d"); ctx.beginPath() ctx.moveTo(40,300) ctx.strokeStyle="#ddd" ctx.lineTo(40,0) ctx.lineTo(40-25,25) ctx.moveTo(40,0) ctx.lineTo(40+25,25) ctx.moveTo(40,300) ctx.strokeStyle="#aff" ctx.lineTo(300,300) ctx.lineTo(300-25,300-25) ctx.moveTo(300,300) ctx.lineTo(300-25,300+25) ctx.lineWidth=5; ctx.stroke() </script> </body> </html>
练习:创建一个函数 openMouth(),画右侧图形
练习:创建一个函数 closeMouth(),画左侧图形
练习:定时器,每隔1S,交替调用上述两个函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <canvas id="c1" width="600px" height="600px" style="background-color: yellow"></canvas> <script> // //=========画两个同心圆==================== // var c1=document.getElementById("c1") // var ctx=c1.getContext("2d") // ctx.beginPath(); // ctx.strokeStyle="blue" // ctx.arc(300,300,200,0,2*Math.PI) // ctx.stroke() // ctx.beginPath() // //画里面的圆 // ctx.strokeStyle="red" // ctx.arc(300,300,80,0,360*Math.PI/180) // ctx.lineWidth=6 // ctx.stroke() //=============画两个笑脸========== //====================== var c1 = document.getElementById("c1") var ctx = c1.getContext("2d") var closeMouth=function () { ctx.beginPath() ctx.arc(300, 300, 200, 0, 2 * Math.PI) ctx.strokeStyle = "black" ctx.lineTo(300, 300) ctx.stroke() //画眼睛 ctx.beginPath() ctx.arc(370, 240, 50, 0, 2 * Math.PI) ctx.fillStyle = "blue" ctx.fill() //画眼珠 ctx.beginPath() ctx.arc(373, 225, 6, 0, 2 * Math.PI) ctx.fillStyle = "#fff" ctx.fill() } //======================== var openMouth=function () { //画大脸盘子 ctx.beginPath() ctx.strokeStyle = "black" ctx.arc(300, 300, 200, 1 / 4 * (Math.PI), 7 / 4 * Math.PI) ctx.lineTo(300, 300) ctx.closePath() ctx.stroke() //画个眼睛 ctx.beginPath() ctx.fillStyle = "blue" ctx.arc(320, 200, 50, 0, 2 * Math.PI) ctx.fill() //画眼珠 ctx.beginPath() ctx.arc(323, 185, 6, 0, 2 * Math.PI) ctx.fillStyle = "#fff" ctx.fill() } var x=1; setInterval( function () { x++ if(x%2==0) { ctx.clearRect(0,0,600,600) closeMouth() }else { ctx.clearRect(0,0,600,600) openMouth() } },1000 ) </script> </body> </html>
canvas 属于客户端技术,图片保存服务器,所以浏览器先下载,再绘制图片,且等待图处下载完成.
var p3 = new Image();
p3.src = “x.jpg”; #下载指定图片
p3.onload = function(){ #当图片下载成功后触发事件
console.log(p3.width);
ctx.drawImage(p3,x,y); //绘制原始大小图片
ctx.drawImage(p3,x,y,w,h); //拉伸图片
}
canvas绘图中有变形技术同,可以针对某一个图形/图像在绘制过程中进行变形:rotate();translate();平移原点
ctx.rotate(弧度); 旋转绘制图像以画布原点为轴心.(旋转的角度是在累加的)
ctx.translate(x,y); 将画布原点平移到指定位置
ctx.save(); 保存画笔当前所有状态值
ctx.restore(); 恢复画笔上一次保存时所有状态值(弧度值,画布原点。。。)
练习:在画布中心位置绘制一个旋转飞机,以自己为中心旋转
练习:画二架飞机,右上角飞机比中心飞机旋转速度快一倍
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> </style> </head> <body> <canvas width="600px" height="600px" id="c1" style="background-color: yellow"> 您的浏览器版本太低请升级 </canvas> <script> var c1=document.getElementById("c1") var ctx=c1.getContext("2d"); var p3=new Image() p3.src="img/p3.png" p3.onload=function () { var deg=10 var timer=setInterval(function () { ctx.clearRect(0,0,600,600) //保存状态 ctx.save() //平移原点中心 ctx.translate(300,300) ctx.rotate(deg*Math.PI/180) ctx.drawImage(p3,-100,-50) //回复状态(恢复状态后需要自己累加旋转角度) ctx.restore() deg+=10; },10) } var p4=new Image() p4.src="img/p4.png" p4.onload=function () { var deg2=20 var timer2=setInterval(function () { ctx.clearRect(0,0,200,500) ctx.save() ctx.translate(500,100) ctx.rotate(deg2*Math.PI/180) ctx.drawImage(p4,-100,-50) ctx.restore() deg2+=20 },10) } </script> </body> </html>