gpt4 book ai didi

jquery - 获取 svg :image in d3 上放置元素的 xy 坐标

转载 作者:行者123 更新时间:2023-12-01 08:31:57 25 4
gpt4 key购买 nike

这里我正在使用一个示例,其中我需要从 svg:image 元素获取所放置元素的 X 和 Y 值(使用 Jquery 拖放)。请查看我的codepen 。在codepen中,你可以看到一个rss图标,它是可拖动元素,主大图用作可放置元素。主大图像是使用 d3 svg:image 添加的。将 rss 图标拖放到主大图像时,应在拖放点上附加 rss 图标。因此,在 drop 函数(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 可视 Canvas 的比例。删除克隆图像时需要考虑这一点,因为您不能使用绝对上/左坐标。它在 0, 0 处看起来可能不错,但是当您开始远离它时,您会发现图像没有放置在您认为应该放置的位置。

解决这个问题的方法是使用d3.scaleLinear()(文档here)。这将有助于将可放置坐标转换为 svg 的坐标。我将其放在一起的方式是,对于 X 比例,domain 是从 SVG 的 left 属性到 left + width 属性, range 设置为 SVG 的 View 框 x-minwidth 值。 Y 比例使用类似的方法(参见代码)。

SVG 位于页面上的位置

这是接下来要考虑的事情。它与上一个有关 View 框的项目一起出现。例如,如果 SVG 有一些边距,那么您在设置 d3.scaleLinear() 比例时需要考虑这一点。方法是使用 getBoundingClientRectangle(),如下所示:

const clientRect = document.getElementById('floor').getBoundingClientRect();

如果调整窗口大小

如果调整窗口大小,您将需要重置比例。

从可拖动元素中抓取图像的位置

如果您想弄清楚如何获取第一次用鼠标抓取图像时抓取图像的位置的 x,y 偏移量,这可能会增加一些工作。相反,我在 draggable() 方法的配置上使用 cursorAt 属性,并将其设置为 { left: 0, top: 0 } 所以当当您拖动图像时,用户将看到光标位于图像的左上角。这可以让您免于计算他们抓取图像的位置的偏移量。

这是我最终使用的代码(笔 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');
}
});
});

关于jquery - 获取 svg :image in d3 上放置元素的 xy 坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60238749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com