Maison > interface Web > Tutoriel H5 > Exemple de code pour HTML5 Canvas pour implémenter des effets de flamme tels que des lancements de boules de feu

Exemple de code pour HTML5 Canvas pour implémenter des effets de flamme tels que des lancements de boules de feu

黄舟
Libérer: 2017-03-21 15:09:06
original
2718 Les gens l'ont consulté

Canvas est une chose très importante et utile en HTML5 Nous pouvons dessiner n'importe quel élément sur Canvas, tout comme vous créez Flash. Aujourd'hui, nous allons créer un effet d'émission de flamme sur Canvas. C'est comme un ancien canon à boule de feu, et il peut rebondir sur le bord du navigateur, ce qui est plutôt cool. Jetons un coup d'œil aux rendus :

Nous pouvons voir la démonstration DEMO de la boule de flammes ici

Bien sûr, nous devons analyser le code source, principalement du code JS.

Tout d’abord, mettez simplement une balise canvas sur la page et donnez-lui un style simple :

<canvas></canvas>
Copier après la connexion
canvas{
  position: absolute;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  cursor: crosshair;
}
Copier après la connexion

Analysons ensuite le code JS. Décomposons JS étape par étape.

Puisqu'il s'agit d'une animation bidimensionnelle, nous utilisons la méthode getContext de canvas pour renvoyer un objet, qui contient nos opérations pour les opérations bidimensionnelles animation.API, le code est le suivant :

