Home > Web Front-end > H5 Tutorial > body text

Example details of HTML5 Canvas practical scratch effect

黄舟
Release: 2017-03-30 11:15:57
Original
1776 people have browsed it

In recent years, due to the better support of mobile devices for HTML5, there are often activities I have been reading about the effect of scratching prizes recently, and I have implemented one myself. Now I will share it with you.

1, Effect

2, Principle

##. #The principle is very simple, that is, add two

canvas in the scratch area. The first canvas is used to display the content after scratching, which can be a picture or a String, the second canvas is used to display the coating. It can be filled with a picture or a solid color. The second canvas covers the first canvas.

When it is on the second canvas. When you click or smear on the canvas (click and drag the mouse), make the clicked area transparent, so that you can see the content on the first canvas, which achieves the scratching effect.

3. Implementation.

(1) Define the Lottery class

function Lottery(id, cover, coverType, width, height, drawPercentCallback) {
    this.conId = id;
    this.conNode = document.getElementById(this.conId);
    this.cover = cover || '#CCC';
    this.coverType = coverType || 'color';
    this.background = null;
    this.backCtx = null;
    this.mask = null;
    this.maskCtx = null;
    this.lottery = null;
    this.lotteryType = 'image';
    this.width = width || 300;
    this.height = height || 100;
    this.clientRect = null;
    this.drawPercentCallback = drawPercentCallback;
}
Copy after login

Explain the parameters:

  • id: the id of the scratch container

  • cover: Coating content, which can be an image address or color value, can be empty, the default is #ccc

  • ##coverType: coating type, the value is image or color, Can be empty, the default is color
  • width: the width of the scratch area, the default is 300px, can be empty
  • height: the height of the scratch area, The default is 100px, it can be empty
  • drawPercentCallback: The percentage callback of the scraped area, it can be empty
  • Then it also defines several things that need to be used The
Variables

:

    background: the first canvas element
  • backCtx: the 2d context of the background element
  • mask: the second canvas element
  • maskCtx: the 2d context of the mask element
  • lottery: The content displayed after scratching, which can be an image address or a string
  • lotteryType: The content type displayed after scratching, the value is image or text, and must be followed by
  • lottery

    Match

  • clientRect: used to record the
  • getBoundingClientRect() value of the mask element

(2) Add two canvases to the scratch container and obtain the 2d context

this.background = this.background || this.createElement('canvas', {
    style: 'position:absolute;left:0;top:0;'
});
this.mask = this.mask || this.createElement('canvas', {
    style: 'position:absolute;left:0;top:0;'
});

if (!this.conNode.innerHTML.replace(/[\w\W]| /g, '')) {
    this.conNode.appendChild(this.background);
    this.conNode.appendChild(this.mask);
    this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null;
    this.bindEvent();
}

this.backCtx = this.backCtx || this.background.getContext('2d');
this.maskCtx = this.maskCtx || this.mask.getContext('2d');
Copy after login
The createElement tool method is used here, and the

event

is also bound, later introduce.

(3) Draw the first canvas

The first canvas is divided into two types, image and

string, if Just use drawImage of canvas directly for the picture. If it is a string, fill it with white first, and then draw the string in the center of the top, bottom, left, and right. The code is as follows:

if (this.lotteryType == 'image') {
    var image = new Image(),
        _this = this;
    image.onload = function () {
        _this.width = this.width;
        _this.height = this.height;
        _this.resizeCanvas(_this.background, this.width, this.height);
        _this.backCtx.drawImage(this, 0, 0);
    }
    image.src = this.lottery;
} else if (this.lotteryType == 'text') {
    this.width = this.width;
    this.height = this.height;
    this.resizeCanvas(this.background, this.width, this.height);
    this.backCtx.save();
    this.backCtx.fillStyle = '#FFF';
    this.backCtx.fillRect(0, 0, this.width, this.height);
    this.backCtx.restore();
    this.backCtx.save();
    var fontSize = 30;
    this.backCtx.font = 'Bold ' + fontSize + 'px Arial';
    this.backCtx.textAlign = 'center';
    this.backCtx.fillStyle = '#F60';
    this.backCtx.fillText(this.lottery, this.width / 2, this.height / 2 + fontSize / 2);
    this.backCtx.restore();
}
Copy after login
(4) Draw the second A canvas

The second canvas can also be filled with image or color.

There is a difficulty here, that is, how to make the mouse click area transparent? The answer is here: developer.mozilla.org/en/docs/Web/Guide/HTML/Canvas_tutorial/Compositing

That is, we need to set the

globalCompositeOperation of maskCtx to destination-out. For detailed usage, please refer to Link given above.

Therefore, the code to draw the second canvas is as follows:

this.resizeCanvas(this.mask, this.width, this.height);
if (this.coverType == 'color') {    
this.maskCtx.fillStyle = this.cover;    
this.maskCtx.fillRect(0, 0, this.width, this.height);    
this.maskCtx.globalCompositeOperation = 'destination-out';
} else if (this.coverType == 'image'){    var image = new Image(),
        _this = this;
    image.onload = function () {
        _this.maskCtx.drawImage(this, 0, 0);
        _this.maskCtx.globalCompositeOperation = 'destination-out';
    }
    image.src = this.cover;
}
Copy after login

Here resizeCanvas is a tool method for changing the size of the canvas.

(5) Binding events

After the drawing is completed, the event must be bound to the second canvas. There are two situations here: mobile devices and PC-WEB. Mobile devices have touchstart and touchmove events, and the corresponding PC-WEB events are

key

down and mousemove events. In addition, in PC-WEB mode, a mouseup event must be bound to the document to determine whether the mouse is pressed. The code is as follows:

Here, the mouse coordinates are taken out in the event, and drawPoint is called to draw, which will be discussed below.

(6) Draw the click and smear area

The radial gradient of canvas is used here to draw a circle at the mouse pointer. The code is as follows:

drawPoint: function (x, y) {
    this.maskCtx.beginPath();
    var radgrad = this.maskCtx.createRadialGradient(x, y, 0, x, y, 30);
    radgrad.addColorStop(0, 'rgba(0,0,0,0.6)');
    radgrad.addColorStop(1, 'rgba(255, 255, 255, 0)');
    this.maskCtx.fillStyle = radgrad;
    this.maskCtx.arc(x, y, 30, 0, Math.PI * 2, true);
    this.maskCtx.fill();
    if (this.drawPercentCallback) {
        this.drawPercentCallback.call(null, this.getTransparentPercent(this.maskCtx, this.width, this.height));
    }
}
Copy after login

(7) Percentage of smeared area

In many cases, we also need to know how much the user has smeared before proceeding to the next interaction. For example, when the user has smeared 80%, the next step is allowed. One display.

How to calculate this percentage? In fact, it is very simple. We can use the getImageData method to specify the pixel data of the rectangle on the canvas. Since each pixel is represented by rgba, and the painted area is transparent, we only need to judge the value of the alpha channel to know. Is it transparent? The code is as follows:

getTransparentPercent: function(ctx, width, height) {
    var imgData = ctx.getImageData(0, 0, width, height),
        pixles = imgData.data,
        transPixs = [];
    for (var i = 0, j = pixles.length; i < j; i += 4) {
        var a = pixles[i + 3];
        if (a < 128) {
            transPixs.push(i);
        }
    }
    return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
}
Copy after login
(8) Call the entrance init

Finally, provide an entrance for drawing and resetting. The code is as follows:

init: function (lottery, lotteryType) {
    this.lottery = lottery;
    this.lotteryType = lotteryType || &#39;image&#39;;
    this.drawLottery();
}
Copy after login

At this point, All key codes have been explained.

The above is the detailed content of Example details of HTML5 Canvas practical scratch effect. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template