初始“跳跃”拖动行为

Initial "jumpy" dragging behavior

本文关键字:拖动 跳跃 初始      更新时间:2023-09-26

下面的代码创建一个背景和一个矩形。可以拖动矩形:

var p = {
  x: 0,
  y: 0
} 
var width = 400
var height = 400
var svg = d3.select('body').append('svg')
  .attr('width', width)
  .attr('height', height)
svg.append('rect')
  .attr('class', 'bg')
  .attr('width', width)
  .attr('height', height)
var drag = d3.behavior.drag()
  .on('drag', dragmove)
svg.append('rect')
  .attr('class', 'btn')
  .attr('width', 100)
  .attr('height', 50)
  .attr('transform', 'translate(' + p.x + ',' + p.y + ')')
  .call(drag)
function dragmove (d) {
  var x = d3.event.x
  var y = d3.event.y
  d3.select(this)
    .attr('transform', 'translate(' + x + ',' + y + ')')
}

拖动事件有效,但每次拖动对象时都有一个初始"跳转"(例如,矩形从光标左侧开始,然后突然跳到右侧)。

你可以在这里看到它:https://jsfiddle.net/alexcheninfo/5rnv7ww5/

是什么原因造成的以及如何防止它(使矩形从一开始就平滑拖动)?

应该是这样的:

//get the translate on the dragged rectangle
var translate = d3.transform(d3.select(this).attr("transform")).translate;
//to that add the mouse move deltax 
                x = d3.event.dx + translate[0],
                y = d3.event.dy + translate[1];

工作代码在这里

当你这样做时

var x = d3.event.x
  var y = d3.event.y
  d3.select(this)
    .attr('transform', 'translate(' + x + ',' + y + ')')

它将矩形转换为鼠标位置,从而跳转。

您需要

指定拖动行为的起源。默认情况下,使用基础数据对象。在您的情况下 - 它是p对象。因此,您需要这样做:

var drag = d3.behavior.drag()
    .origin(function() { return p; })
    .on('drag', dragmove)

并在每次拖动时更新其 x 和 y 属性

function dragmove (d) {
    // ...
    // normally you would update d.x and d.y
    p.x = d3.event.x;
    p.y = d3.event.y;
    // ...
}

请参阅更新的小提琴。

在 d3 v4 中,这称为拖动主题。

对于那些挣扎的人,我的50美分。在 d3 js v7 中没有 event.dx 或 event.dy 属性,相反,您必须读取 event.movementXevent.movementY 属性。这是我的工作代码(我只需要 x 位置)。getTokenizedTransformAttributeValue方法取自此处:https://www.it-swarm-es.com/es/javascript/sustitucion-de-d3.transform-en-d3-v4/825493251/

self=this; 
const consty = 100; //example
let dragHandler = this.d3.drag()
     .on("drag", function() {
          const inputTrasformString = self.d3.select(this).attr("transform");
          var transformObject = self.getTokenizedTransformAttributeValue(inputTrasformString);     
          x = event.movementX+parseInt(transformObject.translate[0])
                     
          self.d3.select(this)
              .attr("transform", "translate("+x+","+consty+")");
          }).on("start",function() {
        //something
                }).on("end", function() {
        //something
              });
            
dragHandler(svg.select(".myclass"));