You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by "K. W. Landry" <kw...@gmail.com> on 2006/12/12 03:51:34 UTC
Limiting Drag
Folks,
What techniques would you use for limiting the drag of an element to within
the bounds of another element?
That is, using the code below, the Circle "rateButton" moves very smoothly
all along its' Y axis(it's also contained within a thread for the
UpdateManager runnable queue which is not shown here).
However, it also moves well outside the rectangle rateSlideBase, that is, it
doesn't stop within that rectangle, it moves well beyond the "Y" of the top
of the rectangle and well below the bottom of the rectangle. I previously
used the rectangles "Y" and height attributes to very successfully limit
the rateButton from exceeding the rectangles bounds. But this no longer
works when using the SVGLocatable points and transform matrix, and isn't
useful when the canvas is resized/zoomed, etc...,
if(grab) {
// DOMMouseEvent elementEvent = (DOMMouseEvent) event;
int dragMoveX = dm.getClientX();
int dragMoveY = dm.getClientY();
SVGOMPoint point = new SVGOMPoint(dragMoveX, dragMoveY);
Node node = ((Node) evt.getTarget()).getParentNode();
SVGMatrix Drag_M = ((SVGLocatable) node).getScreenCTM();
Drag_M = Drag_M.inverse();
SVGOMPoint dp = (SVGOMPoint) point.matrixTransform(Drag_M);
Node Base =
(Node)ae.getOwnerDocument().getElementById("rateSlideBase");
//.getParentNode(); // .getAttributeNS(null, "y");
SVGLocatable Base_L = (SVGLocatable)Base;
// Base_L.getBBox;
top = Base_L.getScreenCTM().getB();
hgt = Base_L.getScreenCTM().getD();
rad = Base_L.getScreenCTM().getF();
bot = hgt+top;
top = top+(2*rad);
bot = bot-(2*rad);
newY = dp.getY();
if(newY < top) newY = top;
if(newY > bot) newY = bot;
String cy = String.valueOf(newY);
String setCY = String.valueOf(dp.getY());
ae.getOwnerDocument().getElementById("rateButton").setAttributeNS(null,
"cy",setCY);
I've played around with BBox ( have deleted those attempts out of this
version of the code) but am obviously getting lost in trying to determine
how to get the topmost Y and bottom-most Y of the rectangle to test against.
Thanks for any suggestions,
KWL
Re: Limiting Drag
Posted by th...@kodak.com.
Hi K.W.
"K. W. Landry" <kw...@gmail.com> wrote on 12/11/2006 09:51:34 PM:
> What techniques would you use for limiting the drag of an element to
> within the bounds of another element?
> if(grab) {
> // DOMMouseEvent elementEvent = (DOMMouseEvent) event;
> int dragMoveX = dm.getClientX();
> int dragMoveY = dm.getClientY();
> SVGOMPoint point = new SVGOMPoint(dragMoveX, dragMoveY);
Don't do this. Use the SVGSVGElement as a factory for points:
http://xmlgraphics.apache.org/batik/javadoc/org/w3c/dom/svg/SVGSVGElement.html
SVGPoint point = svgDoc.getRootElement().createPoint;
point.setX(dragMoveX);
point.setY(dragMoveY);
> Node node = ((Node) evt.getTarget()).getParentNode();
> SVGMatrix Drag_M = ((SVGLocatable) node).getScreenCTM();
> Drag_M = Drag_M.inverse();
> SVGOMPoint dp = (SVGOMPoint) point.matrixTransform(Drag_M);
This gives you dp in the local coordinate system of 'node'.
I would suggest that you want 'dp' to be in the local coordinate
system of 'Base':
> Node Base =
(Node)ae.getOwnerDocument().getElementById("rateSlideBase");
> SVGLocatable Base_L = (SVGLocatable)Base;
SVGMatrix Drag_M = Base_L.getScreenCTM();
Drag_M = Drag_M.inverse();
SVGPoint dp = point.matrixTransform(Drag_M);
SVGRect bbox = Base_L.getBBox;
// Limit dp's Y to the bbox.
if (dp.getY() < bbox.getY())
dp.setY(bbox.getY());
if (dp.getY() > bbox.getY() + bbox.getHeight())
dp.setY(bbox.getY() + bbox.getHeight());
// Now map dp to the rateButton's coordinate system:
node =
ae.getOwnerDocument().getElementById("rateButton");
SVGLocatable rb = (SVGLocatable)node;
SVGMatrix elemMat = Base_L.getTransformToElement(rb);
dp = dp.matrixTransform(elemMat);
// Set both in case of rotation...
rb.setAttributeNS(null, "cx", ""+dp.getX())
rb.setAttributeNS(null, "cy", ""+dp.getY())
> top = Base_L.getScreenCTM().getB();
> hgt = Base_L.getScreenCTM().getD();
> rad = Base_L.getScreenCTM().getF();
> bot = hgt+top;
> top = top+(2*rad);
> bot = bot-(2*rad);
>
> newY = dp.getY();
> if(newY < top) newY = top;
> if(newY > bot) newY = bot;
> String cy = String.valueOf(newY);
> String setCY = String.valueOf(dp.getY());
> ae.getOwnerDocument().getElementById("rateButton").
> setAttributeNS(null, "cy",setCY);
>
>
> I've played around with BBox ( have deleted those attempts out of
> this version of the code) but am obviously getting lost in trying to
> determine how to get the topmost Y and bottom-most Y of the
> rectangle to test against.
>
> Thanks for any suggestions,
>
> KWL