如何使用JQuery在2个元素之间绘制一条线并刷新该线?

Stu*_*ser 15 javascript jquery drawing jquery-ui canvas

我正在使用JQuery-UI draggables和droppables将元素克隆到div上.使用JQuery在页面上的元素之间绘制线条的最佳方法是什么.

刷新页面上的线条的最佳方法是什么?我将在页面上有多行,只想更新特定行而不是刷新每一行.

Stu*_*ser 14

我现在有这个工作.

根据我的经验,不要使用jquery.svg,它可能是解决它的压力,而不是学习我的方式绕过另一个插件,但我发现它比它的价值更麻烦,并导致兼容性问题.

可以使用HTML5画布和excanvas兼容性脚本以及一个很棒的html5演练来解决,但是由于HTML5画布的工作原理,它要求画布上的所有linse都被破坏并重新绘制,如果需要删除行或其职位需要更新.

我在其间绘制线条的元素位于表示关系的父元素内.子元素代表一个开始和结束,所以我可以通过获取父母的集合来重绘所有这些关系,例如$('.relationshipClass')并询问集合元素的子元素以获得行的点.
要使用此代码,您必须提出一种方法,以便轻松获取可用于重绘的线点.

标记:
很简单,一个html <div>来保存(最可能是JQuery UI draggables)之间的任何元素,以及一个<canvas>将处于相同位置的html

 <div id="divCanvasId" class="divCanvasClass"></div>
 <canvas id="html5CanvasId"></canvas>
Run Code Online (Sandbox Code Playgroud)

CSS:
不要<canvas>使用CSS 控制元素的宽度,请参阅画布拉伸问题.将其定位<canvas>在与其<div>后面相同的位置(使用z-index),这将显示在其后面的行,<div>并防止<canvas>阻止与其子项的任何拖放交互<div>.

canvas
{
    background-color: #FFFFFF;
    position: absolute;
    z-index: -10;
    /* control height and width in code to prevent stretching */
}
Run Code Online (Sandbox Code Playgroud)

Javascript方法:
创建实用程序方法:示例代码在JQuery插件中,其中包含:

  • 一个帮助函数来重置画布(更改宽度将删除所有
  • 辅助函数,用于在两个元素之间绘制线条
  • 在需要一个元素的所有元素之间绘制线条的函数

添加新线或调整线的位置时,将销毁现有线并绘制所有线.您可以将下面的代码放入常规函数中或作为插件保留.

Javascript代码:
NB在匿名化后未经过测试.

$(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);
        });
    }
Run Code Online (Sandbox Code Playgroud)

您现在可以从事件处理程序(例如JQuery UI的拖动事件)调用这些函数来绘制线条.