【发布时间】:2019-08-17 12:06:50
【问题描述】:
我有多个 svg 组(每个都包含一个圆圈和文本),我通过 d3-drag 从初始位置拖动它们。我有一个矩形点击区域,我一次只想要其中一个可拖动组。因此,每当有两组处于命中区域时,我希望处于命中区域的第一组消失并重新出现在其初始位置。
我尝试通过一个函数来执行此操作,该函数通过查找圆形的当前位置并翻译如下:将组翻译回其初始位置:
translate(${-current_x}, ${-current_y})
这确实将组转换回 (0,0) 位置,所以我必须偏移它的初始位置。我通过将圆形的初始 x 和 y 值设置为圆形元素中的属性并将它们合并到翻译中来做到这一点:
translate(${-current_x + initial_x}, ${-current_y + initial_y})
这是我尝试的一部分:
https://bl.ocks.org/interwebjill/fb9b0d648df769ed72aeb2755d3ff7d5
这里是sn-p形式:
const circleRadius = 40;
const variables = ['one', 'two', 'three', 'four'];
const inZone = [];
// DOM elements
const svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
const dragDockGroup = svg.append('g')
.attr('id', 'draggables-dock');
const dock = dragDockGroup.selectAll('g')
.data(variables)
.enter().append("g")
.attr("id", (d, i) => `dock-${variables[i]}`);
dock.append("circle")
.attr("cx", (d, i) => circleRadius * (2 * i + 1))
.attr("cy", circleRadius)
.attr("r", circleRadius)
.style("stroke", "none")
.style("fill", "palegoldenrod");
dock.append("text")
.attr("x", (d, i) => circleRadius * (2 * i + 1))
.attr("y", circleRadius)
.attr("text-anchor", "middle")
.style("fill", "white")
.text((d, i) => variables[i]);
const draggablesGroup = svg.append('g')
.attr('id', 'draggables');
const draggables = draggablesGroup.selectAll('g')
.data(variables)
.enter().append("g")
.attr("id", (d, i) => variables[i])
.call(d3.drag()
.on("start", dragStarted)
.on("drag", dragged)
.on("end", dragEnded));
draggables.append('circle')
.attr("cx", (d, i) => circleRadius * (2 * i + 1))
.attr("cy", circleRadius)
.attr("initial_x", (d, i) => circleRadius * (2 * i + 1))
.attr("initial_y", circleRadius)
.attr("r", circleRadius)
.style("stroke", "orange")
.style("fill", "yellowgreen");
draggables.append("text")
.attr("x", (d, i) => circleRadius * (2 * i + 1))
.attr("y", circleRadius)
.attr("text-anchor", "middle")
.style("fill", "white")
.text((d, i) => variables[i]);
svg.append('rect')
.attr("x", 960/2)
.attr("y", 0)
.attr("width", 100)
.attr("height", 500/2)
.attr("fill-opacity", 0)
.style("stroke", "#848276")
.attr("id", "hitZone");
// functions
function dragStarted() {
d3.select(this).raise().classed("active", true);
}
function dragged() {
d3.select(this).select("text").attr("x", d3.event.x).attr("y", d3.event.y);
d3.select(this).select("circle").attr("cx", d3.event.x).attr("cy", d3.event.y);
}
function dragEnded() {
d3.select(this).classed("active", false);
d3.select(this).lower();
let hit = d3.select(document.elementFromPoint(d3.event.sourceEvent.clientX, d3.event.sourceEvent.clientY)).attr("id");
if (hit == "hitZone") {
inZone.push(this.id);
if (inZone.length > 1) {
let resetVar = inZone.shift();
resetCircle(resetVar);
}
}
d3.select(this).raise();
}
function resetCircle(resetVar) {
let current_x = d3.select(`#${resetVar}`)
.select('circle')
.attr('cx');
let current_y = d3.select(`#${resetVar}`)
.select('circle')
.attr('cy');
let initial_x = d3.select(`#${resetVar}`)
.select('circle')
.attr('initial_x');
let initial_y = d3.select(`#${resetVar}`)
.select('circle')
.attr('initial_y');
d3.select(`#${resetVar}`)
.transition()
.duration(2000)
.style('opacity', 0)
.transition()
.duration(2000)
.attr('transform', `translate(${-current_x}, ${-current_y})`)
.transition()
.duration(2000)
.style('opacity', 1);
}
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
<script src="https://d3js.org/d3.v5.min.js"></script>
以下是问题:
虽然使用
translate(${-current_x}, ${-current_y})有效,但当我尝试使用translate(${-current_x + initial_x}, ${-current_y + initial_y})时,转换使用非常大的负数(例如,translate(-52640, -4640))。虽然使用
translate(${-current_x}, ${-current_y})有效,但当我再次尝试拖动此翻译组时,该组立即重复之前的translate(${-current_x}, ${-current_y})
【问题讨论】:
标签: javascript d3.js svg transform