<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> canvas{ border:solid; width:1000px; height:600px } </style> </head> <body> <canvas id="canvas1" width="1000px" height="600px"></canvas> <button id="destroy">Destroy</button> <button id="protect">Protect</button> <!--<button id="a0">A0</button> <button id="a1">A1</button> <button id="a2">A2</button>--> <canvas id="canvas2" width="2000px" height="1200px"></canvas> <script> (function init(){ this.canvas=document.getElementById("canvas1"); this.context=canvas1.getContext("2d"); context.beginPath(); this.canvas2=document.getElementById("canvas2"); this.context2=canvas2.getContext("2d"); context2.beginPath(); document.getElementById("destroy").addEventListener("click",function(){ alert("Everything stopped"); },false); })(); (function(){ /* *回顾canvas画图基本方法 */ /*(function(){ //context.fillRect(20,20,80,80); /!*context.moveTo(20,20); context.lineTo(80,20);*!/ /!*context.moveTo(20,200); context.lineTo(80,200); context.lineTo(50,60); context.closePath(); context.fill();*!/ /!*context.arc(300,300,40,0,Math.PI,false); context.stroke(); context.arc(600,300,40,0,2*Math.PI,false); context.fill();*!/ /!*context.moveTo(20,20); context.lineTo(80,20); context.stroke(); //context.moveTo(340,300); context.arc(300,300,40,0,Math.PI,false); context.stroke();*!/ /!*context.moveTo(20,200); context.lineTo(80,200); context.lineTo(50,60); context.closePath(); context.fill(); //context.beginPath(); context.fillStyle="red"; context.moveTo(320,200); context.lineTo(380,200); context.lineTo(350,60); context.closePath(); setTimeout(function(){ context.fill(); },800);*!/ })();*/ /* * 理解闭包和立即执行函数 * 立即执行函数可以保护作用域,常用于代码封装 * 闭包用法较广,典型的就是保持引用(或隔绝引用,例如私有变量) */ /*(function(){ //IIFE //函数声明不可调用,函数声明会产生声明提升 //函数表达式可直接调用,可以是匿名函数也可以是内联函数,声明不会提升 /!*(function(){ alert("abcd"); })(); +function(){ alert("efg"); }();*!/ //IIFE引起的问题 /!*var test=function(a){ console.log(a); return function(c){ console.log(c); } }(function(b){ console.log(b); })(1); //此处IIFE导致test被重写:test=(function(b){console.log(b)}(1); console.log(test);*!/ //闭包 var button=[document.getElementById("a0"),document.getElementById("a1"),document.getElementById("a2")]; for(var i=0;i<3;i++){ //问题写法 /!*button[i].onclick=function(){ alert(i); }*!/ //用闭包保持引用 /!*(function(j){ button[j].onclick=function(){ alert(j); } })(i);*!/ //高级语法 //eval("a"+i+".onclick=function(){alert("+i+")};"); } //简写 /!*for(var i=0;i<3;i++)(function(j){ button[j].onclick=function(){ alert(j); } })(i);*!/ })();*/ var arr=[]; for(var i=0;i<100;i++){ arr.push(i); } //顺序执行下线条是接近均匀的画出 /*(function(){ function synchronized(n){ var x=0; var start=new Date().getTime(); for(var i=0;i<n;i++){ if(i%2==0){ context.moveTo((new Date().getTime())-start,20); }else{ context.moveTo((new Date().getTime())-start,40); } for(var j=0;j<1000000;j++){ arr.reverse(); } if(i%2==0){ context.lineTo((new Date().getTime())-start,20); }else{ context.lineTo((new Date().getTime())-start,40); } context.stroke(); } } synchronized(10); })();*/ /* * 为什么setTimeout优于setInterval:如果执行一个setInterval的时间本身 * 就比间隔时间长,setInterval就会变成顺序执行,定时器的意义就没有了。 */ /*(function(){ function compare(){ var tickTime=5; var t1=0,t2=0; var start=new Date().getTime(); setTimeout(function timer(){ if(++t1==3){ return; } context.moveTo((new Date().getTime())-start,20); for(var j=0;j<200000;j++){ arr.reverse(); } context.lineTo((new Date().getTime())-start,20); context.stroke(); setTimeout(timer,tickTime); },tickTime); var start2=new Date().getTime(); var id=setInterval(function timer(){ if(++t2==3){ clearInterval(id); } context.moveTo((new Date().getTime())-start2,40); for(var j=0;j<200000;j++){ arr.reverse(); } context.lineTo((new Date().getTime())-start2,40); context.stroke(); },tickTime); } compare(); })();*/ /* * 顺序执行和定时器同时发生,只有一条线程 */ /*(function(){ var start=new Date().getTime(); function asynchronized(n){ var tickTime=5; var t=0; setTimeout(function timer(){ if(t==n){ return; } if(t%2==0){ context.moveTo((new Date().getTime())-start,60); }else{ context.moveTo((new Date().getTime())-start,80); } for(var j=0;j<200000;j++){ arr.reverse(); } if(t%2==0){ context.lineTo((new Date().getTime())-start,60); }else{ context.lineTo((new Date().getTime())-start,80); } context.stroke(); t++; setTimeout(timer,tickTime); },tickTime); } function synchronized(n){ var x=0; for(var i=0;i<n;i++){ if(i%2==0){ context.moveTo((new Date().getTime())-start,20); }else{ context.moveTo((new Date().getTime())-start,40); } for(var j=0;j<1000000;j++){ arr.reverse(); } if(i%2==0){ context.lineTo((new Date().getTime())-start,20); }else{ context.lineTo((new Date().getTime())-start,40); } context.stroke(); } } asynchronized(4); //synchronized(4); setTimeout(function(){ synchronized(4); },10); })();*/ //任何交互事件都会阻塞定时器 /*(function(){ var x=0,y=0; context.moveTo(x,y); setTimeout(function next(){ if(y>=canvas.height-20){ return; } x+=3,y+=3; context.lineTo(x,y); context.stroke(); setTimeout(next,17); },17); })();*/ //如何通过定时器来形成一个完美的动画 /*(function(){ context.fillRect(20,20,80,300); context.moveTo(20,320); context.lineTo(600,320); context.stroke(); var h=300, totalTime=2000, tickTime=60, //tickTime=1, //tickTime=17, animateTimes=totalTime/tickTime, stepH=h/animateTimes, tempY=0, position=0; //第一种错误做法,以时间为基准进行演进 /!*var start=new Date().getTime(); setTimeout(function next(){ var end=new Date().getTime(); if(end-start>=totalTime){ console.log(end-start); return; } context.fillRect(200,20,80,h*(end-start)/totalTime); /!*if(end-start>=totalTime){ return; }*!/ setTimeout(next,tickTime); },tickTime);*!/ //第二种错误写法,坐标偏移 /!*setTimeout(function next(){ if(tempY>=h){ return; } context.fillRect(200,20,80,tempY); tempY+=stepH; setTimeout(next,tickTime); },tickTime);*!/ //一种合理的做法 /!*setTimeout(function next(){ if(position>=animateTimes-1){ context.fillRect(200,20,80,h); return; } context.fillRect(200,20,80,tempY); tempY+=stepH; position++; setTimeout(next,tickTime); },tickTime);*!/ })();*/ /* * 性能测试,通常认为1毫秒可执行一百万次原子操作。 */ /*(function(){ var start=new Date().getTime(); for(var i=0;i<1000000;i++){ var a=1+2; } console.log(new Date().getTime()-start); })();*/ //小游戏 /*(function game(){ var startX,startY,startTime,endX,endY,endTime; var stepX=2,stepY,tickTime=40,id; canvas.addEventListener("mousedown",doMouseDown,false); canvas.addEventListener(‘mouseup‘, doMouseUp, false); function doMouseDown(e){ clearTimeout(id); context.clearRect(0,0,canvas.width,canvas.height); startX= e.pageX; startY= e.pageY; stepX=2; startTime=new Date().getTime(); } function doMouseUp(e){ endX= e.pageX; endY= e.pageY; endTime=new Date().getTime(); stepY=stepX*(endY-startY)/(endX-startX); tickTime/=(endTime-startTime)/100; startFlow(); } function startFlow(){ id=setTimeout(function next(){ context.clearRect(0,0,canvas.width,canvas.height); context.fillRect(endX,endY,20,20); if(endX>=980){ stepX*=-1; }else if(endX<=0){ stepX*=-1; } if(endY>=580){ stepY*=-1; }else if(endY<=0){ stepY*=-1; } endX+=stepX; endY+=stepY; id=setTimeout(next,tickTime); },tickTime); } })();*/ /* * 保护动画,最简单的AOP * CSS动画不受影响,是另一个线程 */ /*(function(){ var h=300,totalTime=2000,tickTime=17,animateTimes=totalTime/tickTime,stepH=h/animateTimes,tempY= 0,id; function cancelAnimate(){ if(id){ clearTimeout(id); } context.clearRect(0,0,canvas.width,canvas.height); context.fillRect(200,20,80,300); } id=setTimeout(function next(){ if(tempY>=h){ return; } context.fillRect(200,20,80,tempY); tempY+=stepH; id=setTimeout(next,tickTime); },tickTime); document.getElementById("protect").addEventListener("click",function(){ cancelAnimate(); alert("Animate protected"); },false); })();*/ /* * 每次都要清除页面所有的定时器?每次都要考虑页面定时器之间的互相影响?针对每个定时器id都要专写一个变量和方法? * 中央定时器和高级AOP方法封装 */ /*(function(){ //中央定时器,并非必须使用 var centerTimer={ tickTime:25, timerID:0, timerFn:[], isAnimate:false, add:function(aFn,cFn){ aFn.cancelFn=cFn; this.timerFn.push(aFn); }, start:function(){ if(this.timerID) return; this.isAnimate=true; (function runNext(){ if(centerTimer.timerFn.length>0){ for(var i=0;i<centerTimer.timerFn.length;i++){ //作为数组的一部分调用方法时this指向方法本身 if(centerTimer.timerFn[i](centerTimer.tickTime)===false){ centerTimer.timerFn.splice(i,1); i--; //console.log(new Date().getTime()-start); } } centerTimer.timerID=setTimeout(runNext,centerTimer.tickTime); } })(); }, stop:function(){ this.isAnimate=false; clearTimeout(this.timerID); this.timerID=0; for(var i in this.timerFn){ if(this.timerFn[i].cancelFn){ this.timerFn[i].cancelFn(); } } this.timerFn=[]; } }; //AOP包装方法 var AOP={ before:function(){ if(centerTimer.isAnimate){ centerTimer.stop(); } }, after:function(){ console.log("do something after function"); }, bind:function(elem,type,fn,useCapture){ var that=this; elem.addEventListener(type,function(){ //that保存aop对象 //this为DOM节点 that.before.apply(this,arguments); fn.apply(this,arguments); that.after.apply(this,arguments); },useCapture); } }; //还是那个长方形的例子,对于不同的情况返回true和false var h=300,totalTime=2000,tickTime=17,animateTimes=totalTime/tickTime,stepH=h/animateTimes,tempY= 0,id; function cancelAnimate(){ context.clearRect(0,0,canvas.width,canvas.height); context.fillRect(200,20,80,300); } function animate(){ if(tempY>=h){ return false; } context.fillRect(200,20,80,tempY); tempY+=stepH; return true; } centerTimer.add(animate,cancelAnimate); AOP.bind(document.getElementById("protect"),"click",function(){ alert("AOP function"); },false); centerTimer.start(); })();*/ /* * 再谈screenPixel */ /*(function(){ //为什么要在手机上缩放,例子无效 //无缩放 /!*(function(){ context.fillStyle="#fa5d5d"; context.moveTo(20,440); context.lineTo(400,440); context.lineTo(210,20); context.closePath(); context.fill(); context.fillStyle="#4a90e2"; context.fillRect(480,20,360,400); context.fillStyle="#888"; context.font=56+"px Arial"; context.textAlign="center"; context.textBaseline="middle"; context.fillText("计算机科学ab",210,500); context.fillText("数据结构与算法12",620,500); })(); //缩放后 (function(){ context2.fillStyle="#fa5d5d"; context2.moveTo(40,880); context2.lineTo(800,880); context2.lineTo(420,40); context2.closePath(); context2.fill(); context2.fillStyle="#4a90e2"; context2.fillRect(960,40,720,800); context2.fillStyle="#888"; context2.font=112+"px Arial"; context2.textAlign="center"; context2.textBaseline="middle"; context2.fillText("计算机科学ab",420,1000); context2.fillText("数据结构与算法12",1240,1000); })();*!/ /!*(function(){ context.moveTo(20,40); context.lineTo(320,40); //context.stroke(); context.moveTo(20,100.3); context.lineTo(320,100.3); context.moveTo(330,100); context.lineTo(500,100); //context.stroke(); context.moveTo(20,160.666); context.lineTo(320,160.666); context.moveTo(330,161); context.lineTo(500,161); //context.stroke(); context.fillStyle="#000"; context.font=24+"px Arial"; context.textAlign="left"; context.textBaseline="bottom"; /!*context.fillText("x:20,y:40",20,38); context.fillText("x:20,y:100.3",20,98); context.fillText("x:20,y:160.666",20,158); context.fillText("x:330,y:100",330,98); context.fillText("x:330,y:161",330,158);*!/ //一种解决方案 /!*x=20; y=266.777; y=Math.round(y); y=y%2==0 ? y:y+1; context.moveTo(x,y); context.lineTo(x+200,y);*!/ context.stroke(); })();*!/ })();*/ })(); </script> </body> </html>
时间: 2024-10-12 22:19:38