Heim  >  Artikel  >  Web-Frontend  >  Lernen Sie beim Spielen mit HTML5 (6) – Detaillierte Einführung in Autobots und Transformationen

Lernen Sie beim Spielen mit HTML5 (6) – Detaillierte Einführung in Autobots und Transformationen

黄舟
黄舟Original
2017-03-29 15:07:211674Durchsuche

1. Zustand und seine Erhaltung und Wiederherstellung

Bevor wir mit diesem Abschnitt beginnen, müssen wir zunächst verstehen, was Zustand und die Erhaltung und Wiederherstellung von Staat ist. Leute, die mit MFC-Programmierung experimentiert haben, stoßen oft auf Code wie diesen:

pOldPen=pDC->SelectObject(pNewPen)

Wenn wir ein neues Pinselobjekt auswählen, müssen wir es immer speichern. Lebe das alte Pinselobjekt. Warum willst du das tun? Da das neue Pinselobjekt nur zur vorübergehenden Verwendung dient und wir die ursprüngliche Pinselkonfiguration wiederherstellen möchten, gehen diese Konfigurationen verloren und es gibt keine Möglichkeit, sie wiederherzustellen.

Beim HTML5-Zeichnen ist der Zustand zu einem bestimmten Zeitpunkt der Konfigurationswert einer Reihe von Eigenschaften des Kontextobjekts zum aktuellen Zeitpunkt. Es gibt jedoch relativ wenige Eigenschaften, die den Zustand eines Pinsels bestimmen, wie z B. Farbe, Dicke, Linientyp usw., und es gibt viele Attribute, die den Kontextstatus bestimmen, einschließlich der folgenden:

1. Die Bewegungs-, Rotations- und Skalierungskonfiguration des aktuellen Kontextobjekts

2. Die Attributwerte „StrokeStyle“, „fillStyle“, „globalAlpha“ des aktuellen Kontextobjekts „lineWidth“, „lineCap“, „lineJoin“, „miterLimit“, „shadowOffsetX“, „shadowOffsetY“, „shadowBlur“, „shadowColor“ und „globalCompositeOperation“ aktuelles Kontextobjekt

Die obige Reihe von Konfigurationen bestimmt den aktuellen Moment des Kontextobjekts, einschließlich

Bewegung, Drehung, Skalierung, globalCompositeOperation (Kombination) und Zuschneiden

, über die wir sprechen werden es bald.

2. Speichern und Wiederherstellen des Zustands

Oben haben wir gesagt, dass der Zustand zu einem bestimmten Zeitpunkt durch so viele Attribute bestimmt wird, ob wir den Zustand zu diesem Zeitpunkt speichern wollen Im Moment müssen wir diese Attribute verwenden. Es wäre zu mühsam, die Werte einzeln zu speichern und sie beim Wiederherstellen einzeln zurückzusetzen. Dies ist in der Tat der Fall, daher bietet der Kontext zwei einfache Methoden zum Speichern und Wiederherstellen des Status:

save( ) undwiederherstellen( )

speichern und wiederherstellen Die Methode kann aufgerufen werden Bei jedem Aufruf der Speichermethode wird der Status zum Zeitpunkt des Aufrufs (d. h. eine Reihe von Attributwerten) in einen Stapel verschoben.

Jedes Mal, wenn die Wiederherstellungsmethode aufgerufen wird, wird der Status der letzten Speicherung wiederhergestellt, d. h. vom Stapel entfernt.

Stellen Sie sich ein Magazin vor. Die erste abgefeuerte Kugel ist immer die letzte, die in das Magazin gedrückt wird.

3. Variation

1. Bewegen Sie:

übersetzen

(dx,dy)dieses Die Methode scheint sehr einfach zu sein, enthält aber tatsächlich bestimmte mathematische Bedeutungen. Sie können davon ausgehen, dass sich der Ursprung des gesamten Koordinatensystems bewegt hat. Jeder Punkt (x, y) im neuen Koordinatensystem entspricht den Koordinaten in der ursprünglichen Koordinate System:

x'=x+dx

y'=y+dy


