2010-11-19 6 views
17

È possibile essere in grado di trascinare e rilasciare oggetti diversi da semplici cerchi e rettangoli intorno a una pagina utilizzando Raphael js?Creazione di percorsi e immagini trascinabili in Raphael js

Voglio aggiungere percorsi e immagini che è possibile spostare, ma è difficile. Mi piacerebbe lavorare su questo con Raphael per il suo supporto con le interfacce touch.

Ecco il codice

<script> 
    window.onload = function() { 
     var R = Raphael(0, 0, "100%", "100%"), 
      r = R.circle(100, 100, 50).attr({fill: "hsb(0, 1, 1)", stroke: "none", opacity: .5}), 
      g = R.circle(210, 100, 50).attr({fill: "hsb(.3, 1, 1)", stroke: "none", opacity: .5}), 
      b = R.circle(320, 100, 50).attr({fill: "hsb(.6, 1, 1)", stroke: "#fff", "fill-opacity": 0, "stroke-width": 0.8, opacity: .5}), 
      p = R.path("M 250 250 l 0 -50 l -50 0 l 0 -50 l -50 0 l 0 50 l -50 0 l 0 50 z") .attr({fill: "hsb(.8, 1, 1)", stroke: "none", opacity: .5}); 
     var start = function() { 
      this.ox = this.attr("cx"); 
      this.oy = this.attr("cy"); 
      this.animate({r: 70, opacity: .25}, 500, ">"); 
     }, 
     move = function (dx, dy) { 
      this.attr({cx: this.ox + dx, cy: this.oy + dy}); 
     }, 
     up = function() { 
      this.animate({r: 50, opacity: .5}, 500, ">"); 
     }; 
     R.set(r, g, b, p).drag(move, start, up); 
    }; 
</script> 

risposta

1

ho sperimentato con questo un po 'di tempo fa, e ottenuto che funziona utilizzando il seguente approccio:

  • Aggiungi un inizialmente nascosto, stile, div posizionato in modo assoluto con uno sfondo trasparente e uno stile di bordo adatto alla tua pagina, e usando jQuery/UI renderlo trascinabile.
  • Aggiungi un evento click a ciascuno degli elementi Rapahel/SVG che desideri trascinare, e in questo caso aggiungi codice per ridimensionare e riposizionare il div sull'elemento che è stato appena cliccato e renderlo visibile.
  • Aggiungere il codice al div che aggiorna la posizione dell'elemento Raphael quando viene trascinato.

ho esteso questo per aggiungere il ridimensionamento capacità, e anche questo ha funzionato bene, ma andando avanti sarebbe bello vedere il drag, drop e ridimensionare le capacità (idealmente correttamente integrati nella libreria piuttosto che utilizzare jQuery) incorporato in Raphael , in quanto queste funzionalità aprirebbero un sacco di possibilità per i progettisti del browser che utilizzano puro Raffaello.

1

Prova questo per non cerchi. Gli attributi di cerchi sono diversi da immagini, testo, ecc., Penso.

var start = function() { 
     this.ox = this.attr("x"); 
     this.oy = this.attr("y"); 
     this.animate({r: 70, opacity: .25}, 500, ">"); 
    }, 
    move = function (dx, dy) { 
     this.attr({x: this.ox + dx, y: this.oy + dy}); 
    }, 
    up = function() { 
     this.animate({r: 50, opacity: .5}, 500, ">"); 
    }; 
0

non è poi così difficile se si comprendono le solite funzioni di trascinamento che Chris Butler ha fornito. Io uso questo:

var start = function() { 
    //storing original coordinates 
    this.xSource = this.attrs.path[0][1]; 
    this.ySource = this.attrs.path[0][2]; 
    this.xDest = this.attrs.path[1][1]; 
    this.yDest = this.attrs.path[1][2]; 
    this.attr({opacity: 0.5}); 
    }, 
    move = function (dx, dy) { 
    //move will be called with dx and dy 
    var xS = this.xSource+dx; 
    var xD = this.xDest+dx; 
    var yS = this.ySource+dy; 
    var yD = this.yDest+dy; 
    this.attr({path: "M"+ xS +" "+ yS +"L"+ xD +" "+yD}); 
    }, 
    drag = function(){ 
    this.node.drag(this.move,this.start,this.up); 
    }; 

È possibile anche sapere che tipo di figura che state trascinando nelle funzioni con this.type, in modo da poter effettuare queste funzioni di lavoro per tutti i tipi di figure.

13

La chiave qui (che ho trovato) è quella di convertire i delta x e y in valori di traduzione, che l'oggetto del percorso comprende.

http://www.nathancolgate.com/post/2946823151/drag-and-drop-paths-in-raphael-js

efficace lo stesso approccio:

var paper = Raphael(10, 50, 320, 200); 

var tri = paper.path("M0 0L0 20L25 10L0 0Z").attr("fill", "#ff0"); 
var rex = paper.rect(10, 20, 50, 50).attr("fill", "#ff0"); 

var start = function() { 
    this.odx = 0; 
    this.ody = 0; 
    this.animate({"fill-opacity": 0.2}, 500); 
}, 
move = function (dx, dy) { 
    this.translate(dx - this.odx, dy - this.ody); 
    this.odx = dx; 
    this.ody = dy; 
}, 
up = function() { 
    this.animate({"fill-opacity": 1}, 500); 
}; 

tri.drag(move, start, up); 
rex.drag(move, start, up); 
+0

Grazie. Ma c'è un modo per conoscere la posizione finale (assoluta) delle forme? – Yako

+0

Yako, puoi usare getBBox() – Dan

+0

translate è deprecato, vedi la mia risposta per fare questo con transform –

1

io consiglierei di raphael.draggable biblioteca, che rende il trucco per voi. L'ho usato con un'applicazione mappa che consente all'utente di utilizzare lo zoom sulla mappa e quindi trascinarlo.

Ho riscontrato un problema con questa libreria in IE8 perché nella funzione eventi che fanno riferimento a mouse, mouse condiviso, ecc. IE rilascia un'eccezione, dicendo all'utente che event è nullo. Puoi risolverlo sostituendo lo event entro il e e aggiungendo e = e || event nello script raphael.draggable.js. Questa correzione non ha effetto sugli altri browser.

Così, il metodo MouseMove nella startDragger è:

function startDragger() { 
    document.onmousemove = function(e) { 
    e = e || event 
    if (paper.draggable.current()) { 
     var transX = e.clientX - lastDragX; 
     var transY = e.clientY - lastDragY; 

     paper.draggable.current().translate(transX, transY); 
     lastDragX = e.clientX; 
     lastDragY = e.clientY; 
    } 
    }; 
} 

E il link: https://github.com/mephraim/raphael.draggable

Spero che questo potrebbe aiutare.

3

Come Translate è in fase di deprecato a Raphael, ho modificato la risposta di Nathan a lavorare con transform:

var paper = Raphael(10, 50, 320, 200); 

var tri = paper.path("M0 0L0 20L25 10L0 0Z").attr("fill", "#ff0"); 

var start = function() { 
    this.lastdx ? this.odx += this.lastdx : this.odx = 0; 
    this.lastdy ? this.ody += this.lastdy : this.ody = 0; 
    this.animate({"fill-opacity": 0.2}, 500); 
}, 
move = function (dx, dy) { 
    this.transform("T"+(dx+this.odx)+","+(dy+this.ody)); 
    this.lastdx = dx; 
    this.lastdy = dy; 
}, 
up = function() { 
    this.animate({"fill-opacity": 1}, 500); 
}; 

tri.drag(move, start, up); 

Sono relativamente nuovo a Raffaello e si avvicinò con questo attraverso tentativi ed errore, quindi qualcuno là fuori potrebbe avere una spiegazione del perché funziona o un modo più pulito di farlo;)

+0

ecco un violino http://jsfiddle.net/ycqdkgmu/ – danyamachine

+0

Ho provato la risposta sopra con questo percorso stringa: '" M25 370 L10 370 L10 411 L25 411 L25 370 L61 370 L61 411 L25 411 "' Non funziona. Mi chiedo perché? – kittu