HTML绘图支持

<!DOCTYPE html>
<html>
<head>
<title>HTML绘图支持</title>
<meta http-equiv="Content-Type" content="text/html;charset=gbk"/>
</head>
<body>
  <!--一、使用canvas元素
HTML新增了一个canvas元素,专门用于绘制图形,但实际上该元素自身并不绘制图形,只相当于一张空画布,要想画图,必须借助JavaScript脚本进行绘制
向<canvas>元素上画图,需要经过三个步骤:
获取<canvas>元素对应的DOM对象,这是一个Canvas对象;
调用Canvas对象的getContext()方法,返回一个CanvasRenderingContext2D对象;
利用CanvasRenderingContext2D对象的方法画图。
-->

<!--二、绘图
1.canvas绘图基础:CanvasRenderingContext2D
HTML5绘图的组件是Canvas对象,但是绘图的核心API是CanvasRenderingContext2D,他提供了一系列的方法和属性供绘制图形使用
2.绘制几何图形
fillRect:填充一个矩形
strokeRect:绘制一个矩形边框
CanvasRenderingContext2D只提供了这两个绘制几何图形的方法,并没有提供绘制其他几何图形的方法
-->
<canvas id="mc" width="300" height="300" style="border:1px solid black"></canvas>
<script type="text/javascript">
  var canvas=document.getElementById('mc');
  var ctx=canvas.getContext('2d');
 //设置填充颜色
  ctx.fillStyle="#f00";
  //填充一个矩形
  ctx.fillRect(30,20,120,60);
  ctx.fillStyle="#ff0";
  ctx.fillRect(80,60,120,60);

  //设置线条颜色
  ctx.strokeStyle="#00f";
  //设置线条宽度
  ctx.lineWidth=10;
  //绘制矩形边框
  ctx.strokeRect(30,130,120,60);

  ctx.strokeStyle="#0ff";
  //设置链接点类型
  ctx.lineJoin="round";
  ctx.strokeRect(80,160,120,60);

  ctx.strokeStyle="#f0f";
  ctx.lineJoin="bevel";
  ctx.strokeRect(130,190,120,60);
</script>

<!--3.绘制字符串
fillText:填充字符串
strokeText:绘制字符串边框
字体的对齐方式:
textAlign:水平对齐方式
textBaseAlign:垂直对齐方式
-->
<canvas id="zfc" width="400" height="400" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('zfc');
var ctx=canvas.getContext('2d');
ctx.fillStyle='#00f';
ctx.font='italic 50px 隶书';
ctx.textBaseline='top';
ctx.fillText("HTML5",0,0);

ctx.strokeStyle="#f0f";
ctx.font='bold 45px 宋体';
ctx.strokeText("Crazy HTML5",0,50);
</script>

<!--4.设置阴影
shadowBlur:阴影的模糊度
shadowColor:阴影的颜色
shadowOffsetX:阴影在X方向的偏移
shadowOffsetY:阴影在Y方向的偏移
-->
<canvas id="yy" width="500" height="500" style="border:1px solid black"></canvas>
<script type="text/javascript">
   var canvas=document.getElementById('yy');
   var ctx=canvas.getContext('2d');
   ctx.shadowBlur=5.6;
   ctx.shadowColor='#222';
   ctx.shadowOffetX=10;
   ctx.shadowOffY=-6;
   ctx.fillStyle="#00f";
   ctx.font="italic 50px 宋体";
   ctx.textBaseline='top';
   ctx.fillText("Crazy HTML",0,0);

   ctx.strokeStyle="#f0f";
   ctx.font="bold 45px 宋体";
   ctx.strokeText("疯狂Java",0,50);

   ctx.fillStyle="#0ff";
   ctx.fillRect(20,150,180,80);
   ctx.strokeStyle="#ff0";
   ctx.lineWidth=8;
   ctx.strokeRect(300,150,180,80);
</script>

