Canvas vs. SVG
Canvas
- canvas通过JavaScript来绘制2D图像、逐像素进行渲染。如果位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图像覆盖的对象
- 依赖分辨率
- 不支持时间处理器
- 能够以.png或.jpg格式保存结果图像
- 最适合图像密集型的游戏,其中的许多对象会被频繁重绘
- SVG是一种使用XML描述2D图像的语言
- SVG基于XML,意味着SVG DOM中的每个元素都是可用的。可以为某个元素附加JavaScript事假处理器
- 每个被绘制图像均被视为对象。如果SVG对象的属性发生变化,那么浏览器能够自动重现图形。
- 不依赖分辨率
- 支持事件处理器
- 最适合带有大型渲染区域的应用程序(比如谷歌地图)
- 复杂度高会减慢渲染速度
- 不适合游戏应用
绘制矩形
fillRect(x,y,width,height) 绘制一个填充的矩形
strokeRect(x,y,width,height) 绘制一个矩形的边框
clearRect(x,y,width,height)清楚指定矩形区域,让清楚部分完全透明
ctx = myRect.getContext('2d');
ctx.fillStyle="#00CCFF";
ctx.strokeStyle = "#fff";
ctx.lineWidth=5;
ctx.fillRect(10,10,200,150);
ctx.strokeRect(30,30,150,110);
ctx.clearRect(50,50,10,10);
ctx.clearRect(150,50,10,10);
ctx.clearRect(50,110,10,10);
ctx.clearRect(150,110,10,10);
绘制路径
beginPath() 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径
closePath() 闭合路径之后图形绘制命令又重新指向到上下文中
stroke() 通过线条来绘制图形轮廓
fill() 通过填充路径的内容区域生成实心的图形
*第一条构造命令通常是moveTo(),无论最后是什么
一个简单的人物(有点丑)
ctx.fillStyle="#00FFCC";
ctx.beginPath();
ctx.arc(80,90,55,20,Math.PI*2,true);
ctx.moveTo(45,100);
ctx.arc(80,100,35,0,Math.PI,false);
ctx.moveTo(70,80)
ctx.arc(60,80,10,0,Math.PI*2,true);
ctx.moveTo(110,80);
ctx.arc(100,80,10,0,Math.PI*2,true);
ctx.fillRect(45,145,80,100);
ctx.moveTo(45,145);
ctx.lineTo(10,200);
ctx.moveTo(125,145);
ctx.lineTo(155,200);
ctx.moveTo(80,244);
ctx.lineTo(70,330);
ctx.moveTo(90,244);
ctx.lineTo(110,320);
ctx.stroke();
一个简单的奥运五环
cxt = myCanvas.getContext('2d');
cxt.strokeStyle ="#00CCFF";
cxt.lineWidth = 5;
cxt.beginPath();
cxt.arc(80,100,60,60,Math.PI*2,true);
cxt.stroke();
cxt.strokeStyle = "#FFD700";
cxt.lineWidth = 5;
cxt.beginPath();
cxt.arc(155,180,60,60,Math.PI*2,true);
cxt.stroke();
cxt.strokeStyle = "black";
cxt.lineWidth = 5;
cxt.beginPath();
cxt.arc(230,100,60,60,Math.PI*2,true);
cxt.stroke();
cxt.strokeStyle = "green";
cxt.lineWidth = 5;
cxt.beginPath();
cxt.arc(305,180,60,60,Math.PI*2,true);
cxt.stroke();
cxt.strokeStyle = "red";
cxt.lineWidth = 5;
cxt.beginPath();
cxt.arc(380,100,60,60,Math.PI*2,true);
cxt.stroke();
两个三角形
使用填充(filled),路径自动闭合,使用描边(stroked)则不会闭合路径。如果没有添加闭合路径closePath()到描述的三角形函数中,则只会绘制两条线段,并不是一个完整的三角形。
//填充三角形
ctx.fillStyle="#00FFCC";
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,100);
ctx.fill();
//描边三角形
ctx.strokeStyle="green";
ctx.beginPath();
ctx.moveTo(120,50);
ctx.lineTo(180,100);
ctx.lineTo(120,180);
ctx.closePath();
ctx.stroke();
圆弧
arc(x,y,radius,startAngle,endAngle,anticlockwise)
radius =(Math.PI/180)*degrees.
function myRadius(){
for(var i=0;i<7;i++){
for(var j=0;j<7;j++){
ctx.fillStyle="wheat";
ctx.strokeStyle="OliveDrab";
ctx.beginPath();
var x = 20 + 35*i ;
var y = 20 + 35*j ;
var radius = 15;
var startAngle = 0 ;
var endAngle = Math.PI*2;
ctx.arc(x,y,radius,startAngle,endAngle);
if(i%2 ==0){
ctx.fill();
}else{
ctx.stroke();
}
}
}
}
function myAngle(){
for(var i=0; i<5; i++){
for(var j=0; j<5; j++){
ctx.fillStyle="Crimson";
ctx.strokeStyle="PaleVioletRed";
ctx.beginPath();
var x = 400 + 80*i;
var y = 200 + 80*j;
var radius = 40;
var startAngle =0;
var endAngle = Math.PI + (Math.PI*j)/2;
var anticlockwise = i%2==0?false:true;
ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise);
if(j%2==0){
ctx.stroke();
}else{
ctx.fill();
}
}
}
}
function draw(id){
var myCanvas = document.getElementById(id);
if(myCanvas==null){
return false;
}
var ctx = myCanvas.getContext('2d');
ctx.fillStyle="#F0F8FF";
ctx.fillRect(0,0,700,800);
for(var i = 0 ; i <=10; i++){
ctx.beginPath();
ctx.arc(350,i*25,i*10,0,Math.PI*2,true);
ctx.fillStyle="rgba(178,34,34,0.5)";
ctx.closePath();
ctx.fill();
}
}
lineTo
cxt.fillStyle = "#AFEEEE";
cxt.fillRect(0,0,300,400);
var xx = 150;
var yy = 200;
var s =100;
cxt.beginPath();
cxt.fillStyle="#DDA0DD";
cxt.strokeStyle="#EEE8AA";
var dig = Math.PI/15*13;
for( var i=0; i <30; i++){
var x = Math.sin(i*dig);
var y = Math.cos(i*dig);
cxt.lineTo(xx+x*s,yy+y*s);
}
cxt.closePath();
cxt.fill();
cxt.stroke();
贝塞尔(bezier)以及二次贝塞尔
quadraticCurveTo(cp1x,cp1y,x,y); x,y为结束点,cp1x,cp1y为控制点 (二次贝塞尔)
quadraticCurveTo(cp1x,cp1y,cp2x,cp2y,x,y) x,y为结束点,cp1x,cp1y为控制点一,cp2x,cp2y为控制前二( 三次贝塞尔)