I'm developing an app using jsPlumb. Currently, if I create a shape, it puts the shape in the top left corner of the canvas. And If I connect from source to target point, it is working.
Now, I want to create the shape on the position where I right clicked and connect from source to target. I'm able to create the shape in the position where i right clicked.
But, if I drag from source to target, the source anchor is not starting from the source. Instead, it starts from the top left corner. In the screenshot below, I want to drag from 'Project' to 'No status' shape.
One more thing is, if I drag the 'Project' shape, endpoint is starting from source correctly.
I have figured the problem. Earlier, ,the if block (1) in the code was below the code (2). That's why even thought the shape moved to the new location, the starting location of the anchor didnt move. As soon as I move the if block(1) above (2), jsPlumb understands the shape's location as well as the anchor's starting point location.
So, if you are moving the shape, you should do it before you tell the shapes location to Jsplumb.
if (!!shape.location) { ------------------------------------> 1)
domEl.style.left = shape.location.left + 'px';
domEl.style.top = shape.location.top + 'px';
}
this.jsPlumbInstance.draggable(domEl, {
// to contain the shape within the canvas
// containment: true
});
this.jsPlumbInstance.makeSource(domEl, { ----------------------2)
filter: '.cp',
anchor: ['AutoDefault'],
connectorStyle: {
stroke: '#181919',
strokeWidth: 2,
outlineStroke: 'transparent',
outlineWidth: 4
}
});
Related
I am confused with gsap's Flip.fit moving to coordinates.
I have a game board with 182 tiles and 182 playing tiles.
The goal
When the user clicks the bag, a random playing tile is selected and is "supposed" to move over the tile on the board.
If you change
Flip.fit(PTILE[tileArray], TILE[tileArray], {duration: 1 , scale: true});
when changing { duration: 0, ... } the move works as expected, however no animation. When duration is above zero, the final location is very random.
codepen
I'm not sure how the duration affects the final position, however, I found a way to get the positions right. That is reset the transform of your PTILE before telling GSAP to do the Flip animation.
// reset transform value
gsap.set(PTILE[tileArray], { transform: "" });
// animate with new transform value
Flip.fit(PTILE[tileArray], TILE[tileArray], {
duration: 1,
scale: true
});
My reason is that PTITLE and TITLE are placed in different <g> tags which means their transform systems are inconsistent. Plus, Flip.fit() will act like gsap.to() with new TITLE position is the to object, GSAP will try to calculate the from object from your original transforms which are already set in the SVG as transform:matrix(). This process, somehow, is messing up. So what I did is give GSAP an exact transform value for the from object, which is empty.
Ok, I found out that Inkscape stores the SVG with inline transforms that threw the animation off. I tried saving in plain or optimised, but still had no luck.
So there are two solutions.
Use SVGOMG an online SVG cleaner.
Use Affinity Designer application which can export and flatten transforms.
The key to rule out other factors is to use relative coordinates and flatten transforms.
I have included a screenshot of Affinity exporting options.
Affinity Export screenshot
Here i'm working on moving images dynamically with random x and y, inside a zooming & dragging SVG. Now I want to append dashed path following these moving images. Similar to the image below:
I found a D3 example, where a dotted path following the mouse. I tried the same code to create a path for one image for the time being. Instead of mouse X & Y coordinates, i used the random X and Y values of moving image.
var pt = [];
pt.push(randomX);pt.push(randomY);
tick(pt);
function tick(pt) {
// push a new data point onto the back
ptdata.push(pt);
// Redraw the path:
path.attr("d", function(d) { return line(d);})
// If more than 100 points, drop the old data pt off the front
if (ptdata.length > npoints) {
ptdata.shift();
}
}
But the result was thick lines displayed in a disorder manner on top of the background image (Grass Texture image). Please check out the FIDDLE and please suggest a way to create dashed line path for the moving images.
First problem: "result was thick lines displayed"
Reason you need to give fill none
.line {
fill: none;
stroke: #000;
stroke-width: 1.5px;
stroke-dasharray: 2,5;
}
You had not given the style for the line.
Second problem: disorder manner on top of the background image
The reason is you running the time interval in a span of 50 millisecond,
but transition to move the image from point 1 to point 2 is 6000 millisecond thus the images are not able to move to its new calculated random position.
In short the anomaly is because you creating new points in 50 milliseconds but want to transition into the new place in 6000 milliseconds, so the points are not able to move to its position.
I have corrected the time interval to create points to 1 second.
Also i have changed the transition time of image to move in 100 milliseconds.
Working code here
An SKSpriteNode, named “leaf” is added as a child to another SKSpriteNode, named “allObjects”.
allObjects is set to be the same width and height as the SKView.
I drag the leaf to a location on allObjects and click a distinctive part of its tip and using println get the following in the console.
touchBegan, touch.locationInNode(allObjects): (621.5, 156.75)
touchesEnded, touch.locationInNode: (621.5, 156.75)
touchesEnded, Leaf location: (695.375, 83.25)
touchesEnded, nodeAtPoint(location).name: Optional("leaf")
So far, so good. I can drag the leaf as much as I like at this point with no problem. The important part to note is that the nodeAtPoint is, as expected, ‘leaf’.
However, if I then rotate allObjects, like this:
var rotate = SKAction()
rotate = SKAction.rotateByAngle(0.4, duration: 0)
allObjects.runAction(rotate)
… And then click in the same location on the leaf (visually in IOS Simulator), I get the following in the console. I’m confused as to why I have rotated allObjects and clicked in the same location (and get the same co-ordinates) I am no longer selecting the leaf but missing it by a wide margin (nodeAtPoint shows I am hitting the background).
touchBegan, touch.locationInNode(allObjects): (620.813842773438,
156.470306396484)
touchesEnded, touch.locationInNode: (620.813842773438, 156.470306396484)
touchesEnded, Leaf location: (695.375, 83.25)
touchesEnded, nodeAtPoint(location).name: Optional("allObjects")
Can anyone help?
The node and coordinates used in the locationInNode and nodeAtPoint need to be consistent. In this case, the point returned by locationInNode is in allObjects coordinates while the nodeAtPoint call (i.e., self.nodeAtPoint) requires a point in scene coordinates. To resolve this, you can either replace
nodeAtPoint(location)
with
allObjects.nodeAtPoint(location)
or replace
let location = touch.locationInNode(allObjects)
with this
let location = touch.locationInNode(self)
I am using FabricJS to create an application. I am finding that scrolling a parent div/container offsets the selectable area of an object to the right in direct relation to amount scrolled.
So, if I have a canvas that is 1200x600 and a container div that is 600x600 and I add a rect to that canvas at 400, 120; when I scroll 200px, I can't click on the rect to select it. Rather, I have to move my mouse to 600, 120 (empty space) to get the cross bar and select the rect.
Not sure if this is known, or has a work around - but I would appreciate any help possible.
You'll have to modify FabricJs code to make it work.
The problem is in the getPointer function, if you search for it in all.js you'll notice the comment "this method needs fixing" from kangax.
A workaround can be substituting this function with
function getPointer(event) {
// TODO (kangax): this method needs fixing
return { x: pointerX(event) + document.getElementById("container").scrollLeft, y: pointerY(event) + document.getElementById("container").scrollTop };
}
where "container" is the wrapper div of you canvas. It's not nice, since you have to put the exact id, but it works.
Hope this helps.
I use Raphael JS to create an SVG-map with area's and textlabels. I want the area to highlight when you move the mouse over it.
I have this working now, but when I move the mouse over the label (in the center of the area) the mouseout-event for that area is triggered, so the area is unhighlighted again.
Is there any way to prevent this from happening, or a workaround ?
Create a rect with opacity set to 0 over the text and attach the event handlers on that rect. You can calculate the dimensions of the rect using getBBox() of the text.
Creating a set via Paper#set was the approach that worked for me. e.g.:
var st = paper.set();
st.push.apply(st, vectors); // `vectors`: my array of "hoverable" vectors
st.push(text); // `text`: my text vector for `vectors`
st.hover(function () {
text.show();
}, function () {
text.hide();
});