Heim > Web-Frontend > H5-Tutorial > HTML5 3D-Kleiderschaukel-Animation, Spezialeffekte_html5-Tutorial-Fähigkeiten

HTML5 3D-Kleiderschaukel-Animation, Spezialeffekte_html5-Tutorial-Fähigkeiten

WBOY
Freigeben: 2016-05-16 15:45:42
Original
2005 Leute haben es durchsucht

Dies ist ein weiteres 3D-Animationsmeisterwerk, das auf HTML5 Canvas basiert. Es handelt sich um einen 3D-Kleiderschaukel-Spezialeffekt, der im Wind flattern kann, was sehr realistisch ist. Wenn wir mit der Maus über die Kleidung fahren, schwankt die Kleidung. Wenn wir mit der Maus klicken, schwingt die Kleidung heftiger.

Online-Demo Quellcode-Download

HTML-Code

XML/HTML-CodeInhalt in die Zwischenablage kopieren
  1. <div style="width:500px;margin :10px auto">
  2. <Leinwand id="cv" Breite="480" Höhe="300">Leinwand> 
  3. <p>Demo „3D auf 2D-Leinwand“< /p>
  4. <p>Cursor zum Schwenken bewegen / klicken zum Schwenken< ;/p> 
  5. div>

JS-Code der P3D-Bibliothek, der hauptsächlich zur Verarbeitung von 3D-Effekten verwendet wird

