HTML5 Achieve Scratch Award effect

Source: Internet
Author: User

Original: HTML5 Achieve Scratch Award effect

To achieve this, the most important thing is to find a way: When you scratch the upper layer of the coating, you can see the results below. HTML5 's Canvas API has a property globalcompositeoperation, which has multiple values, and the value that is used to achieve the scratch effect is destination-out. This means: In places where existing content and new graphics do not overlap, the content is retained and all other content becomes transparent. This may not be easy to understand and will be explained when implemented later. With the Globalcompositeoperation attribute, the implementation process is simple.

We need to have two layers, the upper layer must be a canvas element, because the canvas must be used to scrape it off. The following layer in fact with what elements can be, since the top with the canvas element, the lower level we also use the canvas element, the following is the HTML content:

<!DOCTYPE html>

Implement a constructor first:

var Scratch = function (options) {// 下层画布元素 this.underCanvas = doc.getElementById("underCanvas"); // 上层画布元素 this.upCanvas = doc.getElementById("upCanvas"); // 获取下层画布绘图上下文 this.underCtx = this.underCanvas.getContext("2d"); // 获取上层画布绘图上下文 this.upCtx = this.upCanvas.getContext("2d"); // 画布宽度 this.width = this.upCanvas.width; // 画布高度 this.height = this.upCanvas.height; // 自定义选项 this.options = options; this.award = null;};

Draw a scratch on the lower canvas:

drawText: function () { var ctx = this.underCtx; var text = this.options.text; ctx.font = text.fontWeight + " " + text.fontSize + 'px ' + text.fontFamily; ctx.textAlign = text.align; ctx.fillStyle = text.color; this.award = this.options.awards[(Math.random() * this.options.awards.length) | 0]; //随机抽奖 ctx.fillText(this.award, this.width / 2, this.height / 2 + text.fontSize / 2);}

The content of this award is random, because there must be many kinds of prizes, you can use an array to hold the content of the prize, and then randomly display:

this.award = this.options.awards[(Math.random() * this.options.awards.length) | 0];

If you do not know what the above bit arithmetic means, you can refer to the previous article I wrote, "The use of JS median operation."

Then draw a layer of coating in the upper canvas:

drawMask: function () { var ctx = this.upCtx; ctx.fillStyle = this.options.maskColor; ctx.fillRect(0, 0, this.width, this.height); ctx.globalCompositeOperation = 'destination-out';}

The Globalcompositeoperation property is used in the upper canvas, and when you draw something on the canvas, the contents of the back and the overlapping portions of the coating become transparent, while the rest of the coating is unchanged. Is the use of this principle to achieve the effect of scraping award.

To scrape off the upper layer of the coating, you need to bind the event on the upper canvas:

Addevent:function () {var = this; var upcanvas = This.upcanvas; var callback1, Callback2, Callback3; Upcanvas.addeventlistener ("MouseDown", Callback1 = function (evt) {Upcanvas.addeventlistener ("MouseMove", callback 2 = function (evt) {var x = Evt.clientx-upcanvas.offsetleft; var y = evt.clienty-upcanvas.offsettop; var ctx = That.upctx; var options = that.options; Ctx.beginpath (); var gradient = ctx.createradialgradient (x, y, 0, X, y, Options.radius); In fact, the color value here can be casually written, because it will become transparent, it is important to transparency Gradient.addcolorstop (0, "rgba (255, 255, 255, 0.5)"); Gradient.addcolorstop (1, "Rgba (255, 255, 255, 0)");//can also be used without gradients, directly with a color, but the gradient effect is better ctx.fillstyle = gradient; Ctx.arc (x, y, Options.radius, 0, Math.PI * 2, true); Ctx.fill (); Ctx.closepath ();//When scraping part >80%, remind the scratch result, this can be set yourself if (That.result () > 0.8) {alert(That.award); Upcanvas.removeeventlistener ("MouseMove", Callback2); }}, False); Doc.addeventlistener ("MouseUp", Callback3 = function () {Upcanvas.removeeventlistener ("MouseMove", Callback2); Doc.removeeventlistener ("MouseUp", CALLBACK3); }, False); }, False);}

We need to remind you of the results of the scratch when we scrape to a certain extent:

result: function () {// 获取文字部分的宽、高 var textWidth = this.options.text.fontSize * this.award.length; var textHeight = this.options.text.fontSize; // 获取文字部分的像素,这样可以根据刮开文字的部分占全部文字部分的百分比来提示结果,比如说在刮开80%的时候提示刮奖结果 var imgData = this.upCtx.getImageData(this.width / 2 - textWidth / 2, this.height / 2 - textHeight / 2, textWidth, textHeight); var pixelsArr = imgData.data; var transPixelsArr = []; for (var i = 0, j = pixelsArr.length; i < j; i += 4) { // a代表透明度 var a = pixelsArr[i + 3]; // 渐变的透明度<=0.5,其实透明度的值是介于0~255之间的,0.5 * 255 = 127.5就是a的值 if (a < 128) { transPixelsArr.push(a); } } // 小于128的透明度的值的个数占总透明度的的个数的百分比 return transPixelsArr.length / (pixelsArr.length / 4);}

This method uses the Getimagedata () method, which returns the pixel data. The important thing is that we just get the pixel data from the underlying text, because we just need to know the percentage of the entire text portion of the scratched text.

When the constructor is called, the possible changes are passed to the constructor in an object options:

// 可能变化的值放在options中,方便修改var options = {// 文字部分的样式 text: { fontWeight: "bold", fontSize: 30, fontFamily: "Arial", align: "center", color: '#F60' },// 图层颜色 maskColor: "red",// 画逼半径 radius: 20,// 奖项 awards: ["一等奖", "二等奖", "三等奖", "谢谢!"]};new Scratch(options).init();

Complete code to view Github:https://github.com/lwzhang/scratch

Demo:http://lwzhang.github.io/scratch/scratch.html

HTML5 Achieve Scratch Award effect

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.