2011-01-17 32 views
15

Estoy usando arrastrables y droppables de JQuery-UI para clonar elementos en un div. ¿Cuál es la mejor manera de trazar una línea entre elementos en una página usando JQuery.¿Cómo dibujar una línea entre 2 elementos usando JQuery y refrescar esa línea?

¿Cuál es la mejor manera de actualizar las líneas en la página? Tendré varias líneas en la página y solo quiero actualizar una línea en particular en lugar de actualizar cada línea.

+1

debe consultar esta pregunta: http://stackoverflow.com/questions/536676/how-to-draw-a-line-between-draggable-and-droppable – nunopolonia

+0

+1 para hacer una pregunta sobre mi 'cómo lista para mi aplicación web: espero con interés estas respuestas; ¡El enlace de Yashwant Chavan ya es intrigante! – jlmakes

+0

Gracias @nunopolnia, había visto esa pregunta antes y me gustó la respuesta. Tratar de implementarlo para trazar una línea entre dos arrastres que se movieron después fue bastante doloroso, así que cambié de táctica. También se preguntó si usar 'jquery.svg' para las líneas era mejor que usar' jquery.drawinglibrary' en la parte superior. – StuperUser

Respuesta

14

Ahora tengo esto funcionando.

En mi experiencia, no use jquery.svg, puede haber sido la presión para resolverlo sin aprender a usar otro plugin, pero me pareció más complicado de lo que valía y causó problemas de compatibilidad.

Es posible resolver mediante el canvas de HTML5 y excanvas compatibility script y a great html5 walkthrough, pero debido a cómo funciona el canvas de HTML5, se requiere que todo el linse en el lienzo se destruye y vuelve a dibujar si una línea tiene que ser eliminado o su posición necesita ser actualizado

Los elementos que dibujo entre líneas están dentro de un elemento principal que representa una relación. Los elementos secundarios representan un principio y un final, por lo que puedo volver a dibujar todas estas relaciones obteniendo una colección de los padres usando, por ejemplo, $('.relationshipClass') e interrogar a los elementos de los elementos del conjunto para obtener los puntos de la línea.
Para usar este código, deberá idear un enfoque para obtener fácilmente los puntos de línea disponibles para volver a dibujar.

de marcado:
bonito y sencillo, un html <div> para contener todos los elementos que se dibujan entre (muy probablemente draggables jQuery UI), y una <canvas> que estará en la misma posición

<div id="divCanvasId" class="divCanvasClass"></div> 
<canvas id="html5CanvasId"></canvas> 

CSS:
No controle el ancho del elemento <canvas> con CSS, consulte Question on Canvas streching. Coloque el <canvas> en la misma posición que el <div> y detrás de él (con el índice z), esto mostrará las líneas detrás del <div> y evitará que el <canvas> bloquee las interacciones de arrastrar y soltar con los elementos secundarios del <div>. enfoque

canvas 
{ 
    background-color: #FFFFFF; 
    position: absolute; 
    z-index: -10; 
    /* control height and width in code to prevent stretching */ 
} 

Javascript:
Crear métodos de utilidad: el código de ejemplo está dentro de un JQuery plugin que contiene:

  • una función de ayuda para restablecer el lienzo (cambiando el ancho borrará todos
  • Una función auxiliar para dibujar líneas entre dos elementos
  • Una función que dibuja líneas entre todos los elementos que requiere uno

Cuando agrega una nueva línea o ajusta la posición de una línea, destruye las líneas existentes y dibuja todas las líneas. Puede poner el código a continuación en funciones convencionales o dejarlo como un complemento.

Código de Javascript:
N.B. no probado después de la anonimización

$(document).ready(function() { 
    $.fn.yourExt = { 

     _readjustHTML5CanvasHeight: function() { 
      //clear the canvas by readjusting the width/height 
      var html5Canvas = $('#html5CanvasId'); 
      var canvasDiv = $('#divCanvasId'); 

      if (html5Canvas.length > 0) { 
       html5Canvas[0].width = canvasDiv.width(); 
       html5Canvas[0].height = canvasDiv.height(); 
      } 
     } 
     , 
     //uses HTML5 <canvas> to draw line representing relationship 
     //IE support with excanvas.js 
     _drawLineBetweenElements: function (sourceElement, targetElement) { 

      //draw from/to the centre, not the top left 
      //don't use .position() 
      //that will be relative to the parent div and not the page 
      var sourceX = sourceElement.offset().left + sourceElement.width()/2; 
      var sourceY = sourceElement.offset().top + sourceElement.height()/2; 

      var targetX = targetElement.offset().left + sourceElement.width()/2; 
      var targetY = targetElement.offset().top + sourceElement.height()/2; 

      var canvas = $('#html5CanvasId'); 

      //you need to draw relative to the canvas not the page 
      var canvasOffsetX = canvas.offset().left; 
      var canvasOffsetY = canvas.offset().top; 

      var context = canvas[0].getContext('2d'); 

      //draw line 
      context.beginPath(); 
      context.moveTo(sourceX - canvasOffsetX, sourceY - canvasOffsetY); 
      context.lineTo(targetX - canvasOffsetX, targetY - canvasOffsetY); 
      context.closePath(); 
      //ink line 
      context.lineWidth = 2; 
      context.strokeStyle = "#000"; //black 
      context.stroke(); 
     } 
     , 

     drawLines: function() { 
     //reset the canvas 
     $().yourExt._readjustHTML5CanvasHeight(); 

     var elementsToDrawLinesBetween; 
     //you must create an object that holds the start and end of the line 
     //and populate a collection of them to iterate through 
     elementsToDrawLinesBetween.each(function (i, startEndPair) { 
      //dot notation used, you will probably have a different method 
      //to access these elements 
      var start = startEndPair.start; 
      var end = startEndPair.end; 

      $().yourExt._drawLineBetweenElements(start, end); 
     }); 
    } 

Ahora puede llamar a estas funciones de controladores de eventos (por ejemplo JQuery UI's drag event) para dibujar líneas.

-4

Haz una hr o div con un fondo de 1px de altura, y anima su ancho usando jquery cuando sea necesario.

+1

Esto no funcionará si los elementos no están en el mismo eje Y. Usando los juegos de arrastre, es probable que este no sea el caso. – StuperUser

Cuestiones relacionadas