Ich spiele seit zwei oder drei Wochen mit Canvas und das Spielen mit flachen Objekten ist genauso, also habe ich angefangen, mit 3D herumzuspielen.
Da die Canvas-Leinwand immer noch flach ist, müssen Sie eine Z-Achse abstrahieren, wenn Sie 3D wünschen. Wandeln Sie dann die 3D-Koordinaten in 2D-Koordinaten um, zeichnen Sie sie auf die Leinwand und erzeugen Sie dann mithilfe von Rotations- und anderen Transformationseffekten ein 3D-Gefühl. Bei der Erstellung von 3D geht man im Allgemeinen von Punkten zu Linien und dann von Linien zu Flächen über.
【Punkt】
Wenn Sie darauf klicken, habe ich schon einmal einen Blog-Beitrag über 3D geschrieben. Das Parsen der 3D-Tag-Cloud ist eigentlich sehr einfach. In diesem Blog-Beitrag geht es zwar um die mit div implementierte 3D-Tag-Cloud, aber um die Grundursache Das Prinzip von 3D ist dasselbe, es ist das einfachste 3D, das aus Punkten besteht. Jedes Etikett ist ein Punkt. Sie können sich diese DEMO auch direkt ansehen:
3DBall
Es sind insgesamt fünfhundert Punktobjekte darin enthalten. Jedes Punktobjekt ändert seine Größe und Transparenz entsprechend seiner Z-Achse und verteilt es dann gleichmäßig auf der Kugel eine Punktkugel.
【Linie】
Sobald Sie wissen, wie man Punkte macht, wird die Linie einfach sein, verbinden Sie einfach die Punkte. Ich habe dazu noch keine DEMO gemacht, aber es ist wirklich nicht schwierig. Schleifen Sie einfach „moveTo“ und dann „lineTo“, und die Zeile wird ausgegeben.
【Nudeln】
In diesem Blogbeitrag geht es hauptsächlich um das Gesicht.
Lass uns ohne weitere Umschweife zuerst eine DEMO machen:
3D-Würfel
Um einen Würfel zu erstellen, habe ich drei Objekte verwendet: ein Punktobjekt, ein Flächenobjekt und den Würfel selbst:
Das Folgende ist ein Punktobjekt: x, y, z sind die dreidimensionalen Koordinaten des Punktes. Die _get2d-Methode konvertiert die dreidimensionalen Koordinaten in die zweidimensionale Ebene. fallLength ist die Brennweite.
XML/HTML-CodeInhalt in die Zwischenablage kopieren
- var Vektor = Funktion(x,y,z){
-
this.x = x;
-
this.y = y;
this.z-
= z;
this._get2d
= -
function(){
var scale
= -
fallLength/(fallLength this.z);
var x =
centerX-
this.x*scale;
var y =
centerY-
this.y*scale
return {x:x, y:y};
-
Dann die Zielgruppe:
Die Eigenschaftsseite des Gesichtsobjekts ist leicht zu verstehen. v1v2v3v4 sind die vier Eckpunkte des Gesichts. Es stellt die Ebene des Gesichts dar Dies muss „Ja“ sein, damit beim Zeichnen mit Leinwand diese Fläche vorne gezeichnet werden kann und nicht von anderen Flächen verdeckt wird. Der Wert von zIndex ist ebenfalls leicht zu verstehen. Er ist die durchschnittliche Z-Achsen-Koordinate des Scheitelpunkts, die tatsächlich die Z-Achsen-Koordinate des Mittelpunkts ist. Die Farbe ist die Farbe dieser Oberfläche.
XML/HTML-CodeInhalt in die Zwischenablage kopieren
- var Gesicht = Funktion(vector1,vector2,vector3,vector4,color){
-
this.v1 = vector1;
-
this.v2 = vector2;
-
this.v3 = vector3;
-
this.v4 = vector4;
-
this.color = color;
-
this.zIndex = (this.v1.z this.v2.z this.v3.z this.v4.z)/4;
-
this.draw = function(){
- ctx.save();
- ctx.beginPath();
- ctx.moveTo(this.v1._get2d().x , this.v1._get2d().y);
- ctx.lineTo(this.v2._get2d().x , this.v2._get2d().y);
- ctx.lineTo(this.v3._get2d().x , this.v3._get2d().y);
- ctx.lineTo(this.v4._get2d().x , this.v4._get2d().y);
- ctx.closePath();
-
// ctx.fillStyle = "rgba(" parseInt(Math.random()*255) "," parseInt(Math.random()*255) "," parseInt(Math.random()*255) ",0.2)";
-
ctx.fillStyle = this.color;
- ctx.fill();
- }
- }
最后是立方体本身对象:
因为立方体最后要旋转,所以,立方体对象里面不仅有面对象,还要有点对象,点旋转后才会引起面的旋转.length是立方体的边长,_initVector是初始化立方体的各个顶点,_draw方法就是把所有点形成面, 将面放入数组, 然后对面进行排序(就是根据面里的zIndex排序), 排序好后,调用每个面里的draw方法.立方体就出来了.
XML/HTML-Code复制内容到剪贴板
- var Würfel = Funktion(Länge){
-
this.length = length;
-
this.faces = [];
-
this.vectors = [];
- }
-
Cube.prototype = {
- _initVector:function(){
- this.vectors[0] = new Vector(-this.length/2 , -this.length/2 , this.length/2);
- this.vectors[1] = new Vector(-this.length/2 , this.length/2 , this.length/2);
- this.vectors[2] = new Vector(this.length/2 , -this.length/2 , this.length/2);
- this.vectors[3] = new Vector(this.length/2 , this.length/2 , this.length/2);
- this.vectors[4] = new Vector(this.length/2 , -this.length/2 , -this.length/2);
- this.vectors[5] = new Vector(this.length/2 , this.length/2 , -this.length/2);
- this.vectors[6] = new Vector(-this.length/2 , -this.length/2 , -this.length/2);
- this.vectors[7] = new Vector(-this.length/2 , this.length/2 , -this.length/2);
- },
- _draw:function(){
- this.faces[0] = new Face(this.vectors[0] , this.vectors[1] , this.vectors[3] , this.vectors[2] , "#6c6");
- this.faces[1] = new Face(this.vectors[2] , this.vectors[3] , this.vectors[5] , this.vectors[4] , "#6cc");
- this.faces[2] = new Face(this.vectors[4] , this.vectors[5] , this.vectors[7] , this.vectors[6] , "#cc6");
- this.faces[3] = new Face(this.vectors[6] , this.vectors[7] , this.vectors[1] , this.vectors[0] , "#c6c");
- this.faces[4] = new Face(this.vectors[1] , this.vectors[3] , this.vectors[5] , this.vectors[7] , "#666");
- this.faces[5] = new Face(this.vectors[0] , this.vectors[2] , this.vectors[4] , this.vectors[6] , "#ccc");
-
- this.faces.sort(function(a , b){
- return b.zIndex - a.zIndex;
- });
- this.faces.foreach(function(){
- this.draw();
- })
- }
- }
立方体做好了,接下来就可以让它动起来了。根据鼠标位置改变立方体转动的角度Mit rotateX und rotateY können Sie X drehen und Y drehen原理我在之前那个博文上好像有说过.。。。如果想了解更多, 可以自己去百度一下计算机图形学3 D变换.绕X轴和绕Y轴是最简单的旋转矩阵了.当然,如果有兴趣的还可以去搜一下绕任意轴旋转矩阵Wählen Sie rotateX Drehen Sie Y来了.
XML/HTML-Code复制内容到剪贴板
- if("addEventListener" in window){
- window.addEventListener("mousemove" , function(event){
-
var x = event.clientX - canvas.offsetLeft - centerX;
-
var y = event.clientY - canvas.offsetTop - centerY;
-
Winkel
}); -
}
else {
window.attachEvent("onmousemove" , function(event){ -
var - x
= - event
.clientX - canvas.offsetLeft - centerX; -
var -
y = event.clientY - canvas.offsetTop - centerY;
-
Winkel
});
- }
-
-
- function rotateX(vectors){
-
var cos = Math.cos(angleX);
-
var sin = Math.sin(angleX);
- vectors.foreach(function(){
-
var y1 = this.y * cos - this.z * sin;
-
var z1 = this.z * cos this.y * sin;
-
this.y = y1;
-
this.z = z1;
- });
- }
-
- function rotateY(vectors){
-
var cos = Math.cos(angleY);
-
var sin = Math.sin(angleY);
- vectors.foreach(function(){
-
var x1 = this.x * cos - this.z * sin;
-
var z1 = this.z * cos this.x * sin;
-
this.x = x1;
-
this.z = z1;
- })
- }
-
-
-
-
Würfel = neu Würfel(80);
- cube._initVector();
- function initAnimate(){
- cube._draw();
-
- animate();
- }
-
- function animate(){
- ctx.clearRect(0,0,canvas.width,canvas.height)
-
- rotateY(cube.vectors);
- rotateX(cube.vectors);
- cube._draw();
- if("requestAnimationFrame" in window){
- requestAnimationFrame(animate);
- }
- else if("webkitRequestAnimationFrame" in window){
- webkitRequestAnimationFrame(animate);
- }
- else if("msRequestAnimationFrame" in window){
- msRequestAnimationFrame(animate);
- }
- else if("mozRequestAnimationFrame" in window){
- mozRequestAnimationFrame(animate);
- }
- sonst {
- setTimeout(animate , 16);
- }
- }
Ich werde nicht den gesamten Code veröffentlichen, Sie können ihn über die Konsole in der DEMO sehen. Ich habe nicht auf andere Frameworks oder ähnliches verwiesen, kopieren Sie es einfach und Sie können es verwenden.
Nachdem Sie einen rotierenden Würfel schreiben können, können Sie auch mehrere rotierende Würfel erstellen.
Poke DEMO: Gesicht: 3D Cube 2 3D Cube Line (Ich finde das einfach cooler ohne Gesichter)