Glisser-déposer et la forme de la rotation avec Raphael JS
Je suis en utilisant RaphaelJS 2.0 pour créer plusieurs formes dans un div. Chaque forme doit pouvoir être glissés et déposés dans les limites de la div, de manière indépendante. Sur double-cliquant sur une forme, cette forme doit faire pivoter de 90 degrés. Il peut alors être déplacée et a tourné de nouveau.
J'ai chargé un peu de code sur fiddler: http://jsfiddle.net/QRZMS/. C'est essentiellement ceci:
window.onload = function () {
var angle = 0;
var R = Raphael("paper", "100%", "100%"),
shape1 = R.rect(100, 100, 100, 50).attr({ fill: "red", stroke: "none" }),
shape2 = R.rect(200, 200, 100, 50).attr({ fill: "green", stroke: "none" }),
shape3 = R.rect(300, 300, 100, 50).attr({ fill: "blue", stroke: "none" }),
shape4 = R.rect(400, 400, 100, 50).attr({ fill: "black", stroke: "none" });
var start = function () {
this.ox = this.attr("x");
this.oy = this.attr("y");
},
move = function (dx, dy) {
this.attr({ x: this.ox + dx, y: this.oy + dy });
},
up = function () {
};
R.set(shape1, shape2, shape3, shape4).drag(move, start, up).dblclick(function(){
angle -= 90;
shape1.stop().animate({ transform: "r" + angle }, 1000, "<>");
});
}
Le glisser-déposer fonctionne et est également l'une des formes tourne sur le double clic. Cependant, il y a deux problèmes/questions:
- Comment puis-je joindre la rotation sur chaque forme automatiquement, sans avoir à coder en dur chaque élément de référence dans la rotation de la méthode? I. e. Je veux juste dessiner les formes d'une fois, alors tous automatiquement exposés au même comportement, de sorte qu'ils peuvent être glissé/déplacé/rotation de manière indépendante, sans avoir à appliquer explicitement que le comportement de chaque forme.
- Après une forme a été tourné, il n'est plus fait glisser correctement - comme si la de faire glisser la souris mouvement se rapporte à l'origine de l'orientation de la forme plutôt que la mise à jour lorsque la forme est en rotation. Comment puis-je obtenir que cela fonctionne correctement, de sorte que les formes peuvent seulement être déplacé et tourné de nombreuses fois, seamlessley?
Merci beaucoup pour tous les pointeurs!
OriginalL'auteur Dan | 2011-11-13
Vous devez vous connecter pour publier un commentaire.
J'ai essayé plusieurs fois d'envelopper ma tête autour de la transformation de nouveau à moteur, en vain. Donc, je reviens aux premiers principes.
J'ai enfin réussi à correctement faites glisser et déposez un objet thats subi plusieurs transformations, après avoir essayé de travailler sur l'impact des différentes transformations - t,T,..., t,..., T,r,r, etc...
Donc, ici, est le point crucial de la solution
Que c'est. Bêtement simple, et je suis sûr qu'elle est produite à des charges de personnes déjà, mais peut-être que quelqu'un pourrait trouver utile.
Voici un violon pour vous de jouer avec.
... et cette est une solution de travail pour la question initiale.
Dan, vous avez à penser à ce que l'Raphaël bibliothèque est en train de faire. C'est d'exposer le SVG (et VML) fonctionnalités du navigateur javascript. En tant que telles une grande partie de ce qu'il fait est une exposition directe de la sous-élément SVG. C'est exactement ce que la transformation de la pièce. Si vous êtes à la recherche pour plus d'informations sur la façon dont ils fonctionnent, et en particulier des transformations de matrice, vous avez besoin de google pour "SVG matrice de transformation" par opposition à "Raphaël de la matrice de transformation". Essayez de commons.oreilly.com/wiki/index.php/SVG_Essentials/... ou mecxpert.de/svg/transform.html
Le violon ne fonctionne pas dans FF7. Après la première bouffée, la position relative de la forme et de la souris est hors de synchronisation.
OrangeDog, Pouvez-vous développer? Je l'ai testé sur IE8.0.6001, chrome 15.0.874, et Firefox 8.0, et il semble fonctionner correctement.
OrangeDog, Vous avez raison, il a oublié de réinitialiser faites glisser la position de départ dans le violon exemple, il suffit de remplacer " glisser / déposer avec cela et il fonctionne très bien: la fonction drag_start(e) { ox = 0; oy = 0; };
OriginalL'auteur amadan
J'ai résolu le glisser/rotation problème en ré-appliquant toutes les transformations lors de la modification d'une valeur. J'ai créé un plugin pour ça.
https://github.com/ElbertF/Raphael.FreeTransform
Démo ici:
http://alias.io/raphael/free_transform/
OriginalL'auteur Elbert Alias
Comme amadan l'indique, il est généralement une bonne idée de créer des fonctions lorsque plusieurs choses ont le même (initiale) des attributs/propriétés. C'est en effet la réponse à votre première question. Quant à la seconde question, qui est un peu plus délicat.
Lorsqu'un Rapheal objet est mis en rotation, de sorte que les coordonnées de l'avion. Pour une raison quelconque, dmitry et quelques autres sources sur le web semblent d'accord pour dire que c'est la bonne façon de le mettre en œuvre. J'ai, comme vous, sont en désaccord. Je n'ai pas réussi à trouver tout autour de la bonne solution mais je ne mange de la création d'un travail autour de. Je vais brièvement expliquer et de montrer ensuite le code.
À condition que vous allez seulement la rotation de formes de 90 degrés (si ce n'est qu'il devient beaucoup plus difficile), vous pouvez déterminer la façon dont les coordonnées doivent être manipulés.
Je ne peux pas vraiment penser à claire et concise façon d'expliquer comment la drag_move œuvres. Je pense que c'est probablement mieux que vous regardez le code et de voir comment il fonctionne. Fondamentalement, vous avez juste besoin de travailler sur la façon dont les variables x et y sont maintenant traités à partir de cette nouvelle rotation de l'etat. Sans moi, le tirage au sort des graphismes je ne suis pas sûr que je pourrais être assez clair. (J'ai fait beaucoup de tourne la tête de côté pour travailler sur ce qu'il doit faire).
Il ya quelques inconvénients à cette méthode:
Je suis en supposant que la raison que vous utilisez transformer, c'est que vous pouvez animer la rotation. Si ce n'est pas nécessaire, alors vous pouvez utiliser les
.rotate()
fonction qui tourne autour du centre de l'élément, et donc d'éliminer la 2ème inconvénient que j'ai mentionnés.Ce n'est pas une solution complète, mais il devrait certainement vous permettre de continuer le long du chemin d'accès correct. Je serais intéressé de voir une version de travail.
J'ai également créé une version de ce sur jsfiddle, vous pouvez les consulter ici: http://jsfiddle.net/QRZMS/3/
Bonne chance.
Merci Adam. Nous sommes en arriver là, mais il est malheureusement très difficile de réaliser ce genre de chose avec Raphaël. Je suis en train de me demander si j'ai choisi le bon outil pour le travail ici, car j'ai besoin de faire quelques relativement complexe des trucs avec des glisser-déposer des objets. Si c'est si difficile à réaliser, alors je pense que les autres trucs va être trop dur. Je vais persister pour l'instant, donc merci pour vos efforts!
OriginalL'auteur Adam Holmes
J'ai l'habitude de créer un objet pour ma forme et à écrire à la gestion des événements dans l'objet.
Ci-dessus, le constructeur ne crée pas seulement le rectangle, mais met en place la double cliquez sur l'événement.
Une chose à noter est qu'une référence à l'objet est stocké dans le "que". C'est parce que le "présent" de référence change en fonction de la portée. Dans la double fonction que j'ai besoin de consulter le rect et angle valeurs de mon objet, j'ai donc utiliser la référence stockée .rect et .angle
Voir ce exemple (mise à jour d'un peu douteux instance précédente)
Il peut y avoir de meilleures façons de faire ce dont vous avez besoin, mais cela devrait fonctionner pour vous.
Espère que ça aide,
Nick
Addendum: Dan, si vous êtes vraiment bloqué sur ce, et peut vivre sans certaines des choses que Raphael2 vous donne, je vous recommande de revenir à Raphaël 1.5.x. Transformations ont été juste ajoutés à Raphael2, la rotation/translation/échelle de code est totalement différent (et plus facile) en 1.5.2.
Regardez-moi, la mise à jour de mon post, en espérant pour le karma...
Je suis gênée.. Il y avait une faute de frappe dans mon violon. l'angle doit être la partie de l'objet et de chaque instance incrémentée séparément. J'ai mis à jour le violon et il devrait fonctionner correctement maintenant. Jeter le blâme sur d'avoir plusieurs navigateurs ouverts 🙁
Le violon est un peu difficile 🙁 essayez ce lien à la place jsfiddle.net/vPSuR
En fait, il s'avère que le Mdn fonctionne la première fois et puis s'en va un peu fou. Je retire mon terrible de la solution, et présenter des excuses pour perdre votre temps.
Haha, pas de soucis Nick - c'est à essayer!
OriginalL'auteur amadan
Si vous ne souhaitez pas utiliser un ElbertF de la bibliothèque, vous pouvez transformer des Coordonnées Cartésiennes en Coordonnées Polaires.
Après vous devez ajouter ou supprimer l'angle et la transformer à nouveau en Coordonnées Cartésiennes.
Nous pouvons voir cet exemple avec un rect, tourner dans le rumble et déplacé.
HTML
JAVASCRIPT
DÉMO
http://jsfiddle.net/Ef83k/74/
OriginalL'auteur user1374626
ma première pensée a été d'utiliser getBBox(faux) pour capturer les coordonnées x,y de l'objet après transformation, removeChild() l'original de Raphaël obj de la toile, puis redessiner l'objet à l'aide des données de coordonnées de getBBox( false ). un hack, mais je l'ai à travailler.
une remarque cependant: puisque l'objet de la getBBox( false ) retourne est le COIN des coordonnées ( x, y) de l'objet dont vous avez besoin pour calculer le centre de la re-objet dessiné par ...
x = la case['x'] + ( cocher['largeur'] /2 );
y = la case['y'] + ( cocher['hauteur'] /2 );
où
boîte = shapeObj.getBBox( false );
une autre façon de résoudre le même problème
OriginalL'auteur b_dubb