-
Notifications
You must be signed in to change notification settings - Fork 1
/
ScratchPlugin.js
139 lines (116 loc) · 4.22 KB
/
ScratchPlugin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
* Created by Florian on 03/02/2014.
*/
'use strict'
if (typeof Object.create !== 'function') {
ScratchPlugin.create = function (obj) {
function F() {}
F.prototype = obj;
return new F();
};
}
(function ($, window, document, undefined) {
var scratchCanvasTemplate = $("<canvas class='scratchCanvas' style='display:none'></canvas>");
var ScratchPlugin = {
// Init plugin function
init: function (options, elem) {
var self = this;
self.elem = elem;
self.$elem = $(elem);
self.options = $.extend({}, $.fn.scratchPlugin.options, options);
self.options.backGroundImage = self.$elem.data("background-image");
self.options.foreGroundImage = self.$elem.data("foreground-image");
self.loadedImages = 0;
var canvasForegroundImg = new Image();
canvasForegroundImg.onload = function () {
self.newCanvasTpl = scratchCanvasTemplate.clone();
self.$elem.html(self.newCanvasTpl);
self.canvasElem = self.newCanvasTpl;
self.ctx = self.canvasElem[0].getContext("2d");
$(window).bind('mousedown', $.proxy(self.downHandler, self));
self.canvasElem.bind('mouseup', $.proxy(self.topHandler, self));
$(window).bind('mouseup', $.proxy(self.topHandler, self));
self.canvasElem.bind('touchmove', $.proxy(self.touchMoveHandler, self));
$(self.canvasElem).css({
"backgroundImage": "url(" + canvasForegroundImg.src + ")"
});
self.canvasElem[0].width = canvasForegroundImg.width;
self.canvasElem[0].height = canvasForegroundImg.height;
self.loadedImages++;
self.canvasElem.css("display", "inline");
self.initX = self.canvasElem.offset().left;
self.initY = self.canvasElem.offset().top;
};
var backgroundImg = new Image();
backgroundImg.onload = function () {
self.srcImg = backgroundImg;
canvasForegroundImg.src = self.options.foreGroundImage;
}
backgroundImg.src = self.options.backGroundImage;
},
// Handle the end of the scratching
topHandler: function (e) {
var self = this;
self.canvasElem.unbind('mousemove');
var percentage = self.scratchPercentage(self);
self.options.complete(self.$elem, percentage);
},
// Begin the scratch
downHandler: function (e) {
var self = this;
self.canvasElem.bind('mousemove', $.proxy(self.mouseMoveHandler, self));
},
// Get mouse scratch pos and call the reveal function
mouseMoveHandler: function (e) {
var self = this;
var mouseX = e.pageX - e.currentTarget.offsetLeft;
var mouseY = e.pageY - e.currentTarget.offsetTop;
self.scratch(mouseX, mouseY, self);
},
// Get touch scratch pos and call the reveal function
touchMoveHandler: function (e) {
var self = this;
e.preventDefault();
var event = window.event;
var touchX = event.touches[0].pageX - self.initX;
var touchY = event.touches[0].pageY - self.initY;
self.scratch(touchX, touchY, self);
},
// Scratch the pos
scratch: function (posX, posY, self) {
self.ctx.save();
self.ctx.arc(posX, posY, self.options.scratchRadius, 0, 2 * Math.PI, false);
self.ctx.clip();
self.ctx.drawImage(self.srcImg, 0, 0);
self.ctx.restore();
},
// Get the percentage scratched and return it
scratchPercentage: function (self) {
var hits = 0;
var imageData = self.ctx.getImageData(0, 0, self.canvasElem[0].width, self.canvasElem[0].height).data;
var pixels = imageData.length;
for (var i = 0, ii = pixels; i < ii; i = i + 4) {
if (imageData[i] === 0 &&
imageData[i + 1] === 0 &&
imageData[i + 2] === 0 &&
imageData[i + 3] === 0) {
hits++;
}
}
return ((pixels - (hits * 4)) / pixels) * 100;
}
};
$.fn.scratchPlugin = function (options) {
return this.each(function () {
var scratchPlugin = Object.create(ScratchPlugin);
scratchPlugin.init(options, this);
});
};
//Defaults
$.fn.scratchPlugin.options = {
foreGroundImage: null,
backGroundImage: null,
scratchRadius: 15,
complete: function ($elem, percentScratched) {}
};
})(jQuery, window, document);