您将如何创建 JQuery/svg 单击拖动选择轮廓效果?
不知道到底该怎么称呼它,但我正在寻找一种方法来通过 javascript/svg 创建虚线轮廓/选择框效果,当您单击并拖动到某个区域时,然后在 mouseUp 上消失(可能是如果它不是原始部分,则添加).
Not sure exactly what to call it, but I am looking for a way to create a dotted outline/selection box effect via javascript/svg when you click and drag over an area, and then goes away on mouseUp (that could be added if it wasn't an original part) .
如果有 jQuery 库,那就太好了.我环顾四周,并没有找到我要找的东西.
我猜理论是从第一次点击中获取坐标,跟踪鼠标坐标时刻并相应地调整框.
A jQuery library would be nice if it exists. I've done some looking around, and haven't found exactly what I am looking for.
I guess the theory would be get the coord from the first click, track the mouse coord moment and adjust the box accordingly.
但不要从头开始编写它会很好.
But not writing it from scratch would be nice.
推荐答案
这是我专门为你制作的演示 :)
Here's a demo I made just for you :)
您可以使用 CSS 来控制选取框的视觉样式.您可以将一两个函数传递给 trackMarquee
方法;两者都将使用四个参数调用:选取框的 x1,y1,x2,y2 边界.释放选取框时将调用第一个函数.每次选取框移动时都会调用第二个函数(如果存在)(例如,您可以计算该边界框中的项目).
You can use CSS to control the visual style of the marquee.
You can pass one or two functions to the trackMarquee
method; both will be called with four arguments: the x1,y1,x2,y2 bounds of the marquee. The first function will be called when the marquee is released. The second function (if present) will be called each time the marquee moves (so that you can, for example, calculate what items are within that bounding box).
当您开始拖动 SVG 文档(或您选择跟踪的任何元素)时,它将创建一个 <rect class="marquee"/>
;在拖动过程中,它将调整矩形的大小.使用 CSS(如演示中所示)为这个矩形设置任何你想要的样式.我正在使用 stroke-dasharray
属性以使边框为虚线.
When you start dragging on the SVG document (or whatever element you choose to track) it will create a <rect class="marquee" />
; during dragging it will adjust the size of the rectangle. Use CSS (as seen in the demo) to style this rectangle however you want. I'm using the stroke-dasharray
property to make the border dotted.
对于 Stack Overflow 的后代,这里是代码(如果 JSFiddle 出现故障):
For Stack Overflow posterity, here's the code (on the off chance that JSFiddle is down):
(function createMarquee(global){
var svgNS = 'http://www.w3.org/2000/svg',
svg = document.createElementNS(svgNS,'svg'),
pt = svg.createSVGPoint();
// Usage: trackMarquee( mySVG, function(x1,y1,x2,y2){}, function(x1,y1,x2,y2){} );
// The first function (if present) will be called when the marquee is released
// The second function (if present) will be called as the marquee is changed
// Use the CSS selector `rect.marquee` to select the marquee for visual styling
global.trackMarquee = function(forElement,onRelease,onDrag){
forElement.addEventListener('mousedown',function(evt){
var point0 = getLocalCoordinatesFromMouseEvent(forElement,evt);
var marquee = document.createElementNS(svgNS,'rect');
marquee.setAttribute('class','marquee');
updateMarquee(marquee,point0,point0);
forElement.appendChild(marquee);
document.documentElement.addEventListener('mousemove',trackMouseMove,false);
document.documentElement.addEventListener('mouseup',stopTrackingMove,false);
function trackMouseMove(evt){
var point1 = getLocalCoordinatesFromMouseEvent(forElement,evt);
updateMarquee(marquee,point0,point1);
if (onDrag) callWithBBox(onDrag,marquee);
}
function stopTrackingMove(){
document.documentElement.removeEventListener('mousemove',trackMouseMove,false);
document.documentElement.removeEventListener('mouseup',stopTrackingMove,false);
forElement.removeChild(marquee);
if (onRelease) callWithBBox(onRelease,marquee);
}
},false);
};
function callWithBBox(func,rect){
var x = rect.getAttribute('x')*1,
y = rect.getAttribute('y')*1,
w = rect.getAttribute('width')*1,
h = rect.getAttribute('height')*1;
func(x,y,x+w,y+h);
}
function updateMarquee(rect,p0,p1){
var xs = [p0.x,p1.x].sort(sortByNumber),
ys = [p0.y,p1.y].sort(sortByNumber);
rect.setAttribute('x',xs[0]);
rect.setAttribute('y',ys[0]);
rect.setAttribute('width', xs[1]-xs[0]);
rect.setAttribute('height',ys[1]-ys[0]);
}
function getLocalCoordinatesFromMouseEvent(el,evt){
pt.x = evt.clientX; pt.y = evt.clientY;
return pt.matrixTransform(el.getScreenCTM().inverse());
}
function sortByNumber(a,b){ return a-b }
})(window);
相关文章