我有一个网络应用程序,我希望用户通过以下方式绘制一条线:当他单击Point1并移动鼠标时,将线从Point1绘制到当前鼠标位置,然后单击Point2绘制最终从 Point1 到 Point2 的线。
如何使用 jQuery 和/或其插件之一来做到这一点?
我有一个网络应用程序,我希望用户通过以下方式绘制一条线:当他单击Point1并移动鼠标时,将线从Point1绘制到当前鼠标位置,然后单击Point2绘制最终从 Point1 到 Point2 的线。
如何使用 jQuery 和/或其插件之一来做到这一点?
已接受的挑战。
我尝试使用 CSS 转换和一堆 Javascript 中的数学来做到这一点 - 半小时后我有了这个:
在灰色方块上单击 2 次,应绘制一条线。当角度> 45度时,仍然有一个小错误会画线错误。也许其他人知道如何解决这个问题。也许不是使用 Math.asin (arcsinus),而是使用其他三角函数,但我真的不擅长。我想即使有一个小错误我也会发布它,我认为这对你来说是一个好的开始。
这个周末我尝试了许多不同的方法,最适合我的解决方案来自 Adam Sanderson: http: //monkeyandcrow.com/blog/drawing_lines_with_css3/
他的演示在这里: http: //monkeyandcrow.com/samples/css_lines/
它的核心很简单,总是好的。
div.line{
transform-origin: 0 100%;
height: 3px; /* Line width of 3 */
background: #000; /* Black fill */
}
function createLine(x1,y1, x2,y2){
var length = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
var transform = 'rotate('+angle+'deg)';
var line = $('<div>')
.appendTo('#page')
.addClass('line')
.css({
'position': 'absolute',
'transform': transform
})
.width(length)
.offset({left: x1, top: y1});
return line;
}
你不能用 jQuery 和经典的 HTML 来做到这一点。
您可以使用 SVG(IE8 的 +svgweb- http://code.google.com/p/svgweb/)来动态创建 SVG。jQuery + svgweb 完美运行,您只需要知道如何创建 SVG 节点并且您只需要 jquerify 这个节点。在大多数情况下查询后只使用一种方法attr()
您可以使用 Raphael http://raphaeljs.com/(基于 SVG 和 VML)来实现
您可以使用 Canvas(对于 IE8- 为http://flashcanvas.net/ )
对于 SVG 编程将是这样的:
创建第一个点的时刻:您创建空线var Line
(此点坐标也是x1
和y1
)
然后你绑定mousemove
重新绘制Linex2
的y2
属性
冻结最后一行位置mousedown
后打开。mousemove
更新
您可以使用 CSS/JS 来完成,但主要问题在于 IE8- 的计算,它只有用于转换的矩阵过滤器。
一段时间以来一直在使用它的修改版本。效果很好。
http://www.ofdream.com/code/css/xline2.php
因此,在第一次单击时,将其拖放并作为占位符 div 对象,可能是一个小圆圈,然后在他们移动鼠标时继续重画一条线,或者在他们第二次单击时绘制它,使用原始占位符作为指导。
我最近为此制作了另一个辅助函数,因为我的工具涉及移动线条:
function setLinePos(x1, y1, x2, y2, id) {
if (x2 < x1) {
var temp = x1;
x1 = x2;
x2 = temp;
temp = y1;
y1 = y2;
y2 = temp;
}
var line = $('#line' + id);
var length = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
line.css('width', length + "px");
var angle = Math.atan((y2 - y1) / (x2 - x1));
line.css('top', y1 + 0.5 * length * Math.sin(angle) + "px");
line.css('left', x1 - 0.5 * length * (1 - Math.cos(angle)) + "px");
line.css('-moz-transform', "rotate(" + angle + "rad)");
line.css('-webkit-transform', "rotate(" + angle + "rad)");
line.css('-o-transform', "rotate(" + angle + "rad)");
}
那是 jquery 版本,在这个迭代中我没有 IE 要求,所以我忽略了它。我可以很容易地适应原始功能。
班上
function getXY(evt, element) {
var rect = element.getBoundingClientRect();
var scrollTop = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft;
var elementLeft = rect.left + scrollLeft;
var elementTop = rect.top + scrollTop;
x = evt.pageX - elementLeft;
y = evt.pageY - elementTop;
return { x: x, y: y };
}
var LineDrawer = {
LineHTML: `<div style="cursor: pointer;transform-origin:center; position:absolute;width:200px;height:2px; background-color:blue"></div>`,
isDown: false,
pStart: {},
pCurrent :{},
containerID: "",
JLine: {},
angle: 0,
afterLineCallback: null,
Init: function (containerID, afterLineCallback) {
LineDrawer.containerID = containerID;
LineDrawer.afterLineCallback = afterLineCallback;
LineDrawer.JLine = $(LineDrawer.LineHTML).appendTo("#" + LineDrawer.containerID);
LineDrawer.JLine.css("transform-origin", "top left");
LineDrawer.JLine.hide();
//LineDrawer.JLine.draggable({ containment: "#" + LineDrawer.containerID });
$("#" + LineDrawer.containerID).mousedown(LineDrawer.LineDrawer_mousedown);
$("#" + LineDrawer.containerID).mousemove(LineDrawer.LineDrawer_mousemove);
$("#" + LineDrawer.containerID).mouseup(LineDrawer.LineDrawer_mouseup);
},
LineDrawer_mousedown: function (e) {
if (e.target === LineDrawer.JLine[0]) return false;
LineDrawer.isDown = true;
let p = LineDrawer.pStart = getXY(e, e.target);
LineDrawer.JLine.css({ "left": p.x, "top": p.y, "width": 1});
LineDrawer.JLine.show();
},
LineDrawer_mousemove: function (e) {
if (!LineDrawer.isDown) return;
LineDrawer.pCurrent = getXY(e, document.getElementById("jim"));
let w = Math.sqrt(((LineDrawer.pStart.x - LineDrawer.pCurrent.x) * (LineDrawer.pStart.x - LineDrawer.pCurrent.x)) + ((LineDrawer.pStart.y - LineDrawer.pCurrent.y) * (LineDrawer.pStart.y - LineDrawer.pCurrent.y)));
LineDrawer.JLine.css("width", w - 2);
LineDrawer.angle = Math.atan2((LineDrawer.pStart.y - LineDrawer.pCurrent.y), (LineDrawer.pStart.x - LineDrawer.pCurrent.x)) * (180.0 / Math.PI);
//the below ensures that angle moves from 0 to -360
if (LineDrawer.angle < 0) {
LineDrawer.angle *= -1;
LineDrawer.angle += 180;
}
else LineDrawer.angle = 180 - LineDrawer.angle;
LineDrawer.angle *= -1;
LineDrawer.JLine.css("transform", "rotate(" + LineDrawer.angle + "deg");
},
LineDrawer_mouseup: function (e) {
LineDrawer.isDown = false;
if (LineDrawer.afterLineCallback == null || LineDrawer.afterLineCallback == undefined) return;
LineDrawer.afterLine(LineDrawer.angle, LineDrawer.pStart, LineDrawer.pCurrent);
},
};
用法:
var ECApp = {
start_action: function () {
LineDrawer.Init("jim", ECApp.afterLine);
},
afterLine(angle, pStart, pEnd) {
//$("#angle").text("angle : " + angle);
let disp = "angle = " + angle;
disp += " Start = " + JSON.stringify(pStart) + " End = " + JSON.stringify(pEnd);
//alert(disp);
$("#angle").text("angle : " + disp);
}
}
$(document).ready(ECApp.start_action);
HTML
<div class="row">
<div class="col">
<div id="jim" style="position:relative;width:1200px;height:800px;background-color:lightblue;">
</div>
</div>