<canvas>
个人认为<canvas>是h5最重量级的新标签了,现在各种h5小游戏都是基于<canvas>的,它为游戏提供了一个功能强大的画布,可在画布上绘制丰富的内容,同时也催生出很多游戏引擎。现在就简单介绍一下<canvas>的一些基本绘图和图片处理功能:
1.绘制线条
绘图的基本步骤是:先用getContext("2d")获取二维绘图环境上下文,有二维那肯定也有三位了?是的,三维就要用到WebGL了,技术水平有限,今天就不讨论三维了(三围肿么这么耳熟~~!)。然后设置画笔样式,lineWidth画笔宽度,strokeStyle画笔颜色,lineCap线头样式。样式设置完毕后就开始绘图了,首先用moveTo()把一个看不到的光标移动到起点位置,然后lineTo()设定重点,最后stroke()画出线条。
<!DOCTYPE HTML> <html> <head> <meta charset = "utf-8"> <title>绘制线条</title> <style> body,div{margin:0px;padding:0px;text-align:center} #canv{ border:2px solid black; border-radius:4px; box-shadow:0px 0px 10px black; -webkit-box-shadow:0px 0px 10px black; -moz-box-shadow:0px 0px 10px black; } </style> </head> <body> <h1>绘制线条</h1> <canvas id="canv" width="400px" height="300px"> 你若能看到这句话说明你浏览器不支持canvas! </canvas> </body> <script type="text/javascript"> var canv = document.getElementById("canv"); //获取2d上下文 var ctx = canv.getContext("2d"); //设置样式 ctx.lineWidth = 40; ctx.strokeStyle = "red"; ctx.lineCap = "round"; //butt ,square,round ctx.beginPath(); //设置起始点 ctx.moveTo(20,20); ctx.lineTo(200,200); //开始绘制定义好的路径 ctx.stroke(); </script> </html>
2.绘制矩形
矩形的绘制步骤同上所述,但有两种绘制类型:实心矩形fillRect(起点x,起点y,长,宽),空心矩形strokeRect(起点x,起点y,长,宽)。
var canv = document.getElementById("canv"); //获取2d上下文 var ctx = canv.getContext("2d"); //设置样式 ctx.lineWidth = 10; ctx.strokeStyle = "red"; //绘制实心矩形 ctx.fillStyle="red"; ctx.fillRect(10,10,100,100);
3.绘制圆形
同样,也分实心和空心,主要用到arc(圆心x,圆心y,半径,其实角度,结束角度*Math.PI/180,顺逆时针);
var canv = document.getElementById("canv"); //获取2d上下文 var ctx = canv.getContext("2d"); //设置样式 ctx.lineWidth = 10; ctx.strokeStyle = "red"; /* ctx.beginPath(); //中心点,半径,始末角度,顺逆时针 ctx.arc(200,200,50,0,270*Math.PI/180,false); ctx.stroke(); */ //实心 ctx.fillStyle = "red"; ctx.beginPath(); ctx.arc(200,200,50,0,270*Math.PI/180,false); ctx.fill();
4.擦除
能破就能立,能绘制就能擦除,用clearRect(起点x,起点y,擦出范围长,擦出范围宽)实现擦除。
//设置样式 ctx.lineWidth = 10; ctx.fillStyle = "red"; //绘制矩形 ctx.fillRect(10,10,200,100); //擦除 ctx.clearRect(30,30,100,50);
5.渐变
可实现两种渐变方式:线性渐变createLinearGradient(),径向渐变createRadialGradient()。
var canv = document.getElementById("canv"); //获取2d上下文 var ctx = canv.getContext("2d"); //径向渐变 var grd=ctx.createRadialGradient(100,100,10,100,100,50); grd.addColorStop(0.1,"red"); grd.addColorStop(0.8,"blue"); ctx.fillStyle=grd; ctx.fillRect(0,0,200,200); /* //线性渐变 var grd=ctx.createLinearGradient(0,0,200,0); grd.addColorStop(0.2,"red");//必须0-1之间的数,代表颜色的渐变权重 grd.addColorStop(0.7,"blue"); ctx.fillStyle=grd; ctx.fillRect(0,0,200,200); */
6.像素处理:黑白处理,反色处理
原理:先把要处理的图片读取到canvas上,然后遍历每个像素点,更改像素的rgb值即可。
黑白处理:
反色处理:
<body> <h1>像素处理</h1> <img src = "logo.png" id="logo" /> <canvas id="canv" width="800px" height="800px"> 你若能看到这句话说明你浏览器不支持canvas! </canvas> </body> <script type="text/javascript"> var canv = document.getElementById("canv"); //获取2d上下文 var ctx = canv.getContext("2d"); var image = new Image(); image.src = "01.jpg"; image.onload = function(){ ctx.drawImage(image,0,0); var imgdata = ctx.getImageData(0,0,250,250); var pixels = imgdata.data; /* // 遍历每个像素并对 RGB 值进行取反 for (var i=0, n=pixels.length; i<n; i+= 4){ pixels[i] = 255-pixels[i]; //r pixels[i+1] = 255-pixels[i+1]; //g pixels[i+2] = 255-pixels[i+2]; //b } */ // 遍历每个像素并更改 RGB 值 for (var i=0, n=pixels.length; i<n; i+= 4){ var grayscale = pixels[i]*.3+pixels[i+1]*.59+pixels[i+2]*.11; //灰度处理 pixels[i ] = grayscale; // r pixels[i+1] = grayscale; // g pixels[i+2] = grayscale; // b } // 在指定位置进行像素重绘 ctx.putImageData(imgdata, 250, 0); }; </script>
7.小动画
动画原理:先绘制一张图片drawImage(img,x,y,80,80);时刻更改图片的坐标x,y来使图片不断移动。
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>动画</title> </head> <body> <canvas id="cav" width="500" height="500" style="background:gray;"></canvas> <input type="button" value="stop" onclick="stop()"> <script> // 设置绘图环境 var cav = document.getElementById("cav"); var cxt=cav.getContext('2d'); //初始位置 var x=5; var y=5; // 创建绘图对象,并且画出来 var img =new Image(); img.src="logo.png"; draw(); function draw() { //清除上一帧动画 cxt.clearRect(0,0,500,500); //十分重要 x+=5; y+=5; cxt.drawImage(img,x,y,80,80); } //设定动画,时间间隔100毫秒 var time = setInterval(draw,100); function stop(){ clearInterval(time); } </script> </body> </html>
倘若我们不清除上一次绘制的结果效果会怎样呢?那就注释掉cxt.clearRect(0,0,500,500);试一试。
function draw() { //清除上一帧动画 //注释掉啦 cxt.clearRect(0,0,500,500); //十分重要 x+=5; y+=5; cxt.drawImage(img,x,y,80,80); }
效果将连续出现一叠绘制的图片:
8.拖拽原理+canvas实现简易画板
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"/> <style> #canvas{cursor:default;} #red{background:red; 30px;height: 27px} #blue{background:blue; 30px;height: 27px} #yellow{background:yellow; 30px;height: 27px} #white{background:white; 30px;height: 27px} #zi{background:#8B026B; 30px;height: 27px} </style> </head> <body> <canvas id="canvas" width="600" height="400"> </canvas> <br><label>画笔颜色:</label> <input type="button" id="red" onclick="linecolor='red'"> <input type="button" id="blue" onclick="linecolor='blue'"> <input type="button" id="yellow" onclick="linecolor='yellow'"> <input type="button" id="white" onclick="linecolor='white'"> <input type="button" id="zi" onclick="linecolor='#8B026B'"> <label>画笔宽度:</label> <select id="sel"> <option value="4">4</option> <option value="8">8</option> <option value="16">16</option> <option value="30">30</option> </select> <input type="button" value="生成图片" onclick="toImg()"><br> <img id="image" src="" width="500px" height="200px"> <script type="text/javascript"> //下拉画笔宽度 window.onload=function(){ var huabi=document.getElementById("sel"); huabi.onchange=function(){ linw=huabi.value; }; //linw=huabi; }; var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); //画一个黑色矩形 ctx.fillStyle="#002200"; ctx.fillRect(0,0,600,400); //按下标记 var onoff=false; var oldx=-10; var oldy=-10; //设置颜色默认为白色 var linecolor="white"; //画笔宽度 var linw=5; //鼠标移动事件,事件绑定 canvas.addEventListener("mousedown",down,false); canvas.addEventListener("mousemove",draw,true); canvas.addEventListener("mouseup",up,false); function down(event){ onoff=true; oldx=event.pageX; oldy=event.pageY; } function up(){ onoff=false; } function draw(event){ if(onoff==true) { var newx=event.pageX; var newy=event.pageY; ctx.beginPath(); ctx.moveTo(oldx,oldy); ctx.lineTo(newx,newy); ctx.strokeStyle=linecolor; ctx.lineWidth=linw; ctx.lineCap="round"; ctx.stroke(); oldx=newx; oldy=newy; } } function toImg(){ document.getElementById("image").src=canvas.toDataURL("image/jpg"); } </script> </body> </html>
效果:
内容很基础,各位见笑啦。