<!--5.使用路径
为了在Canvas上绘制更加复杂的图形,必须在Canvas上启用路径,借助路径来绘制图形
按如下步骤:
调用CanvasRenderingContext2D的beginPath()方法开始定义路径
调用CanvasRenderingContext2D的各种方法添加子路径
调用CanvasRenderingContext2D的closePath()方法关闭路径
调用CanvasRenderingContext2D的fill()或者stroke()方法来填充路径或者绘制路径边框
CanvasRenderingContext2D提供了如下方法添加子路径:
arc(x,y,radius,startAngle,endAngle,counterclockwise(boolean值,true为逆时针)):添加一段弧
arcTo(x1,y1,x2,y2,radius):添加一段弧,确定这段圆弧的方式是假设从当前点到P1(x1,y1)绘制一条线条,再从P1(x1,y1)到P2(x2,y2)绘制一条线条,arcTo()则绘制一段同时与上面两条线条相切,且半径为radius的圆弧
bezierCurveTo:贝济埃曲线
lineTo(x,y):添加一段线段
moveTo(x,y):移动到(x,y)
quadraticCurveTo:二次曲线
rect(x,y,width,height):添加一个矩形
-->
<h2>绘制图形</h2>
<canvas id="yx" width="400" height="300" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('yx');
var ctx=canvas.getContext('2d');
for(var i=0;i<10;i++){
 //开始定义路径
 ctx.beginPath();
 //添加一段圆弧
 ctx.arc(i*25,i*25,(i+1)*8,0,Math.PI*2,true);
 //关闭路径
 ctx.closePath();
 //设置填充色
 ctx.fillStyle='rgba(255,0,255,'+(10-i)*0.1+')';
 //填充路径
 ctx.fill();
 }
</script>
<h2>actTo示例</h2>
<canvas id="at" width="400" height="180" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('at');
var ctx=canvas.getContext('2d');
function createRoundPath(Context,x1,y1,width,height,radius){
    ctx.beginPath();
    ctx.moveTo(x1+radius,y1);

    ctx.lineTo(x1+width-radius,y1);
    ctx.arcTo(x1+width,y1,x1+width,y1+radius,radius);

    ctx.lineTo(x1+width,y1+height-radius);
    ctx.arcTo(x1+width,y1+height,x1+width-radius,y1+height,radius);

    ctx.lineTo(x1+radius,y1+height);
    ctx.arcTo(x1,y1+height,x1,y1+height-radius,radius);

    ctx.lineTo(x1,y1+radius);
    ctx.arcTo(x1,y1,x1+radius,y1,radius);

    ctx.closePath();
 }
 ctx.lineWidth=3;
 createRoundPath(ctx,30,30,200,100,20);
 ctx.stroke();
</script>
 <h1>lineTo</h1>
 <canvas id="lt" width="400" height="200" style="border:1px solid black"></canvas>
 <script type="text/javascript">
 var canvas=document.getElementById('lt');
 var ctx=canvas.getContext('2d');
 function createStar(context ,n ,dx,dy,size){
  context.beginPath();
  var dig=Math.PI/n*4;
  for(var i=0;i<n;i++){
   var x=Math.sin(i*dig);
   var y=Math.cos(i*dig);
   context.lineTo(x*size+dx,y*size+dy);
   }
   context.closePath();
  }
  //绘制三角形
  createStar(ctx,3,60,60,50);
  ctx.fillStyle="#f00";
  ctx.fill();
  //绘制五角形
  createStar(ctx,5,160,60,50);
  ctx.fillStyle="#0f0";
  ctx.fill();
  //绘制七角形
  createStar(ctx,7,260,60,50);
  ctx.fillStyle="#00f";
  ctx.fill();
  //绘制九角形
  createStar(ctx,9,360,60,50);
  ctx.fillStyle="#f0f";
  ctx.fill();
 </script>
 <!---6.绘制曲线
