不确定究竟该怎么称呼它,但是当我点击并拖动某个区域时,我正在寻找一种通过javascript / svg创建虚线轮廓/选择框效果的方法,然后在mouseUp上消失(可能是如果它不是原始部分则添加。)
如果存在jQuery库会很好。我做了一些环顾四周,并没有找到我正在寻找的东西 我猜理论是从第一次点击获得坐标,跟踪鼠标坐标时刻并相应地调整框。
但不是从头开始写它会很好。
答案 0 :(得分:15)
这是我为你制作的演示:)
您可以使用CSS来控制选框的视觉样式。
您可以将一个或两个函数传递给trackMarquee
方法;将使用四个参数调用它们:选取框的x1,y1,x2,y2边界。释放选框时将调用第一个函数。每次选框移动时都会调用第二个函数(如果存在)(例如,您可以计算该边框内的项目。)
当您开始拖动SVG文档(或您选择跟踪的任何元素)时,它将创建<rect class="marquee" />
;在拖动过程中它会调整矩形的大小。使用CSS(如演示中所示)可以根据需要设置此矩形的样式。我正在使用stroke-dasharray
属性来使边框点缀。
对于Stack Overflow后代,这里是代码(关于JSFiddle关闭的可能性):
(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);
答案 1 :(得分:4)
你很幸运我自己做了这个。我正在使用jQuery SVG插件(http://keith-wood.name/svg.html)
$("#paper2").mousedown(function(ev) {
ev.preventDefault();
var pX= (ev.pageX - this.offsetLeft) * viewBox[2]/parseInt($("#paper2").css("width"));
var pY= (ev.pageY - this.offsetTop) * viewBox[3]/parseInt($("#paper2").css("height"));
var rect = svg2.rect(
pX, //X
pY, //Y
1,1, //width and height
{ //Settings, you can make the box dotted here
fill: 'black', "fill-opacity": 0.3, stroke: 'red', strokeWidth: 3, id:rect
}
)
$("#paper2").mousemove(function(ev) {
ev.preventDefault();
var rect= $('#rect');
var pX= (ev.pageX - this.offsetLeft) * viewBox[2]/parseInt($("#paper2").css("width")) - rect.attr("x");
var pY= (ev.pageY - this.offsetTop) * viewBox[3]/parseInt($("#paper2").css("height")) - rect.attr("y");
rect.attr("width", pX);
rect.attr("height", pY);
});
$("#paper2").mouseup(function(ev) {
ev.preventDefault();
var div= $("#paper2");
div.unbind('mousemove');
div.unbind('mouseup');
})
});
paper2是一个div,其中我有一个svg元素(所以svg元素和div具有相同的高度/宽度)。这就是我创建svg2元素的方式:
var svg2;
var root2;
$(document).ready(function() {
$("#paper2").svg({
onLoad: function() {
svg2= $("#paper2").svg('get');
svg2.configure({id: 'svg2'});
var div= $("#paper2");
root2= svg2.root();
$("#svg2").attr("viewBox", viewBox[0]+','+viewBox[1]+','+viewBox[2]+','+viewBox[3]);
},
settings: {}
});
}
如果你没有在svg元素上使用viewbox,你在计算中不需要这个:
* viewBox[2]/parseInt($("#paper2").css("*****"));
viewbox [2]将是视图框宽度,viewbox [3]将是视图框高度。