Javascript 我可以使用 jQuery 画一条线吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11743386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I draw a line using jQuery?
提问by Cris
I have a web app where I would like the user to draw a line in the following way: When he clicks on Point1and he moves the mouse, draw the line from Point1to the current mouse positionand, when clicks to Point2draw the final line from Point1 to Point2.
我有一个网络应用程序,我希望用户通过以下方式画一条线:当他点击Point1并移动鼠标时,从Point1到当前鼠标位置绘制线,当点击Point2 时绘制最终从 Point1 到 Point2 的线。
How can I do it using jQuery and/or one of its plugins?
我如何使用 jQuery 和/或其插件之一来做到这一点?
回答by Jonny Burger
Challenge accepted.
已接受的挑战。
I tried to do it with CSS transforms and a bunch of Math in Javascript - after half an hour I have this:
我试图用 CSS 转换和一堆 Javascript 中的数学来做到这一点 - 半小时后我得到了这个:
Make 2 clicks into the gray square and a line should be drawn. There is still a small bug that draws the line wrong when the angle is > 45 degree. Maybe someone else knows how to fix that. Maybe instead of using Math.asin (arcsinus), use a other trigonometrical function, but I'm really not good at it. I thought I'd post it even there is a small bug, I think it's a good start for you.
在灰色方块中单击 2 次,应绘制一条线。当角度> 45度时,仍然有一个小错误会画错线。也许其他人知道如何解决这个问题。也许不是使用 Math.asin (arcsinus),而是使用其他三角函数,但我真的不擅长。我想即使有一个小错误我也会发布它,我认为这对你来说是一个好的开始。
回答by BaronGrivet
I've tried a number of different approaches this weekend and the solution that worked best for me is from Adam Sanderson: http://monkeyandcrow.com/blog/drawing_lines_with_css3/
本周末我尝试了许多不同的方法,最适合我的解决方案来自 Adam Sanderson:http: //monkeyandcrow.com/blog/drawing_lines_with_css3/
His demo is here: http://monkeyandcrow.com/samples/css_lines/
他的演示在这里:http: //monkeyandcrow.com/samples/css_lines/
The core of it is very simple, which is always good.
它的核心非常简单,这总是好的。
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;
}
回答by Rustam
You can not do it with jQuery and classic HTML.
你不能用 jQuery 和经典的 HTML 来做到这一点。
You can do it using SVG (+svgweb for IE8- http://code.google.com/p/svgweb/) SVG can be dynamically created. jQuery + svgweb are working perfectly, you just need to know how to create SVG nodes and you need only jquerify this nodes. After jquerifiing in most cases used only one method
attr()
You can do it using Raphael http://raphaeljs.com/(based on SVG and VML)
You can do it using Canvas ( http://flashcanvas.net/for IE8- )
您可以使用 SVG (+svgweb for IE8- http://code.google.com/p/svgweb/) 来实现 SVG 可以动态创建。jQuery + svgweb 完美运行,您只需要知道如何创建 SVG 节点,并且只需要对这些节点进行 jquerify。大部分情况下jquery之后只用了一种方法
attr()
你可以使用 Raphael http://raphaeljs.com/(基于 SVG 和 VML)
您可以使用 Canvas ( http://flashcanvas.net/for IE8- )
For SVG programming will be this way:
对于 SVG 编程将是这样的:
Moment of creating first point: you create empty line
var Line
(also this points coordinates will bex1
andy1
)Then you bind on
mousemove
repaint ofx2
,y2
properties of LineOn
mousedown
aftermousemove
you freeze last line position.
创建第一个点的时刻:您创建空线
var Line
(此点坐标将为x1
andy1
)然后你绑定
mousemove
的重绘x2
,y2
线的性质在您冻结最后一行位置
mousedown
后mousemove
打开。
UPDATE
更新
You can do it with CSS/JS, but main problem is in calculations for IE8-, that has only Matrix filter for transformations.
你可以用 CSS/JS 来做,但主要问题是在 IE8- 的计算中,它只有用于转换的矩阵过滤器。
回答by ClickMatch
Been using a modified version of this for a while now. Works well.
一段时间以来一直在使用这个的修改版本。效果很好。
http://www.ofdream.com/code/css/xline2.php
http://www.ofdream.com/code/css/xline2.php
So on first click, drop and object there as a placeholder div, maybe a little circle, then either keep redrawing a line as they move their mouse, or draw it when they click the second time, using the original placeholder as a guide.
因此,在第一次单击时,将对象放在那里作为占位符 div,可能是一个小圆圈,然后在移动鼠标时继续重画一条线,或者在第二次单击时绘制一条线,使用原始占位符作为指导。
I recently made another helper function for this, because my tool involves moving lines around:
我最近为此做了另一个辅助函数,因为我的工具涉及移动线:
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)");
}
That is the jquery version, and in this iteration I have no IE requirement so I ignore it. I could be adapted from the original function pretty easily.
那是 jquery 版本,在这次迭代中我没有 IE 要求,所以我忽略了它。我可以很容易地从原始功能中改编。
回答by Dr.Sai
The class
班上
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);
},
};
Usage:
用法:
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
HTML
<div class="row">
<div class="col">
<div id="jim" style="position:relative;width:1200px;height:800px;background-color:lightblue;">
</div>
</div>