bezierCurveTo:贝济埃曲线
quadraticCurveTo:二次曲线
-->
<canvas id="ct" width="400"height="200" style="border:1px solid black"></canvas>
<script type="text/javascript">
    var canvas=document.getElementById('ct');
 var ctx=canvas.getContext('2d');
 function createFlower(context,n,dx,dy,size,length){
  context.beginPath();
  context.moveTo(dx,dy+size);
  var dig=2*Math.PI/n;
  for(var i=1;i<n+1;i++){
   //计算控制点的坐标
   var ctrlx=Math.sin((i-0.5)*dig)*length+dx;
   var ctrly=Math.cos((i-0.5)*dig)*length+dy;
   //计算结束点的坐标
   var x=Math.sin(i*dig)*size+dx;
   var y=Math.cos(i*dig)*size+dy;
   //绘制二次曲线
   context.quadraticCurveTo(ctrlx,ctrly,x,y);

   }
   context.closePath();
  }
  //绘制5瓣花朵
       createFlower(ctx,5,70,100,30,80);
    ctx.fillStyle="#f00";
    ctx.fill();
    //绘制6瓣花朵
       createFlower(ctx,6,200,100,30,80);
    ctx.fillStyle="#0f0";
    ctx.fill();
    //绘制7瓣花朵
       createFlower(ctx,7,330,100,30,80);
    ctx.fillStyle="#f0f";
    ctx.fill();
</script>
<!--7.绘制位图
drawImage方法
该方法需要传入Image对象,创建Image对象采用如下方法:
Image img = new Image([width,height]);
img.src = "图片地址";
需要指出的是为Image对象的src属性赋值后,Image对象会去装载指定图片,这种装载是异步的,需要一定的时间开销,为保证图片装载完成之后才去绘制,可用如下代码来绘制:
Image img = new Image([width,height]);
img.src = "图片地址";
img.onload = function(){
//在该函数里绘制
}
--->
<hr/>
<h2>绘制位图</h2>
<canvas id="wt" width="650" height="380" style="border:1px solid black;"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('wt');
var ctx=canvas.getContext('2d');
var img=new Image();
img.src="imgs/1.jpg";
img.οnlοad=function(){
 //原始尺寸 参数x,y
 ctx.drawImage(img,20,70);
 //绘制图片时进行缩放 参数x,y 缩放的 w,h
 ctx.drawImage(img,320,10,120,150);
 //从原位图挖一块放大3倍绘制在Canvas上
 var sd=50;
 var sh=65;
 ctx.drawImage(img,2,50,sd,sh,460,10,sd*3,sh*3);
 }
</script>

<!--三、图形特效处理
1.使用坐标变换
translate:平移坐标系统
scale:缩放坐标系统(水平方向上缩放sx,垂直方向上缩放sy)
totate:旋转坐标系统
还提供了save和restore方法,避免多次坐标变换后累加结果
需要指出的是save方法保存的绘图状态,不仅包括当前系统的坐标状态,还包括填充风格、线条风格等各种绘图状态,但是不包括Canvas上绘制的图形
-->
<h2>坐标变换</h2>
<canvas id="zbhh" width="650" height="380" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('zbhh');
var ctx=canvas.getContext('2d');
ctx.fillStyle='rgba(255,0,0,0.3)';
ctx.translate(100,200);
for(var i=0;i<50;i++){
 ctx.translate(50,50);
 ctx.scale(0.93,0.93);
 ctx.rotate(-Math.PI/10);
 ctx.fillRect(0,0,150,75);
 }
</script>

