Reputation: 1071
In this jsFiddle I have a Raphael canvas with a line/path where the user can drag it.
Problem is that the exact top pixel of the mouse pointer has to be on the line to be able to drag it. I need Raphael to be more "forgiving" and let the user drag the line if it touches the top, say, 3 pixels of the pointer.
I added mouseover/mouseout
events to actually tell when the mouse is over the line, otherwise is very difficult to know.
So the question is: is there a way to drag the line without having to accurately position the mouse pointer?
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');
});
Upvotes: 1
Views: 360
Reputation: 19301
The Raphael library creates an SVG element (not a CANVAS element) for drawing purposes, and drawing lines creates PATH elements within the SVG element.
I had some success by increasing the line width on hover. You do have to trigger the width change by at least moving the mouse over the line, but it is a lot easier to select afterwards. While the visual effect produced may not be perfect (some width flicking can occur) continuing the drag operation proceeds without problem.
You could try increasing the line width by either modifying the stroke-width
attribute in the mouseover
and mouseout
handlers:
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')
});
or by modifying the stroke-width
styling when hovering over all path elements in CSS using
path:hover {
stroke-width: 9;
}
mouseover
by setting class name draggable
, which sets a move
cursor,draggable
with dragging
( which removes the width increase) and sets a move
cursor over the svg container,draggable
, but not dragging
, on mouseout
up
function."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>
The code is basically for demonstration - if you drag a line outside the SVG element you can't see it or grab it to drag back.
Some CSS rules (i.e. path.dragging
) needed additional specificity to take priority over the defaults supplied by Raphael.
Upvotes: 2