HTML5 CSS3 誘人的實例 :canvas 模擬實現電子彩票刮刮樂
轉載請標明出處:http://blog.csdn.net/lmj623565791/article/details/34089553
今天給大家帶來一個刮刮樂的小例子~基于HTML5 canvas的,有興趣的可以改成android版本的,或者其他的~
效果圖:

貼一張我中500w的照片,咋辦啊,怎么花呢~

好了,下面開始原理:
1、刮獎區域兩個Canvas,一個是front , 一個back ,front遮蓋住下面的canvas。
2、canvas默認填充了一個矩形,將下面canvas效果圖遮蓋,然后監聽mouse事件,根據mousemove的x,y坐標,進行擦出front canvas上的矩形區域,然后顯示出下面的canvas的效果圖。
很簡單把~嘿嘿~
1、HTML文件內容:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<script type="text/javascript" src="../../jquery-1.8.3.js"></script>
<script type="text/javascript" src="canvas2d.js"></script>
<script type="text/javascript" src="GuaGuaLe2.js"></script>
<script type="text/javascript">
$(function ()
{
var guaguale = new GuaGuaLe("front", "back");
guaguale.init({msg: "¥5000000.00"});
});
</script>
<style type="text/css">
body
{
background: url("s_bd.jpg") repeat 0 0;
}
.container
{
position: relative;
width: 400px;
height: 160px;
margin: 100px auto 0;
background: url(s_title.png) no-repeat 0 0;
background-size: 100% 100%;
}
#front, #back
{
position: absolute;
width: 200px;
left: 50%;
top: 100%;
margin-left: -130px;
height: 80px;
border-radius: 5px;
border: 1px solid #444;
}
</style>
</head>
<body>
<div class="container">
<canvas id="back" width="200" height="80"></canvas>
<canvas id="front" width="200" height="80"></canvas>
</div>
</body>
</html>
2、首先我利用了一個以前寫的canvas輔助類,留下來今天要用的一些方法:
/**
* Created with JetBrains WebStorm.
* User: zhy
* Date: 13-12-17
* Time: 下午9:42
* To change this template use File | Settings | File Templates.
*/
function Canvas2D($canvas)
{
var context = $canvas[0].getContext("2d"),
width = $canvas[0].width,
height = $canvas[0].height,
pageOffset = $canvas.offset();
context.font = "24px Verdana, Geneva, sans-serif";
context.textBaseline = "top";
/**
* 繪制矩形
* @param start
* @param end
* @param isFill
*/
this.drawRect = function (start, end, isFill)
{
var w = end.x - start.x , h = end.y - start.y;
if (isFill)
{
context.fillRect(start.x, start.y, w, h);
}
else
{
context.strokeRect(start.x, start.y, w, h);
}
};
/**
* 根據書寫的文本,得到該文本在canvas上書寫的中心位置的左上角坐標
* @param text
* @returns {{x: number, y: number}}
*/
this.caculateTextCenterPos = function (text)
{
var metrics = context.measureText(text);
console.log(metrics);
// context.font = fontSize + "px Verdana, Geneva, sans-serif";
var textWidth = metrics.width;
var textHeight = parseInt(context.font);
return {
x: width / 2 - textWidth / 2,
y: height / 2 - textHeight / 2
};
}
this.width = function ()
{
return width;
}
this.height = function ()
{
return height;
}
this.resetOffset = function ()
{
pageOffset = $canvas.offset();
}
/**
* 當屏幕大小發生變化,重新計算offset
*/
$(window).resize(function ()
{
pageOffset = $canvas.offset();
});
/**
* 將頁面上的左邊轉化為canvas中的坐標
* @param pageX
* @param pageY
* @returns {{x: number, y: number}}
*/
this.getCanvasPoint = function (pageX, pageY)
{
return{
x: pageX - pageOffset.left,
y: pageY - pageOffset.top
}
}
/**
* 清除區域,此用戶鼠標擦出刮獎涂層
* @param start
* @returns {*}
*/
this.clearRect = function (start)
{
context.clearRect(start.x, start.y, 10, 10);
return this;
};
/**
*將文本繪制到canvas的中間
* @param text
* @param fill
*/
this.drawTextInCenter = function (text, fill)
{
var point = this.caculateTextCenterPos(text);
if (fill)
{
context.fillText(text, point.x, point.y);
}
else
{
context.strokeText(text, point.x, point.y);
}
};
/**
* 設置畫筆寬度
* @param newWidth
* @returns {*}
*/
this.penWidth = function (newWidth)
{
if (arguments.length)
{
context.lineWidth = newWidth;
return this;
}
return context.lineWidth;
};
/**
* 設置畫筆顏色
* @param newColor
* @returns {*}
*/
this.penColor = function (newColor)
{
if (arguments.length)
{
context.strokeStyle = newColor;
context.fillStyle = newColor;
return this;
}
return context.strokeStyle;
};
/**
* 設置字體大小
* @param fontSize
* @returns {*}
*/
this.fontSize = function (fontSize)
{
if (arguments.length)
{
context.font = fontSize + "px Verdana, Geneva, sans-serif";
return this;
}
return context.fontSize;
}
} 這個類也就對Canvas對象進行了簡單的封裝,設置參數,繪制圖形什么的,比較簡單,大家可以完善下這個類~
3、GuaGuaLe.js
/**
* Created with JetBrains WebStorm.
* User: zhy
* Date: 14-6-24
* Time: 上午11:36
* To change this template use File | Settings | File Templates.
*/
function GuaGuaLe(idFront, idBack)
{
this.$eleBack = $("#" + idBack);
this.$eleFront = $("#" + idFront);
this.frontCanvas = new Canvas2D(this.$eleFront);
this.backCanvas = new Canvas2D(this.$eleBack);
this.isStart = false;
}
GuaGuaLe.prototype = {
constructor: GuaGuaLe,
/**
* 將用戶的傳入的參數和默認參數做合并
* @param desAttr
* @returns {{frontFillColor: string, backFillColor: string, backFontColor: string, backFontSize: number, msg: string}}
*/
mergeAttr: function (desAttr)
{
var defaultAttr = {
frontFillColor: "silver",
backFillColor: "gold",
backFontColor: "red",
backFontSize: 24,
msg: "謝謝惠顧"
};
for (var p in desAttr)
{
defaultAttr[p] = desAttr[p];
}
return defaultAttr;
},
init: function (desAttr)
{
var attr = this.mergeAttr(desAttr);
//初始化canvas
this.backCanvas.penColor(attr.backFillColor);
this.backCanvas.fontSize(attr.backFontSize);
this.backCanvas.drawRect({x: 0, y: 0}, {x: this.backCanvas.width(), y: this.backCanvas.height()}, true);
this.backCanvas.penColor(attr.backFontColor);
this.backCanvas.drawTextInCenter(attr.msg, true);
//初始化canvas
this.frontCanvas.penColor(attr.frontFillColor);
this.frontCanvas.drawRect({x: 0, y: 0}, {x: this.frontCanvas.width(), y: this.frontCanvas.height()}, true);
var _this = this;
//設置事件
this.$eleFront.mousedown(function (event)
{
_this.mouseDown(event);
}).mousemove(function (event)
{
_this.mouseMove(event);
}).mouseup(function (event)
{
_this.mouseUp(event);
});
},
mouseDown: function (event)
{
this.isStart = true;
this.startPoint = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY);
},
mouseMove: function (event)
{
if (!this.isStart)return;
var p = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY);
this.frontCanvas.clearRect(p);
},
mouseUp: function (event)
{
this.isStart = false;
}
}; 通過用戶傳入的兩個canvas的id,然后生成一個對象,進行初始化操作,設置事件。當然了也提供用戶設置可選的參數,各種顏色,已經刮開后顯示的信息等,通過{
frontFillColor: "silver",
backFillColor: "gold",
backFontColor: "red",
backFontSize: 24,
msg: "謝謝惠顧"
};傳給init方法進行設置。
好了,然后就基本完工了,測試一下:
基本實現了刮開圖層,但是存在一個小問題,就是當用戶滑動特別快時,會出現一些斷點,當然也可以忽略,不過我們準備提供一下解決方案:

產生原因:由于鼠標移動速度過快,產生的斷點;解決方案:將mousemove中兩次的鼠標左邊,進行拆分成多個斷點坐標:

如上圖,把兩點之間進行連線,根據斜率,然后分成多個小段,分別獲得線段上的坐標(有四種可能,有興趣可以畫畫圖,計算下,代碼如下):
var k;
if (p.x > this.startPoint.x)
{
k = (p.y - this.startPoint.y) / (p.x - this.startPoint.x);
for (var i = this.startPoint.x; i < p.x; i += 5)
{
this.frontCanvas.clearRect({x: i, y: (this.startPoint.y + (i - this.startPoint.x) * k)});
}
} else
{
k = (p.y - this.startPoint.y) / (p.x - this.startPoint.x);
for (var i = this.startPoint.x; i > p.x; i -= 5)
{
this.frontCanvas.clearRect({x: i, y: (this.startPoint.y + ( i - this.startPoint.x ) * k)});
}
}
this.startPoint = p; 4、最后貼一下完整的GuaGuaLe.js
/**
* Created with JetBrains WebStorm.
* User: zhy
* Date: 14-6-24
* Time: 上午11:36
* To change this template use File | Settings | File Templates.
*/
function GuaGuaLe(idFront, idBack)
{
this.$eleBack = $("#" + idBack);
this.$eleFront = $("#" + idFront);
this.frontCanvas = new Canvas2D(this.$eleFront);
this.backCanvas = new Canvas2D(this.$eleBack);
this.isStart = false;
}
GuaGuaLe.prototype = {
constructor: GuaGuaLe,
/**
* 將用戶的傳入的參數和默認參數做合并
* @param desAttr
* @returns {{frontFillColor: string, backFillColor: string, backFontColor: string, backFontSize: number, msg: string}}
*/
mergeAttr: function (desAttr)
{
var defaultAttr = {
frontFillColor: "silver",
backFillColor: "gold",
backFontColor: "red",
backFontSize: 24,
msg: "謝謝惠顧"
};
for (var p in desAttr)
{
defaultAttr[p] = desAttr[p];
}
return defaultAttr;
},
init: function (desAttr)
{
var attr = this.mergeAttr(desAttr);
//初始化canvas
this.backCanvas.penColor(attr.backFillColor);
this.backCanvas.fontSize(attr.backFontSize);
this.backCanvas.drawRect({x: 0, y: 0}, {x: this.backCanvas.width(), y: this.backCanvas.height()}, true);
this.backCanvas.penColor(attr.backFontColor);
this.backCanvas.drawTextInCenter(attr.msg, true);
//初始化canvas
this.frontCanvas.penColor(attr.frontFillColor);
this.frontCanvas.drawRect({x: 0, y: 0}, {x: this.frontCanvas.width(), y: this.frontCanvas.height()}, true);
var _this = this;
//設置事件
this.$eleFront.mousedown(function (event)
{
_this.mouseDown(event);
}).mousemove(function (event)
{
_this.mouseMove(event);
}).mouseup(function (event)
{
_this.mouseUp(event);
});
},
mouseDown: function (event)
{
this.isStart = true;
this.startPoint = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY);
},
mouseMove: function (event)
{
if (!this.isStart)return;
var p = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY);
this.frontCanvas.clearRect(p);
},
mouseUp: function (event)
{
this.isStart = false;
}
}; 轉載請標明出處:http://blog.csdn.net/lmj623565791/article/details/34089553
好了,收工吃飯~
來自: http://blog.csdn.net//lmj623565791/article/details/34089553
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!