<!--2.坐标变换与路径结合使用
雪花飘飘的动态效果:
-->
<h2>雪花飘飘</h2>
<canvas id="show" width="420" height="280" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById("show");
var ctx=canvas.getContext('2d');
setInterval("fall(ctx);",200);
snowPos=[
{x:20,y:4},
{x:60,y:4},
{x:100,y:4},
{x:140,y:4},
{x:180,y:4},
{x:220,y:4},
{x:260,y:4},
{x:300,y:4},
{x:340,y:4},
{x:380,y:4}
];
function createFlower(context,n,dx,dy,size,length){
 context.beginPath();
 context.moveTo(dx,dy+size);
 var dig=2*Math.PI/n;
 for(var i=1;i<n+1;i++){
       //计算控制点的坐标
    var ctrlx=Math.sin((i-0.5)*dig)*length+dx;
    var ctrly=Math.cos((i-0.5)*dig)*length+dy;
    //计算结束点的坐标
    var x=Math.sin(i*dig)*size+dx;
    var y=Math.cos(i*dig)*size+dy;
    //绘制二次曲线
    context.quadraticCurveTo(ctrlx,ctrly,x,y);
  }
  context.closePath();
 }
function fall(context){
 context.fillStyle="#000";
 context.fillRect(0,0,420,280);
 context.fillStyle="#fff";
 for(var i=0;i<snowPos.length;i++){
  //保存当前绘图状态
  context.save();
  context.translate(snowPos[i].x,snowPos[i].y);
  context.rotate((Math.random()*6-3)*Math.PI/10);
  //控制雪花掉落
  snowPos[i].y+=Math.random()*8;
  if(snowPos[i].y>280){
   snowPos[i].y=4;
   }
  //创建并绘制雪花
  createFlower(context,6,0,0,5,8);
  context.fill();
  //恢复绘图状态
  context.restore();
 }
 }
</script>
<!--3.使用矩阵变换
CanvasRenderingContext2D提供了一种更加通用的坐标变换方法:
transform(m11,m12,m21,m22,dx,dy)这是一个基于矩阵变换的方法,前面三个变换方法都可以通过transform来实现,只是比较复杂
{x,y}----{x*m11+y*m21+dx,x*m12+y*m22+dy}
实现自定义变换---倾斜变换:
对于倾斜变换而言,Y坐标无需变换,只要将X坐标横向移动tan(angle)*Y即可,这就是实现倾斜变换的理论基础
 
四.控制叠加风格
通过CanvasRenderingContext2D的globalCompositeOperation属性来实现
-->
<p></p>
<h2>叠加风格</h2>
<select style="width:160px;" onChange="draw(this.value);">
<option value="source-over" selected="selected">source-over</option>
<option value="source-in">source-in</option>
<option value="source-out">source-out</option>
<option value="source-atop">source-atop</option>
<option value="destination-over">destination-over</option>
<option value="destination-in">destination-in</option>
<option value="destination-out">destination-out</option>
<option value="destination-atop">destination-atop</option>
<option value="lighter">lighter</option>
<option value="xor">xor</option>
<option value="copy">copy</option>
</select><br/>
<canvas id="dj" width="400" height="200" style="border:1px solid black;"></canvas>
<script type="text/javascript">
  var canvas=document.getElementById('dj');
  var ctx=canvas.getContext('2d');
  var draw=function(coma){
   ctx.save();
   ctx.clearRect(0,0,400,200);
   ctx.fillStyle="#f00";
   ctx.fillRect(30,20,160,100);
   ctx.globalCompositeOperation=coma;
   ctx.fillStyle="#0f0";
   ctx.fillRect(120,60,160,100);
   ctx.restore();
   }
</script>
<!--五.控制填充风格
除了fillStyle,CanvasRenderingContext2D还支持渐变填充(CanvasGradient)和位图填充(CanvasPattern)
1.线性渐变
调用CanvasRenderingContext2D的createLinearGradient方法创建一个线性渐变,返回一个CanvasGradient对象;
调用CanvasGradient对象的addColorStop方法向线性渐变中添加颜色变化;
将CanvasGradient对象赋给CanvasRenderingContext2D的fillStyle或strokeStyle属性。
-->
<canvas id="xj" width="400" height="300" style="border:1px solid black;"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('xj');
var ctx=canvas.getContext('2d');
ctx.clearRect(0,0,400,280);
ctx.save();
ctx.translate(30,20);
//创建线性渐变
var lg=ctx.createLinearGradient(0,0,160,80);
//向线性渐变中添加颜色
lg.addColorStop(0.2,"#f00");
lg.addColorStop(0.5,"#0f0");
lg.addColorStop(0.9,"#00f");
//使用线性渐变作为填充色
ctx.fllStyle=lg;
ctx.fillRect(0,0,160,80);
ctx.restore();
//平移坐标系统
ctx.translate(280,160);
ctx.beginPath();
ctx.arc(0,0,80,0,Math.PI*2,true);
ctx.closePath();
ctx.lineWidth=12;
//再次创建线性渐变
var lg2=ctx.createLinearGradient(-40,-40,80,50);
lg2.addColorStop(0.1,"#ff0");
lg2.addColorStop(0.4,"#0ff");
lg2.addColorStop(0.8,"#f0f");
ctx.strokeStyle=lg2;
ctx.stroke();
</script>

 

<!--2.圆形渐变
createRadialGradient
-->
<hr/>
<h2>圓形漸變</h2>
<canvas id="yj" width="400" height="280" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('yj');
var ctx=canvas.getContext('2d');
ctx.save();
ctx.translate(30,20);
//创建圆形渐变
var lg=ctx.createRadialGradient(80,40,5,80,40,60);
//向线性渐变中添加颜色
lg.addColorStop(0.2,"#f00");
lg.addColorStop(0.5,"#0f0");
lg.addColorStop(0.9,"#00f");
//使用线性渐变作为填充色
ctx.fillStyle=lg;
ctx.fillRect(0,0,160,80);
ctx.restore();
//平移坐标系统
ctx.translate(280,160);
ctx.beginPath();
ctx.arc(0,0,80,0,Math.PI*2,true);
ctx.closePath();
ctx.lineWidth=12;
//再次创建线性渐变
lg2=ctx.createRadialGradient(0,0,5,0,0,80);
lg2.addColorStop(0.1,"#f00");
lg2.addColorStop(0.4,"#0ff");
lg2.addColorStop(0.8,"#f0f");
ctx.fillStyle=lg2;
ctx.fill();
</script>
<!--3.位图填充
createPattern
-->
<hr/>
<h2>位图填充</h2>
<canvas id="wttc" width="400" height="280" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('wttc');
var ctx=canvas.getContext('2d');
ctx.save();
ctx.translate(30,20);
var img=new Image();
img.src="imgs/1.jpg";
img.οnlοad=function(){
 var imgPattern=ctx.createPattern(img,"repeat");
 ctx.fillStyle=imgPattern;
 ctx.fillRect(0,0,160,100);
 ctx.restore();
 ctx.translate(280,160);
 ctx.beginPath();
 ctx.arc(0,0,80,0,Math.PI*2,true);
 ctx.closePath();
 ctx.lineWidth=12;
 ctx.strokeStyle=imgPattern;
 ctx.stroke();
 }
</script>

<!--六、位图处理
1.位图裁剪
clip这个方法会把位图当前路径裁剪下来:
将要裁剪的部分定义成Canvas路径;
调用CanvasRenderingContext2D的clip方法把路径裁剪下来;
绘制位图---被裁剪部分才会显示。
-->
<h2>位图裁剪</h2>
<canvas id="wtcj" width="400" height="350" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('wtcj');
var ctx=canvas.getContext('2d');
var dig=Math.PI/20;
var count=0;
var img=new Image();
img.src="imgs/1.jpg";
img.οnlοad=function(){
 //每隔0.15秒调用一次addRadial函数
 setInterval("addRadial()",150);
 }
 var addRadial=function(){
  ctx.save();
  ctx.beginPath();
  ctx.arc(200,130,200,0,dig*++count,false);
  //让圆弧连接到圆形
  ctx.lineTo(200,130);
  ctx.closePath();
  ctx.clip();
  //此时绘制的图片只有路径覆盖的部分才会显示出来
  ctx.drawImage(img,124,20);
  ctx.restore();
  }
</script>


