2016-12-19 2 views
0

enter image description hereComment trouver l'angle de rotation pour faire un arc SVG "stand up" avec css3d

Je arcs noeuds de connexion dans un graphe orienté force de d3, l'ensemble SVG est transformée avec CSS. Maintenant, les arcs ne sont pas agréables, c'est comme si je me trouvais dans le sol, alors je veux les faire "se lever", ou tourner X, Y, Z pour obtenir l'effet. J'ai défini l'origine de la transformation au centre de la ligne reliant les nœuds, mais maintenant je suis coincé avec trouver les angles auxquels je dois faire tourner les arcs pour les faire se lever. Toute idée/formule pour trouver les angles est très appréciée.

Le code que j'ai en ce moment dans la fonction tick ressemble:

force.on("tick", function() { 
    path.attr("d", function (d) { 
     var dx = d.target.x - d.source.x, 
      dy = d.target.y - d.source.y, 
      dr = Math.sqrt(dx * dx + dy * dy) -200; 
     return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
     }) 
     .attr('style', function(d){ 
      var rotateX = 0, rotateY = 0, rotateZ = 0; 
      return "transform-origin:" + (d.source.x + d.target.x)/2 + "px " + (d.source.y + d.target.y)/2 + "px" + 
       ";transform:rotateX("+rotateX+"deg) rotateY("+rotateY+"deg) rotateZ("+rotateZ+"deg)"; 
     }); 

angles rotateX, rotateY et rotateZ sont ce que je cherche!

Répondre

1

Je n'ai aucune connaissance pratique de d3, j'ai donc résolu le problème pour une mise en page javascript standard.

Espérons que la procédure devrait fonctionner de la même manière.

Sur la démonstration, cliquez 2 fois pour définir le début et la fin de l'arc. Puis cliquez à nouveau pour le voir tourner en 3D.

Vous pouvez répéter le cycle autant de fois que vous le souhaitez.

Dans le calcul de la transformation, nous calculons simplement l'angle dans le plan avec atan2 et les différences horizontales et verticales. La vraie astuce consiste à définir les 90 degrés qui obtiendront l'élément vertical après (en notation) la rotation du plan.

Notez que dans l'extrait, je n'applique pas 90 degrés, mais 80, de sorte que l'arc est toujours visible vu de dessus.

var sequence = 0; 
 
var x1, y1, x2, y2; 
 

 
function getCursorPosition(event) { 
 
    var x = event.clientX; 
 
    var y = event.clientY; 
 
    var ele = document.getElementById('container'); 
 
    if (sequence == 0) { 
 
    x1 = x; 
 
    y1 = y; 
 
    sequence = 1; 
 
    ele.classList.remove("animate"); 
 
    } else if (sequence == 1) { 
 
    x2 = x; 
 
    y2 = y; 
 
    sequence = 2; 
 
    Compute(); 
 
    } else { 
 
    ele.classList.add("animate"); 
 
    sequence = 0; 
 
    } 
 
} 
 

 
function Compute() { 
 
    var ele = document.getElementById('inner'); 
 
    var width = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); 
 

 
    ele.style.width = width + "px "; 
 
    ele.style.height = width/2 + "px "; 
 
    ele.style.left = x1 + "px "; 
 
    ele.style.top = y1 + "px "; 
 
    var angle = Math.atan2(y2 - y1, x2 - x1); 
 
    var deg = angle * 180.0/Math.PI; 
 

 
    ele.style.transform = "rotate(" + deg + "deg) rotateX(80deg) " 
 
    /* 
 
     var style = "width:" + width + "px "; 
 
     style += "left: " + x1 + "px "; 
 
     style += "top: " + y1 + "px "; 
 
     ele.setAttribute("style",style); 
 
    */ 
 
}
.container { 
 
    width: 600px; 
 
    height: 400px; 
 
    border: solid 1px green; 
 
    perspective: 1000px; 
 
    transform-style: preserve-3d; 
 
    position: absolute; 
 
    background-image: repeating-linear-gradient(white 0px, wheat 50px, white 100px); 
 
} 
 
#inner { 
 
    width: 100px; 
 
    height: 50px; 
 
    border-radius: 0px 0px 100px 100px; 
 
    background-color: green; 
 
    position: absolute; 
 
    transform-origin: left top; 
 
    transform-style: preserve-3d; 
 
} 
 
.animate { 
 
    animation: rota 15s 1; 
 
} 
 
@keyframes rota { 
 
    from { 
 
    transform: perspective(1000px) rotateX(0deg); 
 
    } 
 
    to { 
 
    transform: perspective(1000px) rotateX(360deg); 
 
    } 
 
}
<div class="container" id="container" onclick="getCursorPosition(event)"> 
 
    <div id="inner"> 
 
    </div> 
 
</div>

+0

Celui-ci est génial. Pendant ce temps, j'ai abandonné cette idée et porté mon graphique à three.js et j'ai obtenu [this] (https://jsfiddle.net/urzd0fkd/5/show/) dès maintenant. Je n'ai toujours pas compris la fonction Calcul, y a-t-il des maths derrière cela dont vous avez une référence? Merci beaucoup pour le temps et les efforts. – sabithpocker

+0

J'ai ajouté plus d'explications ... Votre démo dans three.js est incroyable :-) – vals