Wenn wir ctx.translate(5,8) aufrufen, um den Koordinatensystemstatus des Kontextobjekts zu ändern , dann entspricht das Zeichnen am Punkt (3,2) im neuen Zustand dem Zeichnen des Bildes am Punkt (8,10) im Originalzustand, d. h.

x'=5+3=8

y'=5+ 2=10


Vielleicht fragen Sie sich, warum man sich so viel Mühe gibt? Ist es in Ordnung, den Vergleich direkt bei (8,10) zu ziehen? Ändern Sie beispielsweise

ctx.translate(5,8)

ctx.drawImage(img,3,2)


in

ctx.drawImage(img, 8 ,10)

Ist das nicht einfacher und direkter?

Wenn die Bewegung größer ist, kann eine entsprechende Änderung des Koordinatenursprungs dazu führen, dass Grafikberechnungen besser verstanden werden und ein einfaches Beispiel gegeben werden :

hat ein Liniensegment, das ein kleines Segment in der positiven Richtung der x-Achse ist

y = 0 (1 <= x <= 3),

Wenn Sie den Koordinatenursprung als Mittelpunkt des Kreises nehmen und ihn um 90 Grad gegen den Uhrzeigersinn drehen, fällt das Liniensegment mit der positiven Richtung der y-Achse zusammen. Das gedrehte Liniensegment ist:

x = 0 (1 <= y <= 3)

Aber es ist für uns unmöglich, jedes Mal mit dem Ursprung als Mittelpunkt des Kreises zu rotieren, wenn wir mit einem Endpunkt (1,0) rotieren. Wie können wir nach der Drehung des Liniensegments den Koordinatenwert jedes Punkts auf dem Liniensegment ermitteln? Tatsächlich kann dieser Vorgang in drei Schritte unterteilt werden:

Schritt 1:

Verschieben Sie die

Ursprungskoordinate nach (1,0). Das neue Liniensegment befindet sich immer noch auf der x-Achse. aber die Gleichung lautet: y = 0 (0 <= x <= 2)Schritt 2:

drehen

mit dem Ursprung des neuen Koordinatensystems als Mittelpunkt des Kreises, und erhalte das Liniensegment x = 0 unter dem neuen Koordinatensystem (0 <= y <= 2)Schritt 3: Verschieben Sie den Ursprung

des neuen Koordinatensystems

nach (- 1,0) unter dem neuen Koordinatensystem, das heißt, den Ursprung wiederherstellen An der ursprünglichen Position ist das Liniensegment zu diesem Zeitpunkt: x = 1 (0 <= y <= 2)Die Das im dritten Schritt erhaltene Liniensegment ist das letzte Liniensegment, das gezeichnet werden muss.

An diesem Beispiel können wir erkennen, dass es selbst in einem so einfachen Fall schwierig ist, die gedrehte Figur direkt zu berechnen, ohne den Koordinatenursprung zu verschieben.

Tipps

: Bevor Sie den Koordinatenursprung verschieben, vergessen Sie nicht, den Zustand zu speichern. Stellen Sie den Zustand nach dem Zeichnen natürlich nicht wieder her. 2. Skalierung

Skalierung

(sx, sy)Dies sind auch sehr einfache Skalierungsfaktoren und die neuen Koordinaten nach der Skalierung Jeder Punkt (x,y) im System entspricht den Koordinaten im ursprünglichen Koordinatensystem:

x' = x * sx

y' = y * sy

Ebenso Vergessen Sie immer nicht, den Status zu speichern und wiederherzustellen, wenn Sie das Koordinatensystem ändern

3. Drehendrehen(A)

Winkel ist Rotationswinkel, jeder Punkt (x, y) im neuen Koordinatensystem nach der Drehung entspricht den Koordinaten im ursprünglichen Koordinatensystem:

x' = x cosA - y sinA
y ' = x sinA + y cosA

Ebenso Vergessen Sie nicht, den Zustand zu speichern und wiederherzustellen, wenn Sie das Koordinatensystem ändern

4 (m11, m12, m21, m22, dx, dy)