<!--2.像素处理
getImageData(int x,int y,int width,int height):该方法获取从Canvas上从(x,y)点开始,宽为width,高为height的图片区域的数据,该方法返回值是一个CanvasPixelArray对象(包含width、height、data属性,data[r1,g1,b1,a1,r2,g2,b2,a2,...,rN,gN,bN,aN],每四个元素确定一个像素点)
putImageData(CanvasPixelArray data,x,y):把data里的数据放入Canvas中从(x,y)开始的区域,该方法直接改变Canvas上的图像数据
通过以上两种像素处理方法,可以对图片进行各种复杂的处理,例如改变图片透明度、高亮、剪切、复制等;如果配合一些算法理论,甚至可以对图片进行模糊、降噪等复杂的滤波处理。
-->
<h2>像素处理</h2>
<canvas id="xscl" width="400" height="350" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('xscl');
var ctx=canvas.getContext('2d');
var img=new Image();
img.src="imgs/1.jpg";
img.οnlοad=function(){
 //带透明度参数的方法绘制图片
 drawImage(img,124,20,0.4);
 }
 var drawImage=function(image,x,y,alpha){
  ctx.drawImage(image,x,y);
  var imgData=ctx.getImageData(x,y,image.width,image.height);
  for(var i=0,len=imgData.data.length;i<len;i+=4){
  imgData.data[i+3]=imgData.data[i+3]*alpha;
  }
      ctx.putImageData(imgData,x,y);
  }
</script>

<!--2)高亮画图:
所谓高亮就是把图片像素的R、G、B值都按比例放大
-->
<h2>高亮显示</h2>
<canvas id="xsgl" width="400" height="350" style="border:1px solid black"></canvas>
<script type="text/javascript">
var canvas=document.getElementById('xsgl');
var ctx=canvas.getContext('2d');
var img=new Image();
img.src="imgs/1.jpg";
img.οnlοad=function(){
 drawImage(img,124,20,1.6);
 }
 var drawImage=function(image,x,y,ligth){
  ctx.drawImage(image,x,y);
  var imgData=ctx.getImageData(x,y,image.width,image.height);
  for(var i=0,len=imgData.data.length;i<len;i+=4){
   imgData.data[i+0]=imgData.data[i+0]*ligth;
   imgData.data[i+1]=imgData.data[i+1]*ligth;
   imgData.data[i+2]=imgData.data[i+2]*ligth;
   }
  ctx.putImageData(imgData,x,y);
  }
</script>

<!--七、输出位图
toDataURL(String type):type是MIME字符串
DataURL格式是一种保存二进制文件的方式,我们既可把图片转换为DataURL格式的字符串,也可把DataURL格式的字符串恢复成原来的文件
-->
<h2>位图输出</h2>
<canvas id="wtsc" width="400" height="280" style="border:1px solid black"></canvas>
<img src="" id="result" alt="图片输出"/>
<script type="text/javascript">
var canvas=document.getElementById('wtsc');
var ctx=canvas.getContext('2d');
ctx.save();
ctx.translate(30,20);
var img=new Image();
img.src="imgs/1.jpg";
img.οnlοad=function(){
 //创建位图填充
 imgPattern=ctx.createPattern(img,"repeat");
 ctx.fillStyle=imgPattern;
 ctx.fillRect(0,0,160,80);
 ctx.restore();
 ctx.translate(280,160);
 ctx.beginPath();
 ctx.arc(0,0,80,0,Math.PI82,true);
 ctx.closePath();
 ctx.lineWidth=12;
 ctx.strokeStyle=imgPattern;
 ctx.stroke();
 document.getElementById('result').src=canvas.toDataURL("image/png");
 }
</script>
<!--实际上,Canvas可以把图片转换成DataURL格式的字符串,这个字符串既可以通过网络传输,也可以保存到磁盘、数据库中,这样就可以永久保存使用Canvas绘制的图片了-->
</body>
</html>

转载于:https://my.oschina.net/u/573470/blog/135241

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值