将鼠标指针放在拉斐尔的 line/path 上

Position mouse pointer on line/path in Raphael

在这个 jsFiddle 中,我有一个 Raphael canvas 和一个 line/path 用户可以拖动它。

问题是鼠标指针的确切顶部像素必须在线上才能拖动它。我需要 Raphael 更多 "forgiving" 并让用户拖动线,如果它触及顶部,比如说,指针的 3 个像素。

我添加了 mouseover/mouseout 事件来实际判断鼠标何时越过线,否则很难知道。

那么问题来了:有没有办法不用鼠标指针准确定位就可以拖线?

var paper = Raphael("canvas", 600, 600); 
var line = this.paper.path('M10 10 L50 50');

var start = function () {
      this.odx = 0;
      this.ody = 0;
},
move = function (dx, dy) {
      this.translate(dx - this.odx, dy - this.ody);
      this.odx = dx;
      this.ody = dy;
},
up = function () {};

line.drag(move, start, up);

line.mouseover(function(e) {
    line.attr('stroke', 'red');
});

line.mouseout(function(e) {
  line.attr('stroke', 'black');
});

Raphael 库创建一个 SVG 元素(不是 CANVAS 元素)用于绘图目的,并且绘图线在 SVG 元素内创建 PATH 元素。

我通过增加悬停时的线宽取得了一些成功。您至少必须通过将鼠标移到线上来触发宽度变化,但之后 select 会容易得多。虽然产生的视觉效果可能不完美(可能会出现一些宽度闪烁),但继续拖动操作没有问题。

您可以尝试通过修改 mouseovermouseout 处理程序中的 stroke-width 属性来增加线宽:

line.mouseover(function(e) {
    line.attr('stroke', 'red');
    line.attr('stroke-width', '9')
});

line.mouseout(function(e) {
  line.attr('stroke', 'black');
  line.attr('stroke-width', '1')
});

或通过使用

将鼠标悬停在 CSS 中的所有路径元素上时修改 stroke-width 样式
path:hover {
   stroke-width: 9;
}


根据 this question Raphael 没有提供所有可能的 CSS 样式的抽象,因此它可以在 XML 文档中使用 VML。如果您可以在没有 IE 9 支持的情况下生活并希望用户拥有现代浏览器,您可能会对以下代码段感兴趣

  • 通过设置 class 名称 draggable 来增加 mouseover 上的行的宽度,这会设置 move 光标,
  • 开始移动时,将 draggable 替换为 dragging(移除宽度增加)并在 svg 容器上设置 move 光标,
  • mouseout
  • 上删除 class draggable,但不删除 dragging
  • 清理 classes 和 up 函数中的光标。

"use strict";
var container = document.getElementById("canvas");
var paper = Raphael("canvas", 600, 600);
var line = this.paper.path('M10 10 L50 50');
var start = function () {
   this.odx = 0;
   this.ody = 0;
},
move = function (dx, dy) {
    this.translate(dx - this.odx, dy - this.ody);
    this.odx = dx;
    this.ody = dy;
    if( this.node.classList.contains("draggable")) {
        this.node.classList.replace("draggable", "dragging");
        container.classList.add("moveCursor");
    }
}, 
up = function (e) {
    line.node.classList.remove("draggable", "dragging");
    container.classList.remove("moveCursor");
};

line.drag(move, start, up);
line.mouseover(function(e) {
    if(!e.target.classList.contains("dragging")) {
        e.target.setAttribute("class", "draggable");
    }
});
.draggable:hover {
    stroke-width: 9;
    stroke:red;
    cursor: move;
} 
path.dragging {
    stroke: red;
}
.moveCursor{
    cursor:move;
}
svg {
   border: thin solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>

<!-- body-html -->
<div id="canvas"></div>

该代码主要用于演示 - 如果您在 SVG 元素之外拖出一条线,您将看不到它或抓住它拖回来。

一些 CSS 规则(即 path.dragging)需要额外的特殊性以优先于 Raphael 提供的默认值。