保持PaperJS拖动项目的焦点(草图)

发布于 2025-02-10 13:21:30 字数 2501 浏览 2 评论 0原文

我有一个函数clastEstpointData要确定一条线的最接点,通过显示红点并确定需要拖动哪个点来突出显示该点。

我的公差有问题,当我拖动太快时,鼠标会“掉落”这一点。

How can I ensure I don't exceed the tolerance of 30px

See Sketch for working version

line = new Path.Line([90, 90], [250, 250]);
line.strokeColor = 'black';
line.strokeWidth = 3;

var redDot = new Path.Circle({
  center: view.center,
  radius: 3,
  fillColor: 'transparent',
  position: [90, 90]
});

function onMouseDrag(e) {
  var cpd = closestPointData(e);
  if (cpd.closestDistance < 30) {
    line.segments[cpd.closestPointIndex].point = e.point;
    redDot.position = cpd.usePoint;
  }
}


function onMouseMove(e) {
  var cpd = closestPointData(e);
  if (cpd.closestDistance < 30) {
    redDot.position = cpd.usePoint;
    redDot.fillColor = 'red';
  }else{
    redDot.fillColor = 'transparent';
  }
}

// Determine which of the line segment points is closest to the mouse pointer
function closestPointData(e) {
  var closestPointIndex = null;
  var closestDistance = Infinity;
  var usePoint; // segment point coordinates
  // console.log(line.segments);
  
  // get point from each end of segment
  for (var i = 0; i < line.segments.length; i++) {
    var pointAt = line.getPointAt(line.segments[i]);
    var distance = e.point.getDistance(pointAt);
    
    // Qualify shortest distance
    if (distance < closestDistance) {
      closestDistance = distance;
      closestPointIndex = i;
      usePoint = pointAt;
    }
  }
  return {
    closestPointIndex: closestPointIndex,
    closestDistance: closestDistance,
    usePoint: usePoint
  };
}

I have a function closestPointData to determine the closest point of a line, highlight that point by showing a red dot and to determine which point needs to be dragged.

I'm having a problem with the tolerance, when I drag too fast, the mouse "drops" the point.

How can I ensure I don't exceed the tolerance of 30px

See Sketch for working version

line = new Path.Line([90, 90], [250, 250]);
line.strokeColor = 'black';
line.strokeWidth = 3;

var redDot = new Path.Circle({
  center: view.center,
  radius: 3,
  fillColor: 'transparent',
  position: [90, 90]
});

function onMouseDrag(e) {
  var cpd = closestPointData(e);
  if (cpd.closestDistance < 30) {
    line.segments[cpd.closestPointIndex].point = e.point;
    redDot.position = cpd.usePoint;
  }
}


function onMouseMove(e) {
  var cpd = closestPointData(e);
  if (cpd.closestDistance < 30) {
    redDot.position = cpd.usePoint;
    redDot.fillColor = 'red';
  }else{
    redDot.fillColor = 'transparent';
  }
}

// Determine which of the line segment points is closest to the mouse pointer
function closestPointData(e) {
  var closestPointIndex = null;
  var closestDistance = Infinity;
  var usePoint; // segment point coordinates
  // console.log(line.segments);
  
  // get point from each end of segment
  for (var i = 0; i < line.segments.length; i++) {
    var pointAt = line.getPointAt(line.segments[i]);
    var distance = e.point.getDistance(pointAt);
    
    // Qualify shortest distance
    if (distance < closestDistance) {
      closestDistance = distance;
      closestPointIndex = i;
      usePoint = pointAt;
    }
  }
  return {
    closestPointIndex: closestPointIndex,
    closestDistance: closestDistance,
    usePoint: usePoint
  };
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱桃奶球 2025-02-17 13:21:30

我认为,仅当没有onMouseMove 时,onMousedRag处理程序才有用,否则,它会有些混乱。
I would do it this way.

// Set target size.
const MIN_DISTANCE = 30;

// Create items.
const path = new Path.Line({
    from: view.center,
    to: view.center + 150,
    strokeColor: 'black',
    strokeWidth: 2,
});
const dot = new Path.Circle({
    center: view.center,
    radius: 5,
    fillColor: 'transparent',
});

// Create state variables.
// This will store the active path point.
let activePoint;
// This will allow us to check if we are currently dragging or not.
let dragging = false;

function onMouseDown() {
    dragging = true;
}

function onMouseMove(event) {
    // If we are not currently dragging...
    if (!dragging) {
        // ...look for the closest path point...
        const closest = path.segments
            .map((it) => ({point: it.point, distance: it.point.getDistance(event.point)}))
            .sort((a, b) => a.distance - b.distance)
            .shift();
        // ...and if it is close enough...
        if (closest.distance <= MIN_DISTANCE) {
            // ...show the dot...
            dot.fillColor = 'red';
            dot.position = closest.point;
            // ...and store the active point.
            activePoint = closest.point;
        }
        // Otherwise...
        else {
            // ...hide the dot...
            dot.fillColor = 'transparent';
            // ...and store no active point.
            activePoint = null;
        }
    }
    // If we are dragging and there is an active point...
    else if (activePoint) {
        // ...move the dot...
        dot.position += event.delta;
        // ...and move the path point.
        activePoint.x = dot.position.x;
        activePoint.y = dot.position.y;
    }
}

function onMouseUp() {
    dragging = false;
}

In my opinion, the onMouseDrag handler is usefull only when there is no onMouseMove, otherwise, it gets a bit confusing.
I would do it this way.

// Set target size.
const MIN_DISTANCE = 30;

// Create items.
const path = new Path.Line({
    from: view.center,
    to: view.center + 150,
    strokeColor: 'black',
    strokeWidth: 2,
});
const dot = new Path.Circle({
    center: view.center,
    radius: 5,
    fillColor: 'transparent',
});

// Create state variables.
// This will store the active path point.
let activePoint;
// This will allow us to check if we are currently dragging or not.
let dragging = false;

function onMouseDown() {
    dragging = true;
}

function onMouseMove(event) {
    // If we are not currently dragging...
    if (!dragging) {
        // ...look for the closest path point...
        const closest = path.segments
            .map((it) => ({point: it.point, distance: it.point.getDistance(event.point)}))
            .sort((a, b) => a.distance - b.distance)
            .shift();
        // ...and if it is close enough...
        if (closest.distance <= MIN_DISTANCE) {
            // ...show the dot...
            dot.fillColor = 'red';
            dot.position = closest.point;
            // ...and store the active point.
            activePoint = closest.point;
        }
        // Otherwise...
        else {
            // ...hide the dot...
            dot.fillColor = 'transparent';
            // ...and store no active point.
            activePoint = null;
        }
    }
    // If we are dragging and there is an active point...
    else if (activePoint) {
        // ...move the dot...
        dot.position += event.delta;
        // ...and move the path point.
        activePoint.x = dot.position.x;
        activePoint.y = dot.position.y;
    }
}

function onMouseUp() {
    dragging = false;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文