文章出處
View Code
文章列表
這周有點迷茫,不知道干嘛了,一天天就過去了!我在博客右側公告欄加了qq交流,各位有好的主題,或者有趣的技術,歡迎交流!今天突發奇想,就寫了2個h5 canvas的demo玩玩!
demo一:刮刮樂
舍不得買2塊錢的刮刮樂,就只能寫個類似的功能過過彩票癮了!
布局
<div id="lottery" style="width:300px;height:500px;margin:10px;background-color:lightskyblue;border-radius:5px;float:left;"> <div style="width:300px;height:100px;line-height:100px;text-align:center;font-size:33px;color:blueviolet;">NICK彩票</div> <div id="txt" style="width:300px;height:200px;font-size:40px;color:peachpuff;display:flex;justify-content:center;align-items:center;flex-direction:column;"> <span>祝</span> <span>君</span> <span>中</span> <span>獎</span> </div> <div id="canvasArea" style="width:300px;height:200px;position:relative;"> <div style="width:300px;height:200px;position:absolute;top:0;left:0;z-index:1;text-align:center;line-height:200px;font-weight:bold;font-size:56px;color:indianred;">一等獎</div> <canvas id="canvas" width="300px" height="200px" style="position:absolute;top:0;left:0;z-index:2;"></canvas> </div> </div>
這段html要注意的地方有2個:
- flex布局,將‘祝君中獎’垂直居中,目前還有兼容問題,不過看我們大前端的發展趨勢,應該很快就能搞定了;
- canvas和‘一等獎’div的z-index問題,將canvas的z-index設置較高,使其置于一等獎div上面。
設置canvas畫布
var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d");
繪制刮獎區域
context.fillStyle='#A9AB9D'; context.fillRect(10,10,280,180); context.fillStyle='#000'; context.font='50px Arial'; context.fillText('刮獎區',75,115);
- 填充顏色;
- 繪制實心矩形;
- 設置字體顏色;
- 設置字體大小類型;
- 繪制實心字體。
以上都是canvas基礎api,看w3c就ok了。
為了好看,我將‘祝君中獎’加個字體變色
setInterval(function(){ document.getElementById('txt').style.color = document.getElementById('txt').style.color=='peachpuff' ? 'yellow' : 'peachpuff'; },500);
刮獎功能函數
var brush=function(){//刮獎 context.clearRect(event.offsetX,event.offsetY,20,20); };
為canvas元素onmousedown和onmouseup事件
canvas.onmousedown = function(){ // 鼠標按下時 - 綁定鼠標跟隨事件 bindHandler(canvas,'mousemove',brush,false); } canvas.onmouseup = function(){ // 停止刮獎功能 - 解綁鼠標跟隨事件 removeHandler(canvas,"mousemove",brush,false); }
這里的事件綁定與解綁我上篇博文有封裝,最后完整代碼也有!
刮刮樂happy到底結束!最后附上完整代碼,再看看效果吧!
demo二:畫筆
布局
<div style="width:300px;height:500px;margin:10px;border-radius:10px;overflow:hidden;float:right;"> <canvas id="canvas2" width="300px" height="500px" style="background-color:lightblue;"></canvas> </div>
設置canvas畫布
var canvas2 = document.getElementById("canvas2"); var context2 = canvas2.getContext("2d");
畫筆功能函數
var draw=function(){ context2.fillRect(event.offsetX,event.offsetY,10,10); };
為canvas元素onmousedown和onmouseup事件
context2.font='20px Arial'; context2.strokeText('NICK畫筆',100,30);//寫個頭 //1. 為canvas元素onmousedown和onmouseup事件 canvas2.onmousedown = function(){ // 啟用畫筆功能 - 綁定鼠標跟隨事件 bindHandler(canvas2,'mousemove',draw,false); } canvas2.onmouseup = function(){ // 停止畫筆功能 - 解綁鼠標跟隨事件 removeHandler(canvas2,"mousemove",draw,false); }
畫圖工具的畫筆功能到底結束!
多謝各位老司機的鞭策與提醒,說畫筆功能有不連續的現象!
現已改良,并兼容了移動端!
//改良后的寫法
var isTouch = "ontouchstart" in window ? true : false;
var StartDraw = isTouch ? "touchstart" : "mousedown",
MoveDraw = isTouch ? "touchmove" : "mousemove",
EndDraw = isTouch ? "touchend" : "mouseup";
context2.strokeStyle='blue';//線色
context2.lineCap = "round";//連接處為圓形
context2.lineWidth =10;//線框
canvas2.addEventListener(StartDraw, function(ev){
ev.preventDefault();
var isX = isTouch ? ev.targetTouches[0].pageX : ev.pageX;
var isY = isTouch ? ev.targetTouches[0].pageY : ev.pageY;
var x = isX - canvas2.offsetLeft;
var y = isY - canvas2.offsetTop;
context2.beginPath();
context2.moveTo(x, y);
function StartMove(ev){
var isX1 = isTouch ? ev.targetTouches[0].pageX : ev.pageX;
var isY1 = isTouch ? ev.targetTouches[0].pageY : ev.pageY;
var x1 = isX1 - canvas2.offsetLeft;
var y1 = isY1 - canvas2.offsetTop;
context2.lineTo(x1, y1);
context2.stroke();
context2.beginPath();
context2.moveTo(x1, y1);
};
function EndMove(ev){
var isX1 = isTouch ? ev.changedTouches[0].pageX : ev.pageX;
var isY1 = isTouch ? ev.changedTouches[0].pageY : ev.pageY;
var x1 = isX1 - canvas2.offsetLeft;
var y1 = isY1 - canvas2.offsetTop;
context2.lineTo(x1, y1);
context2.stroke();
canvas2.removeEventListener(MoveDraw, StartMove, false);
canvas2.removeEventListener(EndDraw, EndMove, false);
};
canvas2.addEventListener(MoveDraw, StartMove, false);
canvas2.addEventListener(EndDraw, EndMove, false);
}, false);
附上完整代碼:

<!DOCTYPE html> <html> <head> <title>Canvas lottery brush nick</title> <meta charset="utf-8"/> </head> <body> <div style="width:640px;margin:auto;"> <!--刮刮樂--> <div id="lottery" style="width:300px;height:500px;margin:10px;background-color:lightskyblue;border-radius:5px;float:left;"> <div style="width:300px;height:100px;line-height:100px;text-align:center;font-size:33px;color:blueviolet;">NICK彩票</div> <div id="txt" style="width:300px;height:200px;font-size:40px;color:peachpuff;display:flex;justify-content:center;align-items:center;flex-direction:column;"> <span>祝</span> <span>君</span> <span>中</span> <span>獎</span> </div> <div id="canvasArea" style="width:300px;height:200px;position:relative;"> <div style="width:300px;height:200px;position:absolute;top:0;left:0;z-index:1;text-align:center;line-height:200px;font-weight:bold;font-size:56px;color:indianred;">一等獎</div> <canvas id="canvas" width="300px" height="200px" style="position:absolute;top:0;left:0;z-index:2;"></canvas> </div> </div> <!--畫圖工具畫筆功能--> <div style="width:300px;height:500px;margin:10px;border-radius:10px;overflow:hidden;float:right;"> <canvas id="canvas2" width="300px" height="500px" style="background-color:lightblue;"></canvas> </div> </div> <div style="text-align:center;"> <p>刮刮樂:鼠標按住不放,拖動開始刮獎!</p> <p>畫筆:鼠標按住不放,拖動畫畫!</p> </div> <script> //插件方法封裝區 ;(function(){ // 事件綁定 window.bindHandler = (function() { if (window.addEventListener) {// 標準瀏覽器 return function(elem, type, handler) { // elem:節點 type:事件類型 handler:事件處理函數 // 最后一個參數為true:在捕獲階段調用事件處理程序;為false:在冒泡階段調用事件處理程序。注意:ie沒有這個參數 elem.addEventListener(type, handler, false); } } else if (window.attachEvent) {// IE瀏覽器 return function(elem, type, handler) { elem.attachEvent("on" + type, handler); } } }()); // 事件解除 window.removeHandler = (function() { if (window.removeEventListener) {// 標準瀏覽器 return function(elem, type, handler) { elem.removeEventListener(type, handler, false); } } else if (window.detachEvent) {// IE瀏覽器 return function(elem, type, handler) { elem.detachEvent("on" + type, handler); } } }()); }()); //命名區 var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); var canvas2 = document.getElementById("canvas2"); var context2 = canvas2.getContext("2d"); var brush=function(){//刮獎 context.clearRect(event.offsetX,event.offsetY,20,20); }; var draw=function(){//寫字 context2.fillRect(event.offsetX,event.offsetY,10,10); }; //功能實現區 //刮刮樂 // 1. 繪制刮獎區域 context.fillStyle='#A9AB9D'; context.fillRect(10,10,280,180); context.fillStyle='#000'; context.font='50px Arial'; context.fillText('刮獎區',75,115); //字體變色 setInterval(function(){ document.getElementById('txt').style.color = document.getElementById('txt').style.color=='peachpuff' ? 'yellow' : 'peachpuff'; },500); //2. 為canvas元素onmousedown和onmouseup事件 canvas.onmousedown = function(){ // 鼠標按下時 - 綁定鼠標跟隨事件 bindHandler(canvas,'mousemove',brush,false); } canvas.onmouseup = function(){ // 停止刮獎功能 - 解綁鼠標跟隨事件 removeHandler(canvas,"mousemove",brush,false); } //畫筆 context2.font='20px Arial'; context2.strokeText('NICK畫筆',100,30);//寫個頭 //為canvas元素onmousedown和onmouseup事件 /* //這是原來的寫法 canvas2.onmousedown = function(){ // 啟用畫筆功能 - 綁定鼠標跟隨事件 bindHandler(canvas2,'mousemove',draw,false); } canvas2.onmouseup = function(){ // 停止畫筆功能 - 解綁鼠標跟隨事件 removeHandler(canvas2,"mousemove",draw,false); } */ //改良后的寫法 var isTouch = "ontouchstart" in window ? true : false; var StartDraw = isTouch ? "touchstart" : "mousedown", MoveDraw = isTouch ? "touchmove" : "mousemove", EndDraw = isTouch ? "touchend" : "mouseup"; context2.strokeStyle='blue';//線色 context2.lineCap = "round";//連接處為圓形 context2.lineWidth =10;//線框 canvas2.addEventListener(StartDraw, function(ev){ ev.preventDefault(); var isX = isTouch ? ev.targetTouches[0].pageX : ev.pageX; var isY = isTouch ? ev.targetTouches[0].pageY : ev.pageY; var x = isX - canvas2.offsetLeft; var y = isY - canvas2.offsetTop; context2.beginPath(); context2.moveTo(x, y); function StartMove(ev){ var isX1 = isTouch ? ev.targetTouches[0].pageX : ev.pageX; var isY1 = isTouch ? ev.targetTouches[0].pageY : ev.pageY; var x1 = isX1 - canvas2.offsetLeft; var y1 = isY1 - canvas2.offsetTop; context2.lineTo(x1, y1); context2.stroke(); context2.beginPath(); context2.moveTo(x1, y1); }; function EndMove(ev){ var isX1 = isTouch ? ev.changedTouches[0].pageX : ev.pageX; var isY1 = isTouch ? ev.changedTouches[0].pageY : ev.pageY; var x1 = isX1 - canvas2.offsetLeft; var y1 = isY1 - canvas2.offsetTop; context2.lineTo(x1, y1); context2.stroke(); canvas2.removeEventListener(MoveDraw, StartMove, false); canvas2.removeEventListener(EndDraw, EndMove, false); }; canvas2.addEventListener(MoveDraw, StartMove, false); canvas2.addEventListener(EndDraw, EndMove, false); }, false); </script> </body> </html>
代碼寫完了,我也想說點其他的:
上面js代碼中,有不少注釋,我將其分為幾個區域:插件方法封裝區、命名區、功能實現區、刮刮樂區以及畫筆區等,我感覺這樣寫加上一些注釋,能使代碼能加簡潔,便于以后的維護!當然這只是個人觀點,歡迎各位點擊我博客右邊公告欄的qq交流交流!
最后附上:
上篇博文:事件綁定與解綁!(只是一個簡單的封裝)
來看看效果,玩玩吧!
文章列表
全站熱搜