这里我正在使用一个示例,在该示例中,我需要从svg:image元素中获取放置元素的X和Y值(使用Jquery拖放)。请检查我的codepen。在Codepen中,您可以看到一个rss图标,它是可拖动的元素,主要的大图像用作可放置的元素。使用d3 svg:image添加主要的大图像。在将rss图标拖放到主大图像时,应在放置点上附加一个rss图标。因此,在放置函数(JQuery)中,我添加了d3代码以将rss图标附加到主要的大图像上。
我已经使用4种方法来检索放置rss图标的点的X和Y值。在代码笔中,您可以看到:
提取xy正子的第一种方法:
var currentPos = ui.helper.position();
var parentOffset = $(this).parent().offset();
var x1 = event.pageX - parentOffset.left;
var y1 = event.pageY - parentOffset.top;
提取xy正子的第二种方法:
var dropPositionX = event.pageX - $(this).offset().left;
var dropPositionY = event.pageY - $(this).offset().top;
// Get mouse offset relative to dragged item:
var dragItemOffsetX = event.offsetX;
var dragItemOffsetY = event.offsetY;
// Get position of dragged item relative to drop target:
var x2 = dropPositionX-dragItemOffsetX;
var y2 = dropPositionY-dragItemOffsetY;
提取xy正子的第三种方法:
var x3 = ui.offset.left - $(this).offset().left;
var y3 = ui.offset.top - $(this).offset().top;
提取xy正子的第四种方法:
var elem = document.getElementById("floor")
var rect = elem.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;
var x4 = event.pageX-elementLeft;
var y4 = event.pageY-elementTop;
将拖放的图标附加到主要的大图像上:
svg.append("svg:image")
.attr('xlink:href', 'http://icons.webpatashala.com/icons/Blueberry-Basic-Icons/Png/rss-icon.PNG')
.attr('x', x1) //x2, x3, x4, x5
.attr('y', y1); //x2, x3, x4, x5
但是使用所有方法,rss图标不会附加在其放置的确切点上。如何获取确切的X和Y值?
我想我已经知道您要寻找的东西了。对于此问题,需要考虑一些事项:
ViewBox缩放比例
这是要考虑的主要项目。由于您在svg元素上使用viewBox
属性,而不在使用width / height
,因此无论浏览器窗口大小如何,都会更改svg可见画布的比例。在删除克隆的图像时,必须考虑这一点,因为您不能使用绝对top / left
坐标。在0, 0
上看起来可能不错,但是当您开始远离它时,您会注意到该图像没有被丢弃在您认为应该的位置。
解决方法是使用d3.scaleLinear()
(docs here)。这将有助于将可放置坐标转换为svg的坐标。我汇总的方式是,对于X比例尺,domain
从SVG的left
属性更改为left + width
属性,并且range
设置为SVG的视图框x-min
和width
值。 Y比例尺使用类似的方法(请参见代码)。
页面上有SVG的地方
这是接下来要考虑的事情。它与有关视图框的上一项一起使用。例如,如果SVG有一些边距,则在设置d3.scaleLinear()
标度时需要考虑这一点。这样做的方法是像这样使用getBoundingClientRectangle()
:
const clientRect = document.getElementById('floor').getBoundingClientRect();
如果调整窗口大小
如果调整窗口大小,则需要重置比例。
您从可拖动元素中获取图像的位置
如果您想弄清楚如何从第一次使用鼠标抓取图像的位置获取x,y偏移量,这会增加一些工作。相反,我在cursorAt
方法的配置上使用draggable()
属性并将其设置为{ left: 0, top: 0 }
,因此,当您拖动图像时,用户将在图像的左上方看到光标。这使您无需进行计算图像获取位置的偏移量的工作。
这是我最后使用的代码(pen here)(而且,我不得不使用其他图标,因为所使用的图标没有为我加载)。
let scaleX = getScaleX();
let scaleY = getScaleY();
function getScaleX() {
const clientRect = document.getElementById('floor').getBoundingClientRect();
return d3.scaleLinear()
.domain([clientRect.left, clientRect.left + clientRect.width])
.range([0, 1500])
}
function getScaleY() {
const clientRect = document.getElementById('floor').getBoundingClientRect();
return d3.scaleLinear()
.domain([clientRect.top, clientRect.top + clientRect.height])
.range([0, 800])
}
window.onresize = function() {
scaleX = getScaleX();
scaleY = getScaleY();
};
var svg = d3.select('#floor');
svg.append("svg:image")
.attr('xlink:href', 'https://wallpapershome.com/images/pages/pic_h/241.jpg')
.style('width', "100%");
$(function() {
$("#draggable" ).draggable({
helper: "clone",
cursor: 'move',
containment: "document",
cursorAt: { top: 0, left: 0 }
});
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this ).addClass( "ui-state-highlight" );
svg.append("svg:image")
.attr('xlink:href', 'https://i2.wp.com/icons.iconarchive.com/icons/cornmanthe3rd/plex/512/Communication-RSS-icon.png')
.attr('x', scaleX(event.pageX))
.attr('y', scaleY(event.pageY))
.attr('width', '50px');
}
});
});