Tatsächlich sind die zuvor erwähnten Bewegungen, Skalierungen und Rotationen Sonderfälle der Transformation. Die sechs Parameter der Transformationsmethode bilden eine Transformation Matrix wie folgt

Das Aufrufen der Transformationsmethode entspricht der Verwendung dieser Parameter zum Festlegen einer neuen Transformationsmatrix für das Kontextobjekt. Den spezifischen Inhalt der Transformationsmatrix finden Sie unter Grafiken Verwandte Informationen, hier sind ein paar einfache Sonderfälle:

Move translator(dx,dy): entspricht transform(1,0,0,1 ,dx,dy)

Skalenskala(sx,xy): entspricht transform(sx,0,0,sy,0,0)

rotieren(A) : Äquivalent zu transform(cosA,sinA,-sinA,cosA,0,0)

Verwenden von (dx,dy) als Referenzpunkt zum Drehen von Winkel A: transformieren (cosA, sinA, -sinA, cosA, dx(1-cosA) + dysinA, dy(1-cosA) - dxsinA)

Verwenden Sie (dx,dy) als Referenzpunkt um eine (sx,sy)-Skalierung durchzuführen. Skalierung: transform(sx, 0, 0, sy, dx(1-sx), dy(1-sy))

Es gibt viele andere Komplexere Transformationen finden Sie in den grafikbezogenen Informationen.

Das Folgende ist ein Beispiel für eine Referenzpunktverformung. Wenn die Maus auf einem bestimmten Punkt im Bild gedrückt gehalten wird, wird das Bild skaliert oder gedreht, wobei dieser Punkt als Referenzpunkt verwendet wird nach dem Loslassen der Taste.

Tipp: Dieses Beispiel für Skalierung und Rotation verwendet keine Verformungsmatrix, sondern besteht aus vier einfachen Verformungen. Der Effekt ist wie folgt:


Verschieben – halten Sie die Maus auf dem Bild gedrückt und verschieben Sie es
Referenzpunktskalierung – halten Sie die Maus an einem bestimmten Punkt im Bild gedrückt
Referenzpunkt Drehung – an einem bestimmten Punkt im Bild. Halten Sie die Maus an einem Punkt gedrückt.
Der Referenzpunkt zoomt und dreht sich gleichzeitig. Halten Sie die Maus an einem bestimmten Punkt des Bildes gedrückt.

4. Kombination

Die sogenannte Kombination ist der Effekt, der auftritt, wenn eine Grafik über einer anderen Grafik gezeichnet wird. Standardmäßig deckt die obere Grafik die untere Grafik ab, was als Source-Over bezeichnet wird.

Kontextobjekt verfügt über insgesamt zwölf Kombinationstypen. Das Attribut globalCompositeOperation wird verwendet, um den Kombinationstyp wie folgt festzulegen:

globalCompositeOperation = Typ

Typ ist einer der Folgende 12 String-Werte 1:

Hinweis: In allen obigen Beispielen wird zuerst das blaue Quadrat gezeichnet, also „vorhandener Canvas-Inhalt“ . Der rote Kreis ist der nach gezeichnete, also die „neue Form“.

5. Beschneidungspfad

Im ersten Artikel haben wir zwei Haupttypen von Zeichenmethoden für Kontextobjekte vorgestellt, nämlich

Strich Reihe von Methoden und die Reihe fill, die den Bereich ausfüllt. Tatsächlich verfügt das Kontextobjekt auch über eine Art Zeichenmethode namens Clipping Clip. Was ist Zuschneiden? Um eine unangemessene Analogie zu verwenden: Sie decken den Fernsehbildschirm mit einem Stück Stoff ab. Zu diesem Zeitpunkt können Sie keine Veränderungen auf dem Fernsehbildschirm sehen.

Wenn man jedoch einen Bereich auf dem Tuch ausschneidet, dann sieht man zumindest die Bildschirmveränderungen in diesem Bereich.

Natürlich

der Bildschirm außerhalb des Zuschneidebereichs ändert sich auch ständig (d. h. er wird auch neu gezeichnet), aber man kann ihn nicht sehen

