<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> 最近一直在做关于H5 canvas的一些demo,正好碰到有人在讨论高中时候的学生时代,就想做一个那时候看的最多的东西----黑板。</span>
这个效果其实很简单,应该是canvas入门都会做得东西,但是还是比较好玩的,废话不多说了,开始贴代码以及讲解过程。
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <title>无标题文档</title> <script src="js/main.js"></script> <style> *{ margin:0; padding:0;} #myID{border:none;position:absolute; left:0px; top:0px;} </style> </head> <body> <div id="myID"></div> </body> <script> var mycontainer=document.getElementById("myID"); var option={ width:screen.width, height:screen.height, parentnode:mycontainer } var heibanquyu=new heiban(option); heibanquyu.init(); </script> </html>这段代码是主体架构的搭建,下面的js是激活heiban.js的方法。option是传的参数。这里不必说过多
// JavaScript Document //初始化面板 function heiban(option){ this.width=option.width; this.height=option.height; this.parentnode=option.parentnode; this.parentnode.style.height=this.height+"px"; this.parentnode.style.width=this.width+"px"; this.clickdown=false; } heiban.prototype={ init:function(){ console.log("1"); this.maincanvas = this.createElem("canvas",{style:"position:absolute;left:0;top:0;"}); console.log("2"); this.mainctx = this.maincanvas.getContext("2d"); console.log("3"); this.maincanvas.height=this.height; this.maincanvas.width=this.width; this.parentnode.appendChild(this.maincanvas); this.maincanvas.style.backgroundColor="black"; //this.mainctx.fillStyle="black"; // this.mainctx.fillRect(0,0,this.width,this.height); // this.mainctx.fill(); this.btn = this.creatButton("input",{style:"position:absolute;left:10px;top:10px; width:100px; height:50px; line-height:50px; text-align:center;"}) this.parentnode.appendChild(this.btn); this.bingEvent(); }, btnclick:function(ev,_this){ _this.mainctx.clearRect(0,0,_this.width,_this.height); }, creatButton:function(tagname,stylecss){ var newbutton = document.createElement(tagname); newbutton.type="button"; newbutton.value="重置"; for(var att in stylecss){ newbutton.setAttribute(att,stylecss[att]); } return newbutton; }, createElem:function(tagname,KeyValue){ var elem=document.createElement(tagname); for(var cssindex in KeyValue){ elem.setAttribute(cssindex,KeyValue[cssindex]); } return elem; }, bingEvent:function(){ var _this=this; var device=(/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase())); var mousedown=device?"touchstart":"mousedown"; var mousemove=device?"touchmove":"mousemove"; var mouseup=device?"touchend":"mouseup"; //console.log(mousedown); this.maincanvas.addEventListener(mousedown,function(ev){ _this.mousedown_Event(ev,_this); },false); this.maincanvas.addEventListener(mousemove,function(ev){ _this.mousemove_Event(ev,_this); },false); this.maincanvas.addEventListener(mouseup,function(ev){ _this.mouseup_Event(ev,_this); },false); this.btn.addEventListener(mousedown,function(ev){ _this.btnclick(ev,_this); },false); }, mousedown_Event:function(ev,_this){ ev.preventDefault(); _this.clickdown=true; var localpos=_this.getlocalpos(ev); _this.huaxian(localpos.x,localpos.y,true); }, mousemove_Event:function(ev,_this){ ev.preventDefault(); if(_this.clickdown==false){ return; } var localpos=_this.getlocalpos(ev); _this.huaxian(localpos.x,localpos.y,false); }, mouseup_Event:function(ev,_this){ ev.preventDefault(); if(_this.clickdown==true){ _this.clickdown=false; } }, getlocalpos:function(ev){ var elem=this.maincanvas; var ox=0,oy=0; var pagex,pagey; if(elem!=null){ ox+=elem.offsetLeft; oy+=elem.offsetTop; elem = elem.offsetParent; } if(ev.hasOwnProperty('changedTouches')){ var first=ev.changedTouches[0]; pagex=first.pageX; pagey=first.pageY; } else{ pagex=ev.pageX; pagey=ev.pageY; } console.log(pagex+" "+pagey); return { 'x':pagex-ox, 'y':pagey-oy } }, huaxian:function(x,y,fresh){ this.mainctx.strokeStyle="white"; this.mainctx.lineWidth=10; this.mainctx.lineCap = this.mainctx.lineJoin = 'round'; if(fresh==true){ this.mainctx.beginPath(); this.mainctx.moveTo(x+0.01,y); } this.mainctx.lineTo(x,y); this.mainctx.stroke(); } }
init是方法的初始化,里面创建了canvas画布和重置的按钮,然后将画布的背景置成黑色,然后连接bangEvent()方法,bangEvent()方法里面是会用到的方法的集合,有鼠标的按下或者触屏开始触发的事件,鼠标移动或者触摸滑动时触发的事件,鼠标抬起或者触摸停止触发的事件,还有按钮按下时候的事件,鼠标按下,会将标志位 clickdown置成true,表示鼠标处于按下状态并会触发getlocalpos事件,实时获取鼠标的位置,也会触发 huaxian()方法,进行笔画的现实。触发huaxian()方法的时候也会传一个标志位status,这个标志位是为了只标记一次moveTo,鼠标移动状态和抬起状态原理一样,这里就不多介绍了。