canvas = document.querySelector(&#39;canvas&#39;);
ctx = canvas.getContext(&#39;2d&#39;);
Copier après la connexion

Définissons les particules :

particles = {};
newParticle = (function(){  var nextIndex = 0;  return function(x,y,r,o,c,xv,yv,rv,ov){
    particles[++nextIndex] = {
      index: nextIndex,
      x: x,
      y: y,
      r: r,
      o: o,
      c: c,
      xv: xv,
      yv: yv,
      rv: rv,
      ov: ov
    };
  };
})();
Copier après la connexion

Ensuite on définit la boule de feu :

fireballs = {};
newFireball = (function(){  var nextIndex = 0;  return function(x,y,xv,yv,life){
    fireballs[++nextIndex] = {
      index: nextIndex,
      x: x,
      y: y,
      xv: xv,
      yv: yv,
      life: life
    };
  };
})();
Copier après la connexion

Ici, la vie signifie le cycle de vie de la boule de feu, comme nous pouvons le voir ci-dessous, la valeur de la vie changera à mesure que l'intensité du lancement de la boule de feu change.

L'étape suivante consiste à définir la souris pour faire glisser la fronde et se préparer à lancer la boule de feu :

mouse = {x:0,y:0,d:0};
onmousemove = function(e){
  mouse.x = e.clientX-o.x;
  mouse.y = e.clientY-o.y;  var dx = mouse.x - pos1.x,
      dy = mouse.y - pos1.y;
  mouse.d = Math.sqrt(dx*dx+dy*dy);
};

charging = false;
pos1 = {x:0,y:0};
showInstructions = true;
onmousedown = function(e){
  pos1.x = mouse.x;
  pos1.y = mouse.y;
  charging = true;
  showInstructions = false;
};

onmouseup = function(){  if(charging){
    newFireball(
      mouse.x,
      mouse.y,
      (pos1.x-mouse.x)*0.03,
      (pos1.y-mouse.y)*0.03,      600
    );
    charging = false;
  }
};
Copier après la connexion

Comme vous pouvez le voir, lorsque le bouton de la souris rebondit, une nouvelle boule de feu est créé et la valeur de vie est initialisée.

Ce qui suit est le code d'exécution de l'animation lorsque la boule de feu se déplace, y compris l'effet de réflexion lorsqu'elle touche le bord du navigateur :

time = 0;
requestAnimationFrame(loop = function(){
  ctx.setTransform(1,0,0,1,0,0);
  ctx.globalCompositeOperation = &#39;source-over&#39;;
  ctx.globalAlpha = 1;
  ctx.fillStyle = bgColor;
  ctx.fillRect(0,0,width,height);
  
  ctx.translate(o.x,o.y);  
  if(charging){    var c = Math.floor(30+mouse.d/2);
    ctx.strokeStyle = &#39;rgba(&#39;+c+&#39;,&#39;+c+&#39;,&#39;+c+&#39;,1)&#39;;
    ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.moveTo(pos1.x,pos1.y);
    ctx.lineTo(mouse.x,mouse.y);
    ctx.lineCap = &#39;round&#39;;
    ctx.stroke();
  }  
  if(showInstructions){
    pos1.x = -70;
    pos1.y = -35;    
    if(time<10){      var x = -70,
          y = -35,
          r = 30-time*2,
          a = time/10;
    }else if(time<80){      var x = (time-10)*2-70,
          y = (time-10)-35,
          r = 10,
          a = 1;
    }else if(time<90){      var x = 70,
          y = 35,
          r = 10+(time-80)*2,
          a = 1-(time-80)/10;
    }else if(time<140){      var x = 70,
          y = 35,
          r = 30,
          a = 0;
    }    var dx = pos1.x-x,
        dy = pos1.y-y,
        d = Math.sqrt(dx*dx+dy*dy);    if(time<80&&time>10){
      ctx.globalCompositeOperation = &#39;source-over&#39;;
      ctx.globalAlpha = 1;      var c = Math.floor(30+d/2);
      ctx.strokeStyle = &#39;rgba(&#39;+c+&#39;,&#39;+c+&#39;,&#39;+c+&#39;,1)&#39;;
      ctx.lineWidth = 4;
      ctx.beginPath();
      ctx.moveTo(pos1.x,pos1.y);
      ctx.lineTo(x,y);
      ctx.lineCap = &#39;round&#39;;
      ctx.stroke();
    }    if(time<140){
      ctx.globalCompositeOperation = &#39;source-over&#39;;
      ctx.globalAlpha = a;
      ctx.beginPath();
      ctx.arc(x,y,r,0,Math.PI*2);
      ctx.lineWidth = 2;
      ctx.strokeStyle = &#39;#aaa&#39;;
      ctx.stroke();
    }    if(time==80){
      newFireball(
        x,
        y,
        dx*0.03,
        dy*0.03,        240
      );
    }
    time = (time+1)%180;
  }
  
  ctx.globalCompositeOperation = &#39;lighter&#39;;  
  for(var i in particles){    
  var p = particles[i];
    ctx.beginPath();
    ctx.arc(p.x,p.y,p.r,0,Math.PI*2);
    ctx.globalAlpha = p.o;
    ctx.fillStyle = p.c;
    ctx.fill();
  }  
  for(var i in particles){    
  var p = particles[i];
    p.x += p.xv;
    p.y += p.yv;
    p.r += p.rv;
    p.o += p.ov;    
    if(p.r<0)delete particles[p.index];    
    if(p.o<0)delete particles[p.index];
  }  
  for(var i in fireballs){
    f = fireballs[i];    
    var numParticles = Math.sqrt(f.xv*f.xv+f.yv*f.yv)/5;    
    if(numParticles<1)numParticles=1;    
    var numParticlesInt = Math.ceil(numParticles),
        numParticlesDif = numParticles/numParticlesInt;    
        for(var j=0;j<numParticlesInt;j++){
      newParticle(
        f.x-f.xv*j/numParticlesInt,
        f.y-f.yv*j/numParticlesInt,
        7,
        numParticlesDif,
        particleColor,
        Math.random()*0.6-0.3,
        Math.random()*0.6-0.3,        
        -0.3,        
        -0.05*numParticlesDif
      );
    }
    f.x += f.xv;
    f.y += f.yv;
    f.yv += gravity;    
    var boundary;    
    if(f.y<(boundary = edge.top+7)){
      f.y = boundary;
      f.yv *= -1;
    }else if(f.y>(boundary = edge.bottom-7)){
      f.y = boundary;
      f.yv *= -1;
    }    if(f.x>(boundary = edge.right-7)){
      f.x = boundary;
      f.xv *= -1;
    }else if(f.x<(boundary = edge.left+7)){
      f.x = boundary;
      f.xv *= -1;
    }    if(--f.life<0)delete fireballs[f.index];
  }
  
  requestAnimationFrame(loop);
});
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal