html部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="guaguaCard.css">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<style>
#guaguaCard {
width: 400px;
height: 200px;
max-width: 100%;
}
</style>
</head>
<body>
<script type="text/javascript" src="guaguacard.js"></script>
<div id='guaguaCard'></div>
<button type="button" id="reset">reset</button>
<script type="text/javascript">
var a = new GuaGuaCard({
el: document.getElementById('guaguaCard')
});
</script>
</body>
</html>
javascript 部分
!(function(window, document){
function GuaGuaCard (config) {
var defaults = {
el: null,
// 画笔的半径
size: 40,
// 中奖内容
text: '你中奖了!',
// 盒子样式 eg: 'aaa bbb'
elClass: '',
// 文字样式
textClass: ''
};
this.defaults = defaults;
this.init(config);
};
GuaGuaCard.prototype = {
constructor: GuaGuaCard,
version: '1.0',
init: function (config) {
var con = Object.assign(this.defaults, config);
for (var key in con) {
this[key] = con[key];
}
this.initSize().initTpl().draw().bindEvt();
},
initSize: function () {
var elStyle = this.getStyle.call(this.el);
var width = parseInt(elStyle.width);
var height = parseInt(elStyle.height);
this.width = width;
this.height = height;
this.el.style.width = this.width + 'px';
this.el.style.height = this.height + 'px';
return this;
},
getStyle: function () {
var oStyle = this.currentStyle? this.currentStyle : window.getComputedStyle(this, null);
return oStyle;
},
initTpl: function () {
this.el.style.position = 'relative';
this.el.className = this.addClass('guaguaCard', this.elClass);
var div = document.createElement('div');
div.className = this.addClass('content', this.textClass);
div.innerHTML = this.text;
var canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
canvas.className = 'cover';
canvas.setAttribute('isdown', false);
this.el.append(div);
this.el.append(canvas);
this._canvas = canvas;
this._cover = canvas.getContext("2d");
return this;
},
addClass: function (str, classList) {
return [str].concat(classList.split(' ')).join(' ').replace(/^\s+|\s+$/g, '');
},
bindEvt: function () {
var cover = this._canvas;
cover.addEventListener('touchstart', this.isDown);
cover.addEventListener('touchmove', this.move.bind(this));
cover.addEventListener('touchend', this.isUp);
cover.addEventListener('mousemove', this.move.bind(this));
cover.addEventListener('mousedown', this.isDown);
cover.addEventListener('mouseup', this.isUp);
return this;
},
draw: function () {
this._cover.fillStyle = "transparent";
this._cover.fillRect(0, 0, this.width, this.height);
this._cover.fillStyle = "#ccc";
this._cover.fillRect(0, 0, this.width, this.height);
// 最关键的是设置这个地方
this._cover.globalCompositeOperation = 'destination-out';
return this;
},
move: function (e) {
e.preventDefault();
if (e.target.getAttribute('isdown') === 'true') {
if (e.changedTouches) {
e = e.changedTouches[e.changedTouches.length - 1];
}
// 获取鼠标点击的中心位置
var parent = e.target.offsetParent;
touchX = e.clientX - parent.offsetLeft;
touchY = e.clientY - parent.offsetTop;
this._cover.beginPath();
this._cover.arc(touchX, touchY, this.size, 0, Math.PI * 2);
this._cover.fill();
}
},
isDown: function (e) {
e.preventDefault();
e.target.setAttribute('isdown', true);
},
isUp: function (e) {
e.target.setAttribute('isdown', false);
}
};
window.GuaGuaCard = GuaGuaCard;
})(window, document);
css部分
.guaguaCard {
position: relative;
}
.guaguaCard .content,
.guaguaCard .cover {
position: absolute;
width: 100%;
height: 100%;
}
.guaguaCard .content {
font-size: 24px;
line-height: 100%;
text-align: center;
}