. Dies wird als Zuschneiden bezeichnet und ist bei der Verarbeitung von Bildern häufig erforderlich. Was ist also der

Beschneidungspfad

? Es heißt, dass Sie einen Bereich auf dem Stoff ausschneiden müssen. Woher kommt dieser Bereich? Dieser Bereich wird durch den Zeichenpfad vor der Beschneidungsaktion

Clip

festgelegt. Es kann sich um ein Quadrat, einen Kreis, einen Fünfstern oder jede andere Umrissform handeln, die gezeichnet werden kann. Der Beschneidungspfad ist also eigentlich der Zeichenpfad, aber dieser Pfad wird nicht zum Zeichnen verwendet, sondern um eine Trennlinie zwischen dem Anzeigebereich und dem Okklusionsbereich festzulegen.

Wenn Sie nicht verstehen, was ein Zeichenpfad ist, wird er im vorherigen Artikel HTML5 Learning by Play (2): Grundlegendes Zeichnen vorgestellt.

Das folgende Beispiel verwendet zwei Methoden zum Zuschneiden. Die erste Methode zeigt einen kreisförmigen Zuschneidebereich an, der sich hin und her bewegt. Der allgemeine Vorgang ist wie folgt:

1. Löschen Sie die Leinwand

2. Ändern Sie die Mittelposition des Kreises

3. Legen Sie im neuen Bereich einen kreisförmigen Zuschneidebereich in der Mitte des Kreises fest

4. Zeichnen Sie ein schönes Bild auf die Leinwand

Da wir den Zuschneidebereich immer wieder an neuen Positionen festlegen , wir können den Zuschneidebereich sehen. Während der Bewegung wird das Bild außerhalb des Zuschneidebereichs nicht angezeigt.

Wir verwenden die Clip-Methode, um den Zuschneidebereich festzulegen. Die anschließend gezeichneten Grafiken können nur einen Teil des Zuschneidebereichs anzeigen Die Leinwand wird immer außerhalb der Hintergrundfarbe des Zuschneidebereichs angezeigt.

Wenn Sie beispielsweise das Bild außerhalb des Zuschneidebereichs nicht vollständig blockieren möchten, möchten wir, dass das Bild innerhalb des Zuschneidebereichs vollständig angezeigt wird, das Bild außerhalb des Zuschneidebereichs jedoch halb angezeigt wird -transparente Art und Weise, was sollen wir tun?

Dies erfordert das oben erwähnte Kombinationswissen. Die zweite Methode zeigt die durchscheinende Farbe an:

1. Füllen Sie alle Bereiche der Leinwand mit einer durchscheinenden Farbe , mit Transparenz 0,9

3. Ändern Sie die Mittelposition des Kreises

4、在新的圆心位置处以 XOR 方式绘制圆,这样和圆形重叠的部分将被擦除掉
这时候我们得到的图形效果是一个半透明的画布,上面有一块完全透明的圆形区域

5、 在第 4 步的基础上,以 destination-over 方式绘制美女图像,这时候美女图像将会出现在第 4 步图形效果的下方,想象一下,正好是我们想要的效果吧?!

代码



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><canvas id="canvas1" width="250" height="300" 

    onmousedown="trans.transform(event);"  

    onmouseup="trans.init(event);" 

    onmousemove="trans.translate(event);" 

    style="background-color:black">

    你的浏览器不支持 &lt;canvas&gt;标签,请使用 Chrome 浏览器 或者 FireFox 浏览器

</canvas><br/>

<input type="radio" name="r" id="r1" checked="checked">移动——在图像上按住鼠标并移动<br />

<input type="radio" name="r" id="r2">基准点缩放——在图像某点处按住鼠标<br />

<input type="radio" name="r"  id="r3">基准点旋转——在图像某点处按住鼠标<br />

<input type="radio" name="r"  id="r4">基准点缩放同时旋转——在图像某点处按住鼠标<br />



<canvas id="canvas3" width="250" height="300" style="background-color:black">

    你的浏览器不支持 &lt;canvas&gt;标签,请使用 Chrome 浏览器 或者 FireFox 浏览器

</canvas><br/>

<input type="button" onclick="move(1);" value="移动裁剪区域">

<input type="button" onclick="move(2);" value="移动蒙版">

<input type="button" onclick="stop();" value="停止移动"><br />



        <div>

            <table>

                <tr>

                    <td><canvas id="tut0" width="125" height="125"></canvas><br/><label id="lab0"></label></td>

                <td><canvas id="tut1" width="125" height="125"></canvas><br/><label id="lab1"></label></td>

                <td><canvas id="tut2" width="125" height="125"></canvas><br/><label id="lab2"></label></td>

                <td><canvas id="tut3" width="125" height="125"></canvas><br/><label id="lab3"></label></td>

                </tr>

                <tr>

                    <td><canvas id="tut4" width="125" height="125"></canvas><br/><label id="lab4"></label></td>

                <td><canvas id="tut5" width="125" height="125"></canvas><br/><label id="lab5"></label></td>

                <td><canvas id="tut6" width="125" height="125"></canvas><br/><label id="lab6"></label></td>

                <td><canvas id="tut7" width="125" height="125"></canvas><br/><label id="lab7"></label></td>

                </tr>

                <tr>

                    <td><canvas id="tut8" width="125" height="125"></canvas><br/><label id="lab8"></label></td>

                <td><canvas id="tut9" width="125" height="125"></canvas><br/><label id="lab9"></label></td>

                <td><canvas id="tut10" width="125" height="125"></canvas><br/><label id="lab10"></label></td>

                <td><canvas id="tut11" width="125" height="125"></canvas><br/><label id="lab11"></label></td>

                </tr>

            </table>

        </div>