JavaScript-CodeInhalt in die Zwischenablage kopieren
  1. window.P3D = {   
  2.  Textur: null,   
  3.  g: null  
  4. };   
  5.   
  6. P3D.clear = Funktion(f, w, h) {   
  7.  var g = this.g;   
  8.  g.beginPath();   
  9.  g.fillStyle = f;   
  10.  g.fillRect(0, 0, w, h);   
  11.   
  12. }   
  13.   
  14. P3D.num_cmp = Funktion(a,b){return a-b;}  
  15.   
  16. P3D.drawTriangle = function(poss, uvs, shade_clr) {   
  17.  var w = this.texture.width;   
  18.  var h = this.texture.height;   
  19.   
  20.  var g = this.g;   
  21.   
  22.  var vAd = [ poss[1].x - poss[0].x , poss[1].y - poss[0].y ] ;   
  23.  var vBd = [ poss[2].x - poss[0].x , poss[2].y - poss[0].y ] ;   
  24.   
  25.  var vA = [ uvs[1].u - uvs[0].u , uvs[1].v - uvs[0].v ] ;   
  26.  var vB = [ uvs[2].u - uvs[0].u , uvs[2].v - uvs[0].v ] ;   
  27.   
  28.  vA[0] *= w;   
  29.  vA[1] *= h;   
  30.   
  31.  vB[0] *= w;   
  32.  vB[1] *= h;   
  33.   
  34.  var m = neu M22();   
  35.  m._11 = vA[0];   
  36.  m._12 = vA[1];   
  37.  m._21 = vB[0];   
  38.  m._22 = vB[1];   
  39.   
  40.  var im = m.getInvert();   
  41.  if (!im) return false;   
  42.   
  43.  var a = im._11 * vAd[0]   im._12 * vBd[0];   
  44.  var b = im._21 * vAd[0]   im._22 * vBd[0];   
  45.   
  46.  var c = im._11 * vAd[1]   im._12 * vBd[1];   
  47.  var d = im._21 * vAd[1]   im._22 * vBd[1];   
  48.   
  49.  var wu = uvs[0].u * w;   
  50.  var hv = uvs[0].v * h;   
  51.  var du = wu * a   hv * b;   
  52.  var dv = wu * c   hv * d;   
  53.   
  54.  g.save();   
  55.   
  56.  g.beginPath();   
  57.  g.moveTo(poss[0].x, poss[0].y);   
  58.  g.lineTo(poss[1].x, poss[1].y);   
  59.  g.lineTo(poss[2].x, poss[2].y);   
  60.  g.clip();   
  61.   
  62.  g.transform(a, c, b, d, poss[0].x - du, poss[0].y - dv);   
  63.   
  64.  // Grenzen   
  65.  var bx = [wu, wu vA[0], wu vB[0]];   
  66.  var by = [hv, hv vA[1], hv vB[1]];   
  67.   
  68.  bx.sort(P3D.num_cmp);   
  69.  by.sort(P3D.num_cmp);   
  70.   
  71.  var bw = bx[2] - bx[0];   
  72.  var bh = by[2] - by[0];   
  73.   
  74.  if ((bx[0] bw) <= (w-1)) bw ;   
  75.  if ((by[0] bh) <= (h-1)) bh ;   
  76.  if (bx[0] >= 1) {bx[0]--; bw ;}   
  77.  if (by[0] >= 1) {by[0]--; bh ;}   
  78.   
  79.  g.drawImage(this.texture, bx[0], by[0], bw, bh, bx[0], by[0], bw, bh);   
  80.   
  81.  if (shade_clr) {   
  82.   g.fillStyle = shade_clr;   
  83.   g.fillRect(bx[0], by[0], bw, bh);   
  84.  }   
  85.   
  86.  g.restore();   
  87.   
  88.  zurück wahr;   
  89. }   
  90.   
  91. P3D.drawTestByIndexBuffer = function(pos_buf, ix_buf, culling) {   
  92.  var g = this.g;   
  93.   
  94.  if ((ix_buf.length%3) != 0)   
  95.   throw "ungültige Indexpufferlänge!";   
  96.   
  97.  var len = ix_buf.length/3;   
  98.   
  99.  var i, ibase, vbase;   
  100.  var poss = [{},{},{}];   
  101.  g.StrokeWidth = 1;   
  102.  for (i = 0, ibase = 0;i < len; i)   
  103.  {   
  104.   vbase = ix_buf[ibase ] << 2;   
  105.   poss[0].x = pos_buf[vbase ];   
  106.   poss[0].y = pos_buf[vbase  ];   
  107.   
  108.   vbase = ix_buf[ibase ] << 2;   
  109.   poss[1].x = pos_buf[vbase ];   
  110.   poss[1].y = pos_buf[vbase  ];   
  111.   
  112.   vbase = ix_buf[ibase ] << 2;   
  113.   poss[2].x = pos_buf[vbase ];   
  114.   poss[2].y = pos_buf[vbase  ];   
  115.   
  116.   // z-Komponente des Produktübergreifenden < 0 ?   
  117.   
  118.   var Ax = poss[1].x - poss[0].x;   
  119.   var Ay = poss[1].y - poss[0].y;   
  120.   var Cx = poss[2].x - poss[1].x;   
  121.   var Cy = poss[2].y - poss[1].y;   
  122.   
  123.   var cull = ( (((Ax * Cy) - (Ay * Cx))*culling) < 0);   
  124.   
  125.   g.beginPath();   
  126.   g.strokeStyle = cull ? "#592" : "#0f0";   
  127.   g.moveTo(poss[0].x, poss[0].y);   
  128.   g.lineTo(poss[1].x, poss[1].y);   
  129.   g.lineTo(poss[2].x, poss[2].y);   
  130.   g.lineTo(poss[0].x, poss[0].y);   
  131.   g.stroke();   
  132.  }   
  133. }   
  134.   
  135. P3D.drawByIndexBuffer = function(pos_buf, ix_buf, tx_buf, culling, z_clip) {   
  136.  var w, h;   
  137.  var color_polygon = !this.texture;   
  138.  if (this.texture) {   
  139.   w = this.texture.width;   
  140.   h = this.texture.height;   
  141.  }  
  142.   
  143.  var g = this.g;   
  144.  var m = neu M22();   
  145.   
  146.  if (!culling) culling = 0;   
  147.   
  148.  if ((ix_buf.length%3) != 0)   
  149.   throw "ungültige Indexpufferlänge!";   
  150.   
  151.  var i, ibase, vbase, tbase, poss = [{},{},{}];   
  152.  var len = ix_buf.length/3;   
  153.  var uv_0u, uv_0v, uv_1u, uv_1v, uv_2u, uv_2v;   
  154.   
  155.  for (i = 0, ibase = 0;i < len; i)   
  156.  {   
  157.   tbase = ix_buf[ibase ] << 1   
  158.   vbase = tbase << 1;   
  159.   poss[0].x = pos_buf[vbase ]; uv_0u = tx_buf[tbase ];   
  160.   poss[0].y = pos_buf[vbase ]; uv_0v = tx_buf[tbase];   
  161.   if (z_clip && (pos_buf[vbase] < 0 || pos_buf[vbase] > 1)) {ibase  = 2; weiter;}   
  162.   
  163.   tbase = ix_buf[ibase ] << 1   
  164.   vbase = tbase << 1;   
  165.   poss[1].x = pos_buf[vbase ]; uv_1u = tx_buf[tbase ];   
  166.   poss[1].y = pos_buf[vbase ]; uv_1v = tx_buf[tbase];   
  167.   if (z_clip && (pos_buf[vbase] < 0 || pos_buf[vbase] > 1)) { ibase; weiter;}   
  168.   
  169.   tbase = ix_buf[ibase ] << 1   
  170.   vbase = tbase << 1;   
  171.   poss[2].x = pos_buf[vbase ]; uv_2u = tx_buf[tbase ];   
  172.   poss[2].y = pos_buf[vbase ]; uv_2v = tx_buf[tbase];   
  173.   if (z_clip && (pos_buf[vbase] < 0 || pos_buf[vbase] > 1)) {continue;}  
  174.   
  175.   var vAd = [ poss[1].x - poss[0].x , poss[1].y - poss[0].y ] ;   
  176.   var vBd = [ poss[2].x - poss[0].x , poss[2].y - poss[0].y ] ;   
  177.   
  178.   var vCd = [ poss[2].x - poss[1].x , poss[2].y - poss[1].y ] ;   
  179.   
  180.   // z-Komponente des Produktübergreifenden < 0 ?   
  181.   if( (((vAd[0] * vCd[1]) - (vAd[1] * vCd[0]))*culling) < ;  0)   
  182.    weiter;   
  183.   
  184.   if (color_polygon) {   
  185.    g.fillStyle = uv_0u;   
  186.   
  187.    g.beginPath();   
  188.    g.moveTo(poss[0].x, poss[0].y);   
  189.    g.lineTo(poss[1].x, poss[1].y);   
  190.    g.lineTo(poss[2].x, poss[2].y);   
  191.    g.fill();   
  192.    weiter;   
  193.   }   
  194.   
  195.   var vA = [ uv_1u - uv_0u , uv_1v - uv_0v ];   
  196.   var vB = [ uv_2u - uv_0u , uv_2v - uv_0v ];   
  197.   
  198.   vA[0] *= w;   
  199.   vA[1] *= h;   
  200.   
  201.   vB[0] *= w;   
  202.   vB[1] *= h;   
  203.   
  204.   m._11 = vA[0];   
  205.   m._12 = vA[1];   
  206.   m._21 = vB[0];   
  207.   m._22 = vB[1];   
  208.   
  209.   var im = m.getInvert();   
  210.   if (!im) { continue;}  
  211.   var a = im._11 * vAd[0]   im._12 * vBd[0];   
  212.   var b = im._21 * vAd[0]   im._22 * vBd[0];   
  213.   var c = im._11 * vAd[1]   im._12 * vBd[1];   
  214.   var d = im._21 * vAd[1]   im._22 * vBd[1];   
  215.   var wu = uv_0u * w;   
  216.   var hv = uv_0v * h;   
  217.   var du = wu * a   hv * b;   
  218.   var dv = wu * c   hv * d;   
  219.   g.save();   
  220.   g.beginPath();   
  221.   g.moveTo(poss[0].x, poss[0].y);   
  222.   g.lineTo(poss[1].x, poss[1].y);   
  223.   g.lineTo(poss[2].x, poss[2].y);   
  224.   g.clip();   
  225.   g.transform(a, c, b, d, poss[0].x - du, poss[0].y - dv);   
  226.   // Grenzen   
  227.   var bx = [wu, wu vA[0], wu vB[0]];   
  228.   var by = [hv, hv vA[1], hv vB[1]];   
  229.   bx.sort(P3D.num_cmp);   
  230.   by.sort(P3D.num_cmp);   
  231.   var bw = bx[2] - bx[0];   
  232.   var bra = by[2] - by[0];   
  233.   if ((bx[0] bw) <= (w-1)) bw ;   
  234.   if ((by[0] bra) <= (h-1)) bra ;   
  235.   if (bx[0] >= 1) {bx[0]--; bw ;}   
  236.   if (by[0] >= 1) {by[0]--; BH ;}   
  237.   g.drawImage(this.texture, bx[0], by[0], bw, bh, bx[0], by[0], bw, bh);   
  238. /*
  239.   if (shade_clr) {  
  240.    g.fillStyle = shade_clr;  
  241.    g.fillRect(bx[0], by[0], bw, bh);  
  242.   }  
  243. */
  244.   g.restore();   
  245. }  
  246.   
  247. }   
  248.   
  249. Funktion Vec3(_x, _y, _z)   
  250. {   
  251.  dieses.x = _x || 0;   
  252.  dieses.y = _y || 0;   
  253.  dieses.z = _z || 0;   
  254. }   
  255.   
  256. Vec3.prototype = {   
  257.  Null: Funktion() {   
  258.   dieses.x = dieses.y = dieses.z = 0;   
  259.  }, ​​  
  260.   
  261.  sub: Funktion(v) {   
  262.   dieses.x -= v.x;   
  263.   dieses.y -= v.y;   
  264.   dieses.z -= v.z;   
  265.   
  266.   zurückgeben dies;   
  267.  }, ​​  
  268.   
  269.  hinzufügen: Funktion(v) {   
  270.   dieses.x  = v.x;   
  271.   dieses.y  = v.y;   
  272.   dieses.z  = v.z;   
  273.   
  274.   zurückgeben dies;   
  275.  }, ​​  
  276.   
  277.  copyFrom: function(v) {   
  278.   dieses.x = v.x;   
  279.   dieses.y = v.y;   
  280.   dieses.z = v.z;   
  281.   
  282.   zurückgeben dies;   
  283.  }, ​​  
  284.   
  285.  norm:Funktion() {   
  286.   return Math.sqrt(this.x*this.x   dieses.y*dieses.y   dieses.z *dies.z);   
  287.  },   
  288.   
  289.  normalisieren: Funktion() {   
  290.   var nrm = Math.sqrt(this.x*this.x   dieses.y*dieses.y   dieses .z*dies.z);   
  291.   if (nrm != 0)   
  292.   {   
  293.    dieses.x /= nrm;   
  294.    dieses.y /= nrm;   
  295.    dieses.z /= nrm;   
  296.   }   
  297.   zurückgeben dies;   
  298.  }, ​​  
  299.   
  300.  smul: Funktion(k) {   
  301.   dieses.x *= k;   
  302.   dieses.y *= k;   
  303.   dieses.z *= k;   
  304.   
  305.   zurückgeben dies;   
  306.  }, ​​  
  307.   
  308.  dpWith: function(v) {   
  309.   zurückgeben dieses.x*v.x   dieses. y*v.y   dies.z*v.z;   
  310.  }, ​​  
  311.   
  312.  cp: Funktion(v, w) {   
  313.   dies.x = (w.y * v.z) - (w.z * v.y);   
  314.   dies.y = (w.z * v.x) - (w.x * v.z);   
  315.   dies.z = (w.x * v.y) - (w.y * v.x);   
  316.   
  317.   zurückgeben dies;   
  318.  }, ​​  
  319.   
  320.  toString: function() {   
  321.   zurück dies.x   ", "   dieses.y   ","   dieses.z;   
  322.  }   
  323. }  
  324.   
  325. Funktion M44(cpy)   
  326. {   
  327.  if (cpy)   
  328.   dieses.copyFrom(cpy);   
  329.  sonst {   
  330.   dieses.ident();   
  331.  }   
  332. }   
  333.   
  334. M44.prototype = {   
  335.  ident: function() {   
  336.      dieses._12 = dieses._13 = dieses._14 = 0;   
  337.   dieses._21 =       dieses._23 = dieses._24 = 0;   
  338.   dieses._31 = dieses._32 =       dieses._34 = 0;   
  339.   dieses._41 = dieses._42 = dieses._43 =       0;   
  340.   
  341.   dieses._11 = dieses._22 = dieses._33 = dieses._44 = 1;   
  342.   
  343.   zurückgeben dies;   
  344.  },   
  345.   
  346.  copyFrom: function(m) {   
  347.   dieses._11 = m._11;   
  348.   dieses._12 = m._12;   
  349.   dieses._13 = m._13;   
  350.   dieses._14 = m._14;   
  351.   
  352.   dieses._21 = m._21;   
  353.   dieses._22 = m._22;   
  354.   dieses._23 = m._23;   
  355.   dieses._24 = m._24;   
  356.   
  357.   dieses._31 = m._31;   
  358.   dieses._32 = m._32;   
  359.   dieses._33 = m._33;   
  360.   dieses._34 = m._34;   
  361.   
  362.   dieses._41 = m._41;   
  363.   dieses._42 = m._42;   
  364.   dieses._43 = m._43;   
  365.   dieses._44 = m._44;   
  366.   
  367.   zurückgeben dies;   
  368.  }, ​​  
  369.   
  370.  transVec3: Funktion(out, x, y, z) {   
  371.   out[0] = x * dieses._11   y * dieses._21   z *  dieses._31   dieses._41;   
  372.   out[1] = x * dieses._12   y * dieses._22   z *  dieses._32   dieses._42;   
  373.   out[2] = x * dieses._13   y * dieses._23   z *  dieses._33   dieses._43;   
  374.   out[3] = x * dieses._14   y * dieses._24   z *  dieses._34   dieses._44;   
  375.  },   
  376.   
  377.  transVec3Rot: Funktion(out, x, y, z) {   
  378.   out[0] = x * dieses._11   y * dieses._21   z *  dieses._31;   
  379.   out[1] = x * dieses._12   y * dieses._22   z *  dieses._32;   
  380.   out[2] = x * dieses._13   y * dieses._23   z *  dieses._33;   
  381.  }, ​​  
  382.   
  383.  PerspektiveLH: Funktion(vw, vh, z_near, z_far) {   
  384.   dieses._11 = 2.0*z_near/vw;   
  385.   dieses._12 = 0;   
  386.   dieses._13 = 0;   
  387.   dieses._14 = 0;   
  388.   
  389.   dieses._21 = 0;   
  390.   dies._22 = 2*z_near/vh;   
  391.   dieses._23 = 0;   
  392.   dieses._24 = 0;   
  393.   
  394.   dieses._31 = 0;   
  395.   dieses._32 = 0;   
  396.   dies._33 = z_far/(z_far-z_near);   
  397.   dieses._34 = 1;   
  398.   
  399.   dieses._41 = 0;   
  400.   dieses._42 = 0;   
  401.   dies._43 = z_near*z_far/(z_near-z_far);   
  402.   dieses._44 = 0;   
  403.   
  404.   zurückgeben dies;   
  405.  },   
  406.   
  407.  lookAtLH: function(aUp, aFrom, aAt) {   
  408.   var aX = neu Vec3();   
  409.   var aY = neu Vec3();   
  410.   
  411.   var aZ = neu Vec3(aAt.x, aAt.y, aAt.z);   
  412.   aZ.sub(aFrom).normalize();   
  413.   
  414.   aX.cp(aUp, aZ).normalize();   
  415.   aY.cp(aZ, aX);   
  416.   
  417.   dieses._11 = aX.x;  dies._12 = aY.x;  dieses._13 = aZ.x;  dieses._14 = 0;   
  418.   dieses._21 = aX.y;  dieses._22 = aY.y;  dies._23 = aZ.y;  dieses._24 = 0;   
  419.   dieses._31 = aX.z;  dies._32 = aY.z;  dieses._33 = aZ.z;  dieses._34 = 0;   
  420.   
  421.   dies._41 = -aFrom.dpWith(aX);   
  422.   dies._42 = -aFrom.dpWith(aY);   
  423.   dies._43 = -aFrom.dpWith(aZ);   
  424.   dieses._44 = 1;   
  425.   
  426.      zurückgeben dies;   
  427.  },   
  428.   
  429.  mul: Funktion(A, B) {   
  430.   dieses._11 = A._11*B._11     A._12*B._21     A._13*B._31     A._14*B._41 ;   
  431.   dies._12 = A._11*B._12     A._12*B._22     A._13*B._32     A._14*B._42 ;   
  432.   dies._13 = A._11*B._13     A._12*B._23     A._13*B._33     A._14*B._43 ;   
  433.   dies._14 = A._11*B._14     A._12*B._24     A._13*B._34     A._14*B._44 ;   
  434.   
  435.   dies._21 = A._21*B._11     A._22*B._21     A._23*B._31     A._24*B._41 ;   
  436.   dies._22 = A._21*B._12     A._22*B._22     A._23*B._32     A._24*B._42 ;   
  437.   dies._23 = A._21*B._13     A._22*B._23     A._23*B._33     A._24*B._43 ;   
  438.   dies._24 = A._21*B._14     A._22*B._24     A._23*B._34     A._24*B._44 ;   
  439.   
  440.   dies._31 = A._31*B._11     A._32*B._21     A._33*B._31     A._34*B._41 ;   
  441.   dieses._32 = A._31*B._12     A._32*B._22     A._33*B._32     A._34*B._42 ;   
  442.   dies._33 = A._31*B._13     A._32*B._23     A._33*B._33     A._34*B._43 ;   
  443.   dies._34 = A._31*B._14     A._32*B._24     A._33*B._34     A._34*B._44 ;   
  444.   
  445.   dies._41 = A._41*B._11     A._42*B._21     A._43*B._31     A._44*B._41 ;   
  446.   dies._42 = A._41*B._12     A._42*B._22     A._43*B._32     A._44*B._42 ;   
  447.   dies._43 = A._41*B._13     A._42*B._23     A._43*B._33     A._44*B._43 ;   
  448.   dieses._44 = A._41*B._14     A._42*B._24     A._43*B._34     A._44*B._44 ;   
  449.   
  450.   zurückgeben dies;   
  451.  },   
  452.   
  453.  traduire : fonction(x, y, z) {   
  454.   ceci._11 = 1 ;  ce._12 = 0 ;  ce._13 = 0 ;  ce._14 = 0;   
  455.   ceci._21 = 0 ;  ce._22 = 1 ;  ce._23 = 0 ;  ce._24 = 0 ;   
  456.   ce._31 = 0 ;  ce._32 = 0;  ce._33 = 1 ;  ce._34 = 0;   
  457.   
  458.   ce._41 = x;  ce._42 = y ;  ce._43 = z ;  ce._44 = 1 ;   
  459.   retourner ceci ;   
  460.  }, ​​  
  461.   
  462.  transpose33 : fonction() {   
  463.   var t;   
  464.   
  465.   t = ce._12;   
  466.   ce._12 = ce._21;   
  467.   ce._21 = t ;   
  468.   
  469.   t = ce._13;   
  470.   ce._13 = ce._31;   
  471.   ceci._31 = t ;   
  472.   
  473.   t = ce._23;   
  474.   ce._23 = ce._32;   
  475.   ceci._32 = t;   
  476.   
  477.   retourner ceci ;   
  478.  },   
  479.   
  480.  // Rotation de style OpenGL   
  481.  glRotate : fonction(angle, x, y, z) {   
  482.   var s = Math.sin( angle );   
  483.   var c = Math.cos( angle );   
  484.   
  485.   var xx = x * x;   
  486.   var yy = y * y;   
  487.   var zz = z * z;   
  488.   var xy = x * y;   
  489.   var yz = y * z;   
  490.   var zx = z * x;   
  491.   var xs = x * s;   
  492.   var ys = y * s;   
  493.   var zs = z * s;   
  494.   var one_c = 1.0 - c;   
  495. /*  
  496.   this._11 = (one_c * xx)   c;  
  497.   this._21 = (one_c * xy) - zs ;  
  498.   this._31 = (one_c * zx)   oui ;  
  499.   this._41 = 0;  
  500.  
  501.   this._12 = (one_c * xy)   zs;  
  502.   this._22 = (one_c * yy)   c ;  
  503.   this._32 = (one_c * yz) - xs ;  
  504.   this._42 = 0;  
  505.  
  506.   this._13 = (one_c * zx) - oui ;  
  507.   this._23 = (one_c * yz)   xs ;  
  508.   this._33 = (one_c * zz)   c;  
  509.   this._43 = 0;  
  510.  
Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage