创建canvas
<canvas id="mycanvas" class="canvas"> 您的浏览器不支持canvas </canvas>
基础设置
<script type="text/javascript"> var canvas = document.getelementbyid('mycanvas'); var ctx = canvas.getcontext('2d'); canvas.width=100; canvas.height=100; </script>
画直线
moveto(x1, y1)
lineto(x2, y2)
ctx.moveto(0, 0); ctx.lineto(100, 100); ctx.stroke();
画圆形
ctx.arc(x,y,radius,0,2*math.pi,true)
ctx.beginpath(); ctx.arc(300,300,50,0,2*math.pi,true); ctx.strokestyle = '#000'; ctx.stroke();
画矩形
ctx.strokerect(x1, y1,x2, y2)
ctx.strokerect(300,100,200,100);
beginpath()开始一条新路径
closepath()使当前路径闭合
不是成对出现的
ctx.beginpath(); ctx.moveto(300, 0); ctx.lineto(200, 100); ctx.lineto(200, 200); ctx.closepath(); ctx.strokestyle = '#0f0'; ctx.stroke();
设置样式
ctx.moveto(0,0); ctx.lineto(100,100); ctx.lineto(100,200); ctx.closepath(); //linewidth 设置描边的线宽 ctx.linewidth = 10; //strokestyle 设置描边样式 ctx.strokestyle = "#f00"; ctx.stroke(); //fillstyle 设置填充样式 ctx.fillstyle = "rgba(0,255,0,0.5)"; ctx.fill();
绘制矩形与样式同步
ctx.strokerect(100,200,100,100); ctx.fillrect(100,200,100,100);
保存和恢复上下文环境,一般成对出现
save 保存当前绘画环境,包括变换和样式
restore 恢复当前绘画环境,包括变换和样式
ctx.save(); ctx.restore();
图形变换
//translate 平移变换 ctx.translate(0,100); ctx.beginpath(); ctx.moveto(0,0); ctx.lineto(100,100); ctx.stroke(); //rotate 旋转变换 ctx.rotate(math.pi/4); ctx.beginpath(); ctx.moveto(0,0); ctx.lineto(100,100); ctx.linewidth = 5; ctx.strokestyle = "#f00"; ctx.stroke(); //scale 缩放变换 ctx.scale(1,0.5); ctx.fillrect(0,-100,100,100);
线性渐变
var lineargradient = ctx.createlineargradient(0, 0, 200, 0); //给渐变添加颜色 lineargradient.addcolorstop(0, 'rgb(255,0,0)'); lineargradient.addcolorstop(0.3, 'rgb(0,255,0)'); lineargradient.addcolorstop(1, 'rgb(0,0,255)'); //设置渐变作为样式 ctx.fillstyle = lineargradient; ctx.fillrect(0, 0, 200, 200);
径向渐变
var radialgradient = ctx.createradialgradient(400, 50, 0, 400, 150, 100); radialgradient.addcolorstop(0, 'rgb(255,255,0)'); radialgradient.addcolorstop(1, 'rgb(0,0,0)'); ctx.fillstyle = radialgradient; ctx.beginpath(); ctx.arc(400, 150, 100, 0, math.pi * 2, true); ctx.fill();
文字
字体若设置了居中,圆心会在文字的中间位置,所以圆心还是要根据画布大小和文字的宽度进行设置。
var str = "hello world"; //设置文本样式,比如大小,字体 ctx.font = "50px sans-serif"; //水平对其设置,left center right ctx.textalign = "center"; //垂直对齐设置,top middle bottom ctx.textbaseline = "top"; //填充文本 ctx.filltext(str,300,0); //描边文本 ctx.stroketext(str,0,200); //获取文本宽度 var width = ctx.measuretext(str).width; console.log(width);
图片
ctx.fillrect(0, 0, canvas.width, canvas.height); var img = new image(); img.src = "logo.png"; //一定要在图像加载完成后的回调中绘制图像 img.onload = function () { //在(0,0)点处绘制img图像 // ctx.drawimage(img, 0, 0); //在(0,0)点处绘制img图像,缩放成256*80 // ctx.drawimage(img, 0, 0, 256, 80); //获取img图像的(0,0)点处的40*40区域,绘制在(100,100)点处,缩放成80*80 ctx.drawimage(img, 0, 0, 40, 40, 100, 100, 80, 80); }
创建图像画刷ctx.createpattern(image, type)
ctx.fillrect(0, 0, canvas.width, canvas.height); var img = new image(); img.src = "logo.png"; img.onload = function () { //创建图像画刷,no-repeat,repeat-x,repeat-y,repeat var pattern = ctx.createpattern(img, "repeat"); ctx.fillstyle = pattern; ctx.fillrect(0, 0, canvas.width, canvas.height); }
阴影绘制
//阴影的x偏移 ctx.shadowoffsetx = 10; //阴影的y偏移 ctx.shadowoffsety = 10; //阴影的颜色 ctx.shadowcolor = 'rgba(0, 0, 0, 0.5)'; //阴影的模糊度 ctx.shadowblur = 10; ctx.fillstyle = 'rgba(255, 0, 0, 0.5)'; ctx.fillrect(100, 100, 100, 100); ctx.font = "50px sans-serif"; ctx.filltext("我是小可爱",200,100);
区域剪辑
//保存当前环境 ctx.save(); ctx.arc(300, 100, 200, 0, math.pi*2, true); //进行区域剪辑 ctx.clip(); ctx.fillstyle = "#f00"; ctx.fillrect(100, 100, 200, 200); //恢复环境,释放了剪辑区域的作用 ctx.restore();
绘制曲线ctx.arc(x, y, startangle, endangle ,math.pi*2, true)
最后一个参数代表是否是逆时针方向
//绘制圆弧 ctx.arc(100, 100, 50, 0 ,math.pi*2, true); ctx.fill(); //二次样条曲线ctx.quadraticcurveto(qcpx,qcpy,qx,qy) ctx.beginpath(); ctx.moveto(100,355); ctx.quadraticcurveto(265,145,380,349); ctx.fill(); //贝塞尔曲线ctx.beziercurveto(cp1x,cp1y,cp2x,cp2y,x,y) ctx.beginpath(); ctx.moveto(175,375); ctx.beziercurveto(297,182,468,252,517,380); ctx.fill();
canvas绘制曲线生成工具
两次贝塞尔曲线:
http://blogs.sitepointstatic.com/examples/tech/canvas-curves/quadratic-curve.html
三次贝塞尔曲线:
http://blogs.sitepointstatic.com/examples/tech/canvas-curves/bezier-curve.html
动画
ctx.clearrect(x, y, width, height) 清除区域,用于重新绘制
var canvas = document.getelementbyid('mycanvas'); var ctx = canvas.getcontext('2d'); var posx = 0, posy = 0, dir = 1, ismouseinrect = false; // 确定动画范围 canvas.onmousemove = function(e){ var mousex = e.offsetx; var mousey = e.offsety; if(mousex > posx && mousey <posx +50 && mousey > posy && mousey < posy+ 50){ ismouseinrect = true; }else{ ismouseinrect = false; } } // 开始动画 setinterval(function() { if(!ismouseinrect){ posx += 10 * dir; } //clearrect清空画布的一个矩形区域 ctx.clearrect(0, 0, canvas.width, canvas.height); ctx.fillrect(posx, posy, 50, 50); if(posx + 50 >= canvas.width){ dir = -1; }else if(posx <= 0){ dir = 1; } },100);
离屏技术
把canvas(sx,sy)处宽sw,高sy的区域,绘制到(dx,dy)处,并缩放为宽dx,高dh
ctx.drawimage(canvas,sx,sy,sw,sh,dx,dy,dw,dh)
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>canvas</title> <style type="text/css"> canvas { border: 1px solid red; } #offcanvas{ display: none; } </style> </head> <body> <canvas id="mycanvas" width="600px" height="400px"> 您的浏览器不支持canvas </canvas> <!--创建离屏canvas--> <canvas id="offcanvas" width="600px" height="400px"> 您的浏览器不支持canvas </canvas> <script type="text/javascript"> var canvas = document.getelementbyid('mycanvas'); var ctx = canvas.getcontext('2d'); var offcanvas = document.getelementbyid('offcanvas'); var offctx = offcanvas.getcontext('2d'); var posx = 0, posy = 0, dir = 1, ismouseinrect = false; //把一些复杂的绘画操作,画在离屏canvas上面 var drawalot = function(){ for(var k=0; k<20; k++){ for(var i=0;i<canvas.width;i+=10){ for(var j=0;j<canvas.height;j+=10){ offctx.beginpath(); offctx.arc(i,j,5,0,2*math.pi,true); offctx.stroke(); } } } } canvas.onmousemove = function(e){ var mousex = e.offsetx; var mousey = e.offsety; if(mousex > posx && mousey <posx +50 && mousey > posy && mousey < posy + 50){ ismouseinrect = true; }else{ ismouseinrect = false; } } setinterval(function() { if(!ismouseinrect){ posx += 10 * dir; } //clearrect清空画布的一个矩形区域 ctx.clearrect(0, 0, canvas.width, canvas.height); // drawalot(); //真正要用到复杂的绘画的时候,直接从离屏canvas上拷贝过来 ctx.drawimage(offcanvas,0,0,offcanvas.width, offcanvas.height,0,0, canvas.width, canvas.height); ctx.fillrect(posx, posy, 50, 50); if(posx + 50 >= canvas.width){ dir = -1; }else if(posx <= 0){ dir = 1; } },100); drawalot(); </script> </body> </html>
案例:电子名片生成器
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>电子名片生成器</title> <link href="style/style.css" rel="stylesheet" /> </head> <body> <div class="left-div"> <div class="line"> <input id="name" type="text" placeholder="姓名"/> </div> <div class="line"> <input id="address" type="text" placeholder="地址"/> </div> <div class="line"> <input id="job" type="text" placeholder="职业"/> </div> <div class="line"> <input id="slogan" type="text" placeholder="口号" /> </div> <div class="line"> <button id="generatebtn">生成名片</button> </div> </div> <div class="right-div"> <canvas id="cardcanvas"> 您的浏览器不支持canvas,请升级浏览器 </canvas> <canvas id="animcanvas"> 您的浏览器不支持canvas,请升级浏览器 </canvas> </div> <script src="script/main.js"></script> </body> </html>
style.css
* { margin: 0; padding: 0; } html, body { height: 100%; } .left-div { width: 30%; height: 100%; float: left; background: #a4a296; } .line { text-align: center; margin-top: 30px; } .line:first-child { margin-top: 200px; } .line span { color: white; } .line input { width: 300px; height: 30px; border-radius: 15px; padding-left: 15px; outline: none; border: none; } .line button { width: 100px; height: 30px; outline: none; border: none; background: #222; color: #ddd; cursor: pointer; position: relative; border-radius: 15px; } .line button:hover { background: #000; color: #fff; } .line button:active { left: 1px; top: 1px; } .right-div { width: 70%; height: 100%; float: left; background: #eee9d3; text-align: center; position: relative; } .right-div canvas { position: absolute; top: 200px; left: 50%; margin-left: -300px; } #cardcanvas { display: none; }
main.js
// 创建和设置cardcanvas,该canvas作为离屏canvas var cardcanvas = document.getelementbyid('cardcanvas'); var cardctx = cardcanvas.getcontext('2d'); cardctx.canvas.width = 600; cardctx.canvas.height = 100; // 加载图片 var img = new image(); img.src = "images/logo.png"; img.onload = function() { cardctx.drawimage(img, 10, 10); } var generatebtn = document.getelementbyid("generatebtn"); generatebtn.onclick = function() { cardctx.clearrect(0, 0, cardctx.canvas.width, cardctx.canvas.height); // 背景的线性渐变 var lineargradient = cardctx.createlineargradient(0, 0, cardctx.canvas.width, cardctx.canvas.height); lineargradient.addcolorstop(0.5, 'rgb(0,0,0)'); lineargradient.addcolorstop(1, 'rgb(133,133,133)'); cardctx.fillstyle = lineargradient; cardctx.fillrect(0, 0, cardctx.canvas.width, cardctx.canvas.height); // logo图像 cardctx.drawimage(img, 10, 10); // 获取姓名、地址、职业,绘制,并计算长度 var name = document.getelementbyid("name").value || "请输入姓名"; var address = document.getelementbyid("address").value || "请输入地址"; var job = document.getelementbyid("job").value || "请输入职业"; var namewidth, addresswidth, jobwidth, maxwidth = 0; cardctx.font = "bold 30px sans-serif"; cardctx.fillstyle = "#fff"; cardctx.filltext(name, 105, 35); namewidth = cardctx.measuretext(name).width; cardctx.font = "bold 20px sans-serif"; cardctx.filltext(address, 105, 60); cardctx.filltext(job, 105, 85); addresswidth = cardctx.measuretext(address).width; jobwidth = cardctx.measuretext(job).width; if(maxwidth < namewidth) { maxwidth = namewidth; } if(maxwidth < addresswidth) { maxwidth = addresswidth; } if(maxwidth < jobwidth) { maxwidth = jobwidth; } // 绘制口号 var slogan = document.getelementbyid("slogan").value || "请输入口号"; cardctx.save(); // 做图形变换 cardctx.rotate(-0.1); cardctx.translate(0, 50); // 阴影 cardctx.shadowoffsetx = 10; cardctx.shadowoffsety = 10; cardctx.shadowcolor = 'rgba(0, 0, 0, 0.5)'; cardctx.shadowblur = 1.5; cardctx.fillstyle = "#ddd"; // 计算口号位置 var solganwidth; solganwidth = cardctx.measuretext(slogan).width; var offset = (cardctx.canvas.width - 115 - maxwidth - solganwidth) / 2; cardctx.filltext(slogan, 115 + maxwidth + offset, 50); // 画曲线 cardctx.beginpath(); cardctx.moveto(115 + maxwidth + offset, 70); cardctx.quadraticcurveto(115 + maxwidth + offset, 50, 115 + solganwidth + maxwidth + offset, 60); cardctx.strokestyle = "#ddd"; cardctx.stroke(); cardctx.restore(); } // 触发click事件 generatebtn.click(); // 创建和设置animcanvas,该canvas才是真正的显示 var animcanvas = document.getelementbyid('animcanvas'); var animctx = animcanvas.getcontext('2d'); animctx.canvas.width = 600; animctx.canvas.height = 100; var circles = []; setinterval(function() { // 擦出画布 animctx.clearrect(0, 0, animctx.canvas.width, animctx.canvas.height); // 把离屏canvas的内容画进来 animctx.drawimage(cardcanvas, 0, 0, animctx.canvas.width, animctx.canvas.height, 0, 0, cardctx.canvas.width, cardctx.canvas.height); // 绘制下落的圆形 for(var i=0; i<=10; i++) { if(!circles[i]) { circles[i] = {}; circles[i].radius = math.floor(math.random() * 5) + 1; circles[i].y = - circles[i].radius - math.floor(math.random() * 10); circles[i].x = i * 60 + math.floor(math.random() * 10) - 5; circles[i].vy = math.floor(math.random() * 5) + 1; } animctx.beginpath(); animctx.arc(circles[i].x, circles[i].y, circles[i].radius, 0, math.pi * 2); animctx.fillstyle = "rgba(255, 255, 255, 0.5)"; animctx.fill(); circles[i].y = circles[i].y + circles[i].vy; if(circles[i].y > animctx.canvas.height + circles[i].radius * 2) { circles[i] = undefined; } } }, 100);
案例:山中明月风景图
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>document</title> <style> canvas{background-color:#000;opacity:0.7} </style> </head> <body> <canvas id="canvas" width="720px" height="600px">您的浏览器不支持canvas</canvas> <script> var canvas=document.getelementbyid("canvas"); var context=canvas.getcontext("2d"); // 月亮绘制 context.shadowoffsetx=10; context.shadowoffsety=10; context.shadowblur=5; context.shadowcolor='rgba(255,255,255,0.2)'; context.fillstyle='yellow'; context.arc(100,100,40,0,math.pi*2,true); context.fill(); // 文字绘制 context.beginpath(); var str='山高月小'; context.font='50px 宋体'; context.fillstyle='#fff'; context.shadowcolor='rgba(255,255,255,0.4)'; context.filltext(str,400,200); // 山峰绘制 context.beginpath(); context.linewidth=5; context.strokestyle='lightblue'; context.moveto(14, 600); context.quadraticcurveto(60, 193, 123, 600); context.stroke(); context.beginpath(); context.moveto(298, 600); context.beziercurveto(81, 193, 73, 691, 100, 600); context.stroke(); context.beginpath(); context.moveto(500, 600); context.beziercurveto(451, 34, 273, 361, 298, 600); context.stroke(); context.beginpath(); context.moveto(452, 600); context.beziercurveto(569, 210, 695, 426, 715, 600); context.stroke(); </script> </body> </html>
如对本文有疑问, 点击进行留言回复!!
web前端基础之HTML5语义化新标签学习笔记(8)学会用语义化标签
网友评论