<script type="text/javascript">

    //美女图的 Base64 编码

    IMG_SRC=&#39;data:image/gif;base64,/9j/4QDfRXhpZgAASUkqAAgAAAAFABIBAwA......&#39;;//省略四十字节



    //==========================================

    //基准点变形类

    //==========================================

    function Transform(){

        //获取画布对象

        this.ctx = document.getElementById("canvas1").getContext("2d");

        //创建图像对象

        this.img=new Image();

        //指定图像源

        this.img.src=IMG_SRC;

        this.interval = null;

        //鼠标按钮状态

        this.pressed=false;

        this.init();

    }

    

    //初始化图形

    Transform.prototype.init=function(){

        //鼠标按钮状态

        this.pressed=false;

        //停止计时器

        if(this.interval) clearInterval(this.interval);

        //变化值

        this.delta = 0.06;

        //清空

        this.ctx.clearRect(0,0,250,300);

        //重绘

        this.paint();

    }

    

    //绘制图像

    Transform.prototype.paint=function(){

        var that=this;

        var img=this.img

        if(img.complete)

            that.ctx.drawImage(img,0,0);

        else 

            var interval = setInterval(function(){

                if(img.complete){

                    that.ctx.drawImage(img,0,0);

                    clearInterval(interval);

                }

            },300);

    }

    

    //鼠标按钮按下后,开始变形

    Transform.prototype.transform = function(){

        //获取基准点

        this.dx=event.offsetX;

        this.dy=event.offsetY;

        //获取基准点

        this.startx=event.offsetX;

        this.starty=event.offsetY;

        //初始缩放比例

        this.sc=1;

        //初旋转角度

        this.angle=0;

        

        var that=this;

        if(document.getElementById("r1").checked)

            //鼠标按钮状态

            this.pressed=true;

        else if(document.getElementById("r2").checked)

            this.interval = setInterval(function(){that.scale()},50);

        else if((document.getElementById("r3").checked))

            this.interval = setInterval(function(){that.rotate()},50);

        else 

            this.interval = setInterval(function(){that.scaleAndRotate()},50);

    }

    

    //移动

    Transform.prototype.translate = function(){

        this.ddx=event.offsetX-this.startx;

        this.ddy=event.offsetY-this.starty;

        if(this.pressed){

            //清空

            this.ctx.clearRect(0,0,250,300);

            //保存状态

            this.ctx.save();

            //平移

            this.ctx.translate(this.ddx,this.ddy);

            //重绘

            this.paint();

            //绘制基准点

            this.ctx.fillStyle="red";

            this.ctx.fillRect(this.dx-5,this.dy-5,10,10);

            //恢复状态

            this.ctx.restore();

        }

    }



    //缩放变形

    Transform.prototype.scale = function(){

        //清空

        this.ctx.clearRect(0,0,250,300);

        //改变缩放比例

        this.sc=this.sc - this.delta;

        if(this.sc<0.2 || this.sc>2) 

            this.delta = -this.delta;

        //保存状态

        this.ctx.save();

        //以 (dx,dy) 为基准点进行 (sx,sy)比例缩放:transform(sx, 0, 0, sy, dx(1-sx), dy(1-sy))

        this.ctx.transform(this.sc, 0, 0, this.sc, this.dx*(1-this.sc), this.dy*(1-this.sc))

        //用新的变形矩阵重绘

        this.paint();

        //绘制基准点

        this.ctx.fillStyle="red";

        this.ctx.fillRect(this.dx-5,this.dy-5,10,10);

        //恢复状态

        this.ctx.restore();

    }

    

    //旋转变形

    Transform.prototype.rotate = function(){

        //清空

        this.ctx.clearRect(0,0,250,300);

        //改变缩放比例

        var PI = Math.PI;

        this.angle=this.angle + PI/60;

        //保存状态

        this.ctx.save();

        //以 (dx,dy) 为基准点旋转角度 A:transform(cosA, sinA, -sinA, cosA, dx(1-cosA) + dysinA, dy(1-cosA) - dxsinA)

        this.ctx.transform(Math.cos(this.angle), Math.sin(this.angle), 

                -Math.sin(this.angle), Math.cos(this.angle), 

                this.dx*(1-Math.cos(this.angle)) + this.dy*Math.sin(this.angle), 

                this.dy*(1-Math.cos(this.angle)) - this.dx*Math.sin(this.angle))

        //用新的变形矩阵重绘

        this.paint();

        //绘制基准点

        this.ctx.fillStyle="red";

        this.ctx.fillRect(this.dx-5,this.dy-5,10,10);

        //恢复状态

        this.ctx.restore();

    }

    

    //即缩放又旋转变形,没有使用变形矩阵

    Transform.prototype.scaleAndRotate = function(){

        //清空

        this.ctx.clearRect(0,0,250,300);

        //改变缩放比例

        this.sc=this.sc - this.delta;

        if(this.sc<0.2 || this.sc>2) 

            this.delta = -this.delta;

        var PI = Math.PI;

        this.angle=this.angle + PI/60;

        //保存状态

        this.ctx.save();

        //先移动原点到基点

        this.ctx.translate(this.dx,this.dy);

        this.ctx.scale(this.sc,this.sc);

        this.ctx.rotate(this.angle);

        this.ctx.translate(-this.dx,-this.dy);

        //用新的变形矩阵重绘

        this.paint();

        //绘制基准点

        this.ctx.fillStyle="red";

        this.ctx.fillRect(this.dx-5,this.dy-5,10,10);

        //恢复状态

        this.ctx.restore();

    }

    

    var trans = new Transform();

    

    //==========================================

    function Clip(){

        var canvas = document.getElementById("canvas3");

        this.ctx = canvas.getContext("2d");

        this.img=new Image();

        this.img.src=IMG_SRC;

        //移动方向

        this.delta=[3,3];

        //起始点

        this.pos_x = 225;

        this.pos_y = 120;

        //半径

        this.radius = 40;

        //画布的长和宽

        this.w = parseInt(canvas.getAttribute("width"));

        this.h = parseInt(canvas.getAttribute("height"));

    }

    

    Clip.prototype.draw1=function(){

        //碰撞检测

        if (this.pos_x < this.radius) {

            this.delta[0] = Math.random() % 4 + 5;

        } else if (this.pos_x > this.w - this.radius) {

            this.delta[0] = -(Math.random() % 4 + 5);

        }

        if (this.pos_y < this.radius) {

            this.delta[1] = Math.random() % 4 + 5;

        } else if (this.pos_y > this.h - this.radius) {

            this.delta[1] = -(Math.random() % 4 + 5);

        }

        this.pos_x += this.delta[0];

        this.pos_y += this.delta[1];



        this.ctx.clearRect(0, 0, this.w, this.h);

        //保存状态

        this.ctx.save()

        //移动变形

        this.ctx.translate(this.pos_x,this.pos_y);

        //设置裁剪区域

        this.ctx.beginPath();

        this.ctx.arc(0 ,0,this.radius,0,Math.PI*2,true);

        this.ctx.clip();         

        // 将图片画到画布上

        this.ctx.drawImage(this.img, -this.pos_x, -this.pos_y,this.w, this.h);

        //恢复状态

        this.ctx.restore();

    }

    

    Clip.prototype.draw2=function(){

        //碰撞检测

        if (this.pos_x < this.radius) {

            this.delta[0] = Math.random() % 4 + 5;

        } else if (this.pos_x > this.w - this.radius) {

            this.delta[0] = -(Math.random() % 4 + 5);

        }

        if (this.pos_y < this.radius) {

            this.delta[1] = Math.random() % 4 + 5;

        } else if (this.pos_y > this.h - this.radius) {

            this.delta[1] = -(Math.random() % 4 + 5);

        }

        this.pos_x += this.delta[0];

        this.pos_y += this.delta[1];



        this.ctx.clearRect(0, 0, this.w, this.h);

        //绘制灰色的半透明蒙版

        this.ctx.fillStyle="rgba(125,125,125,0.9)"

        this.ctx.fillRect(0, 0, this.w, this.h);

        //保存状态

        this.ctx.save()

        //移动坐标

        this.ctx.translate(this.pos_x,this.pos_y);

        //裁剪透明的圆形区域

        this.ctx.globalCompositeOperation = "xor";   

        this.ctx.fillStyle="white"

        this.ctx.beginPath();

        this.ctx.arc(0 ,0,this.radius,0,Math.PI*2,true);

        this.ctx.fill();       

        // 将图片画到蒙版的下面,即只露出透明区域

        this.ctx.globalCompositeOperation = "destination-over";   

        this.ctx.drawImage(this.img, -this.pos_x, -this.pos_y,this.w, this.h);

        //恢复状态

        this.ctx.restore();

    }



    var cl=new Clip();

    cl.interval=null;

    

    function move(id){      

        if(cl.interval)

            clearInterval(cl.interval)

        if(id==1){

            cl.ctx.clearRect(0, 0, 450, 300);    

            cl.interval=setInterval(function(){cl.draw1()},20);

        }

        else{

            cl.ctx.clearRect(0, 0, 450, 300);    

            cl.interval=setInterval(function(){cl.draw2()},20);

        }

    }



    function stop(){

        clearInterval(cl.interval)

    }

    

    var compositeTypes = [

        &#39;source-over&#39;,&#39;source-in&#39;,&#39;source-out&#39;,&#39;source-atop&#39;,

        &#39;destination-over&#39;,&#39;destination-in&#39;,&#39;destination-out&#39;,&#39;destination-atop&#39;,

        &#39;lighter&#39;,&#39;darker&#39;,&#39;copy&#39;,&#39;xor&#39;

    ];

    function drawComp(){

        for (i=0;i<compositeTypes.length;i++){

            var label = document.createTextNode(compositeTypes[i]);

            document.getElementById(&#39;lab&#39;+i).appendChild(label);

            var ctx = document.getElementById(&#39;tut&#39;+i).getContext(&#39;2d&#39;);



            // draw rectangle

            ctx.fillStyle = "#09f";

            ctx.fillRect(15,15,70,70);



            // set composite property

            ctx.globalCompositeOperation = compositeTypes[i];



            // draw circle

            ctx.fillStyle = "#f30";

            ctx.beginPath();

            ctx.arc(75,75,35,0,Math.PI*2,true);

            ctx.fill();

        }

    }

    drawComp();

</script>

Das obige ist der detaillierte Inhalt vonLernen Sie beim Spielen mit HTML5 (6) – Detaillierte Einführung in Autobots und Transformationen. 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