2010-11-27 52 views
1

Je ne suis pas un programmeur, et je fais de mon mieux pour résoudre la situation, mais après plusieurs heures et mal de tête j'abandonne et Je demande de l'aide. J'ai un logo circulaire (un div avec un rayon px suffisant pour devenir un cercle et du texte), et j'ai une animation qui sort de derrière le logo quand je passe dessus.Comment faire le planant déclencher une animation seulement sur une zone de cercle dans un div avec rayon de frontière avec jquery

J'ai remarqué que mon animation se déclenche sur la "zone vide" entre le logo circulaire et le div qui tient le logo (c'est encore un carré). Au moment de mon script, il est le suivant:

$("#logo").hover(function(event){  // Hovering 
    myHover = "transition"; 
    $("#black").stop().animate({"top":"-200px"}, speed/2, function(){ 
     myHover = 1; 
    }); 
},function(event){  // Finish hovering 
    myHover = "transition"; 
    $("#black").stop().animate({"top":"0px"}, speed/2, function(){ 
     myHover = 0; 
    }); 
}); 

J'ai essayé de regarder sur le web et sur un débordement de pile pour trouver quelque chose qui va me aider, et ce que je l'ai trouvé est ce le plus proche:

http://jsbin.com/oqewo - à partir de cette autre question Accurately detect mouseover event for a div with rounded corners

J'ai essayé de l'implémenter et je suis sorti avec quelque chose qui n'est pas assez lisse comme animation (j'ai essayé de déboguer en essayant de reculer et d'avancer avec la souris sur le logo pour voir la réaction du script):

$(".myCircle").hover(
    // when the mouse enters the box do... 
    function(){ 
     var $box = $(this), 
     offset = $box.offset(), 
     radius = $box.width()/2, 
     circle = new SimpleCircle(offset.left + radius, offset.top + radius, radius); 

     $box.mousemove(function(e){ 
      if(circle.includesXY(e.pageX, e.pageY) && myHover != "transition"){ 
       $(this).css({"cursor":"pointer"}); 
       myHover = "transition"; 
       $("#black").stop().animate({"top":"-200px"}, speed/2, function(){ 
        myHover = 1; 
       }); 
      }else if(!circle.includesXY(e.pageX, e.pageY)){ 
       $(this).css({"cursor":"default"}); 
       myHover = "transition"; 
       $("#black").animate({"top":"0px"}, speed/2, function(){ 
        myHover = 0; 
       }); 
      } 
     }); 

    }, 
    // when the mouse leaves the box do... 
    function() {  
     //alert("in") 
     //$(this).includesXY(e.pageX, e.pageY) 
     myHover = "transition"; 
     $(this).css({"cursor":"default"}); 
     $("#black").stop().animate({"top":"0px"}, speed/2, function(){ 
      myHover = 0; 
     }); 
    } 
) 

J'ai inséré une variable myHover = 0; au début de mes fonctions car j'avais besoin d'une variable qui me permettrait de savoir quand l'animation est terminée, elle est cachée derrière le logo, ou en transition.

Et je ne sais pas quand et comment utiliser la propriété .unbind afin que je ne suce pas assez de cpu. Y at-il quelque chose de mieux que l'événement mouseenter? Il se déclenche à divers moments, et seulement lorsque je déplace la souris sur le logo, et non lorsque j'ai la souris sur le logo pendant l'animation. De toute façon toute suggestion ou révision de toute sorte sur l'approche de ce problème est plus que bienvenue :)

=======================

MISE à JOUR

je pourrais trouver un moyen, il semble fonctionner, mais je ne sais pas s'il est possible d'optimiser/propre, ou si je me sers unbind correctement, quelqu'un peut vérifier mon code?

$(".myCircle").hover(
     // when the mouse enters the box do... 
     function(){ 
      var $box = $(this), 
      offset = $box.offset(), 
      radius = $box.width()/2, 
      circle = new SimpleCircle(offset.left + radius, offset.top + radius, radius); 

      $box.mousemove(function(e){ 
      if(circle.includesXY(e.pageX, e.pageY) && myHover != "transition1"){ 
       $(this).css({"cursor":"pointer"}); 
       myHover = "transition1"; 
       $("#black").stop().animate({"top":"-200px"}, speed/2, function(){ 
        myHover = 1; 
       }); 
      } 

      else if(!circle.includesXY(e.pageX, e.pageY)){ 
       $(this).css({"cursor":"default"}); 
       if(myHover == 1 || myHover == "transition1"){ 
        myHover = "transition0"; 
        $("#black").stop().animate({"top":"0px"}, speed/2, function(){ 
         myHover = 0; 
        }); 
       } 
      } 
     }); 

    }, 
    // when the mouse leaves the box do... 
    function() {  
     if(myHover == 1 || myHover == "transition1"){ 
      myHover = "transition0"; 
      $(this).css({"cursor":"default"}); 
      $("#black").stop().animate({"top":"0px"}, speed/2, function(){ 
       myHover = 0; 
      }) 
     }; 
     $("#container").unbind('mousemove'); 
    } 
) 

La classe SimpleCircle utilisée dans ce code, de la démo mentionnée ci-dessus, est définie comme:

function SimpleCircle(x, y, r) { 
    this.centerX = x; 
    this.centerY = y; 
    this.radius = r; 
} 

SimpleCircle.prototype = { 
    distanceTo: function(pageX, pageY) { 
    return Math.sqrt(Math.pow(pageX - this.centerX, 2) + Math.pow(pageY - this.centerY, 2)); 
    }, 
    includesXY: function(x, y) { 
    return this.distanceTo(x, y) <= this.radius; 
    } 
}; 
+0

Je mis à jour la demande – Littlemad

Répondre

1

En ce qui concerne votre mise à jour, tout semble bon.

Vous pouvez obtenir une légère amélioration des performances en inversant l'ordre des deux paramètres if() de sorte que myHover != "transition1" soit le premier. Le && est en court-circuit, donc si myHover != "transition1" est faux, la vérification d'inclusion de cercle coûteux n'a pas besoin d'être appelée.

Également sur le else if() peut-être vaut la peine d'avoir une variable définie à quelque chose qui dit que vous avez déjà placé le curseur pour arrêter cela être appelé en continu.

En regardant la classe SimpleCircle, les seules opérations onéreuses effectuées sont deux appels de puissance et une racine carrée (Math.pow() x 2 + Math.sqrt()). Que l'on veuille ou non essayer d'accélérer cela est discutable, seule l'optimisation que je peux imaginer est de vérifier si les coordonnées sont dans le carré du cercle, ce qui est quatre comparaisons rapides, cela couvre 50% des points intérieurs, mais évidemment ralentit l'autre 50% des points. Pour voir si cela a amélioré les choses, il faudrait le tester.

Square inside a circle inside a square

+0

Thx pour la réponse! Je suis à la recherche de "SimpleCircle" + jquery sur google mais je ne trouve rien, où devrais-je regarder? – Littlemad

+0

@Littlemad J'ai ajouté la classe 'SimpleCircle' à votre question à partir de l'exemple que vous lisiez; de sorte que la question soit plus complète pour ceux qui la regardent. – Orbling

+0

@Littlemad ... et mis à jour ma réponse. – Orbling