Heim  >  Artikel  >  Web-Frontend  >  Beispieldetails des praktischen Scratch-Effekts von HTML5 Canvas

Beispieldetails des praktischen Scratch-Effekts von HTML5 Canvas

黄舟
黄舟Original
2017-03-30 11:15:571769Durchsuche

In den letzten Jahren gab es aufgrund der besseren Unterstützung mobiler Geräte für HTML5 Ich habe kürzlich auch einen H5-Inhalt gelesen und ihn mit allen geteilt.

2 >

Das Prinzip ist sehr einfach, das heißt, fügen Sie zwei

Leinwände

im Scratch-Bereich hinzu. Der erste Canvas wird verwendet, um den Inhalt nach dem Scratchen anzuzeigen. Es kann ein

Bild sein oder eine Zeichenfolge , die zweite Leinwand wird zur Anzeige der Beschichtung verwendet, die mit einem Bild oder einer Volltonfarbe gefüllt werden kann. Die zweite Leinwand bedeckt die erste Leinwand , wenn sie sich in der zweiten befindet . Machen Sie beim Klicken oder Verschmieren (Klicken und Ziehen mit der Maus) den angeklickten Bereich transparent, damit Sie den Inhalt auf der ersten Leinwand sehen können.

3.

(1) Definieren Sie die Lotterieklasse

Erklären Sie die Parameter:

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;
}

id: die ID des Rubbelcontainers
  • cover: Beschichtungsinhalt, der eine Bildadresse oder ein Farbwert sein kann, kann leer sein und der Standardwert ist #ccc
  • coverType: Beschichtungstyp, Der Wert ist Bild oder Farbe, kann leer sein, der Standardwert ist Farbe
  • Breite: Die Breite des Scratch-Bereichs, der Standardwert ist 300 Pixel, kann leer sein
  • height: Höhe des Scratch-Bereichs, Standard ist 100 Pixel, nullbar
  • drawPercentCallback: Rückruf in Prozent des Scraped-Bereichs, nullbar
  • Anschließend werden mehrere Anforderungen definiert. Verwendete
  • Variablen
:

Hintergrund: das erste Canvas-Element
  • backCtx: 2D-Kontext des Hintergrundelement (Kontext)
  • Maske: das zweite Canvas-Element
  • maskCtx: 2D-Kontext des Maskenelements
  • Lotterie: Der nach dem Rubbeln angezeigte Inhalt, der eine Bildadresse oder eine Zeichenfolge sein kann
  • Lotterietyp: Der nach dem Rubbeln angezeigte Inhaltstyp, der Wert ist Bild oder Text, to be Matches
  • lottery

    clientRect: wird zum Aufzeichnen des
  • getBoundingClientRect()-Werts des Maskenelements
  • verwendet
  • (2) Fügen Sie dem Scratch-Container zwei Leinwände hinzu und erhalten Sie den 2D-Kontext

Hier wird die Werkzeugmethode createElement und auch das Ereignis

verwendet gebunden.
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');

(3) Zeichnen Sie die erste Leinwand

Die erste Leinwand ist in zwei Typen unterteilt: Bild und Zeichenfolge

, wenn nur verwendet Wenn es sich um eine Zeichenfolge handelt, füllen Sie sie zuerst mit Weiß und zeichnen Sie dann die Zeichenfolge oben, unten, links und rechts. Der Code lautet wie folgt:

(4) Zeichnen der zweiten Leinwand

Die zweite Leinwand kann auch mit Bild oder Farbe gefüllt werden.
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();
}

Hier gibt es eine Schwierigkeit: Wie macht man den Mausklickbereich transparent? Die Antwort ist hier: Developer.mozilla.org/en/docs/Web/Guide/HTML/Canvas_tutorial/Compositing

d. h. wir werden maskCtx's

zeichnen, also das zweite Der Code von Canvas lautet wie folgt:

globalCompositeOperation 设置为 destination-out ,详细的用法请参考上面给出的链接。

Hier ist resizeCanvas eine Werkzeugmethode zum Ändern der Größe von Canvas.

(5) Ereignisse binden
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;
}

Nach Abschluss der Zeichnung binden Sie das Ereignis an die zweite Leinwand. Hier gibt es zwei Situationen: mobile Geräte und PC-WEB. Mobile Geräte verfügen über Touchstart- und Touchmove-Ereignisse, und die entsprechenden PC-WEB-Ereignisse sind

Tasten-

Ereignisse. Darüber hinaus muss im PC-WEB-Modus ein Mouseup-Ereignis an das Dokument gebunden werden, um zu bestimmen, ob das Maus gedrückt wird. Der Code lautet wie folgt:

Hier werden die Mauskoordinaten im Ereignis herausgenommen und drawPoint zum Zeichnen aufgerufen, was weiter unten erläutert wird.

(6) Zeichnen Sie den Klick- und Verwischbereich
bindEvent: function () {
    var _this = this;
    var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
    var clickEvtName = device ? 'touchstart' : 'mousedown';
    var moveEvtName = device? 'touchmove': 'mousemove';
    if (!device) {
        var isMouseDown = false;
        document.addEventListener('mouseup', function(e) {
            isMouseDown = false;
        }, false);
    }
    this.mask.addEventListener(clickEvtName, function (e) {
        isMouseDown = true;
        var docEle = document.documentElement;
        if (!_this.clientRect) {
            _this.clientRect = {
                left: 0,
                top:0
            };
        }
        var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientLeft;
        var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientTop;
        _this.drawPoint(x, y);
    }, false);

    this.mask.addEventListener(moveEvtName, function (e) {
        if (!device && !isMouseDown) {
            return false;
        }
        var docEle = document.documentElement;
        if (!_this.clientRect) {
            _this.clientRect = {
                left: 0,
                top:0
            };
        }
        var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientLeft;
        var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientTop;
        _this.drawPoint(x, y);
    }, false);
}

Der radiale Farbverlauf der Leinwand wird hier verwendet, um einen Kreis am Mauszeiger zu zeichnen. Der Code lautet wie folgt:

(7) Prozentsatz der verschmierten Fläche

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));
    }
}

In vielen Fällen müssen wir auch wissen, wie viel der Benutzer verschmiert hat, bevor wir mit der nächsten Interaktion fortfahren. Wenn der Benutzer 80 % verschmiert hat, wird die nächste angezeigt.

Wie berechnet man diesen Prozentsatz? Tatsächlich ist es sehr einfach, die Pixeldaten des Rechtecks ​​auf der Leinwand mit der Methode getImageData anzugeben. Da jedes Pixel durch RGBA dargestellt wird und der gemalte Bereich transparent ist, müssen wir nur den Wert beurteilen Alphakanal zu wissen. Ist er transparent? Der Code lautet wie folgt:

(8) Rufen Sie den Eingang init auf

und stellen Sie schließlich einen Eingang zum Zeichnen und Zurücksetzen bereit. Der Code lautet wie folgt:
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);
}

An dieser Stelle wurden alle Schlüsselcodes erklärt.

Das obige ist der detaillierte Inhalt vonBeispieldetails des praktischen Scratch-Effekts von HTML5 Canvas. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn