I have a simple ellipse element:
<span style={{
width: /*someWith*/,
height: /*someHeight*/,
borderRadius: "50%"
}}/>
and, using getBoundingClientRect() I'm getting its bounds (shown in blue).
There is nothing wrong about it as long as I don't rotate it via transform: rotate:
now, getBoundingClientRect() shows ellipse's "wrong" bounds, showing not the bounds of the rotated ellipse, but it's span element's.
Is there any way to get the actual bounds of the ellipse?
Found a npm package which solved my problem. The only "downside" is that it requires using SVGs rather than HTML element.
npm: https://www.npmjs.com/package/svg-boundings
Related
Imagine simple ms paint application written in react and you are trying to implement rectangle drawing.
It's something I currently have but if I drag my mouse over rectangle I am currently drawing it starts to flicker because it fires event with position relative to rectangle and not drawing area (in my case div) depending over which element (drawing area/rectangle) my mouse is currently over.
I have extracted the problem into this simple app https://codesandbox.io/s/6yxx4y9lz3
I feel like I could solve the problem with hacky calculations but I would appreciate some elegant solution/advice as this functionality is going to be base stone of bigger application.
The actual problem is that the blue box you are drawing eats up the mouse events.
You can just add pointer-events:none to it so that it is ignored. (pointerEvents when used from inside React)
style={{
width: item.w,
height: item.h,
top: item.y,
left: item.x,
border: "solid blue",
position: "absolute",
pointerEvents:"none"
}}
Updated demo at https://codesandbox.io/s/l7ll3wy5pl
I'm very new to both JointJS and SVG, so I am having a hard time interpreting some of the documentation for JointJS. I am trying to get randomly searched images to display in a circle for this project, in a graph that uses JointJS to display and link the images with arrows. I am convinced this shouldn't be as hard as I am making it, but I have spent hours going through the documentation, so I need help. From what I can tell, joint.shapes.standard.Circle elements cannot take an image as a background or fill. I would be really happy to use the .BorderedImage elements, but when I change the radius to make them a circle, the border changes without cropping the image. I also tried to use the .Image element and change the radius, and again the image didn't change. I am under the impression that I could add a clipPath definition to an .Image or .BorderedImage to force a circle, but I am not familiar enough with the syntax to be clear on where to do that, and none of the examples I have found on stackoverflow have given me enough information to do that. I tried using the .define method, and kept getting "cannot read property define of undefined" errors, so I know I wasn't using that right.
Here's what I have in the way of error-free code (rounded border that doesn't crop):
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: document.getElementById('myholder'),
model: graph,
width: 600,
height: 600,
gridSize: 1,
// makes code not draggable
interactive: { elementMove: false, arrowheadMove: false }
});
var borderedImage = new joint.shapes.standard.BorderedImage();
borderedImage.resize(100, 100);
borderedImage.position(100, 100);
borderedImage.attr('root/title', 'joint.shapes.standard.BoarderedImage');
borderedImage.attr('label/text', 'Monster\nImage');
borderedImage.attr('border/rx', "50%");
borderedImage.attr('image/xlinkHref', './assets/images/monster.svg');
borderedImage.addTo(graph);
The code I tried for .define looked like:
joint.shapes.Element.define('standard.BorderedImage', {
attrs: {
body: {
rx: "50%"
}
}
})
Some of the resources I have looked at and couldn't figure out how to use correctly are:
Putting multiple films in a circle in Raphael/Joint.js
How to set background image for a rectangle in JointJs?
Using predefined SVG file for creating a custom JointJS shape with ports
https://resources.jointjs.com/docs/jointjs/v2.1/joint.html#dia.Paper.prototype.properties
I want to have a shape inside of a node, which would be partly out of the boundaries of the node. Meaning, -10px top and left of the parent element.
Right now I have rectangle and a circle inside of a node and it looks like this:
As you can see, the link does not connect properly, since the size of the node has expanded. I would like the circle to be, using css terms, to be absolutely positioned, in other words, I don't want it to affect the node sizing the node (which is, obviously, invisible in this sample).
I have tried the following solutions:
Setting width and height to the node. Then it crops the circle, because it is out of the boundaries.
Using the fromSpot and toSpot properties in the node to connect the link to the center of the node. Apparently they are overridden by the layout, and I can't figure out how to disable isLayoutPositioned
Using adornments, but I don't understand at all how am I supposed to use them.
Searching if I could somehow set the overflow of the element visible, or to affect somehow the boundaries, or something like that, but have not found anything which would work for me.
What would be the proper solution here?
Make your Node a "Spot" Panel, make the "main" element of your node the "port" by assigning it a GraphObject.portId, and position the red circle relative to the "main" element by setting its GraphObject.alignment property, in this case to go.Spot.TopLeft. I'm also guessing that assigning the Node.locationObjectName is what you will want.
myDiagram.nodeTemplate =
$(go.Node, "Spot",
{ locationSpot: go.Spot.Center, locationObjectName: "BODY" },
$(go.Shape,
{ name: "BODY", width: 50, height: 50,
fill: "lightgreen", strokeWidth: 0,
portId: "" }),
$(go.Shape, "Circle",
{ alignment: go.Spot.TopLeft, width: 20, height: 20,
fill: "transparent", stroke: "red" })
);
Please read more at http://gojs.net/latest/intro/nodes.html. I recommend reading not only the Getting Started page, http://gojs.net/learn, but also all of the Introduction pages, http://gojs.net/intro, that apply to the kind of app you want to create.
In particular, these should be useful:
http://gojs.net/latest/intro/panels.html
http://gojs.net/latest/intro/tablePanels.html
http://gojs.net/latest/intro/ports.html
http://gojs.net/latest/intro/nodes.html
I am using the FreeTransform plugin for moving and scaling objects.
I want to limit this moving and scaling to the size of another rect which contains this object. How can I achieve this?
I have provided an example of problem on JSFiddle. (I want the red rect to stay inside the other rect.)
Thank you.
The FreeTransform plugin provides the option to set a boundary:
boundary: { x: x-pos, y: y-post, width: i, height: i},
see the documentation
https://github.com/ElbertF/Raphael.FreeTransform/
I just started with fabric.js and I have a (probably beginner) error:
I am using fabric with jquery with the following code:
$(document).ready(function () {
canvas = new fabric.StaticCanvas('scroller');
canvas.add(
new fabric.Rect({ top: 0, left: 0, width: 140, height: 100, fill: '#f55' })
);
});
This code should draw a 140x100 Rectangle on the canvas.
Sadly, only a quarter of the Rectangle appears.
If I change the top and left values to higher numbers, more of the Rectangle appears on the canvas.
So it seems, that the canvas origin is not at 0/0, but at sth. higher.
Does someone know how to fix this or what I am doing wrong?
Thanks in advance,
McFarlane
Here is a jsfiddle link with some examples http://jsfiddle.net/pukster/sdQ7U/2/
My guess is that fabric.js calculates everything from the origin (middle point) since it is drawing exactly one quarter of a rectangle even with a canvas 10 times the size of the rectangle. My guess is that top and left actually refer to the origin and not the top and left sides of the imaginary bounding box. Trouble is there is very little documentation on fabricjs. Is there any reason you are using fabricjs and not easeljs
EDIT Here's the same fiddle but with squares instead of rectangles (it is more clear) http://jsfiddle.net/pukster/sdQ7U/3/
EDIT OK I am now almost absolutely certain that fabric.js uses the center as the top/left. I ripped their example off of their site and overlayed it with the transparent couterpart to those shapes had they been coded in pure canvas http://jsfiddle.net/pukster/uathZ/2/ (blue border is the limit of the canvas element).
What you see is that the boxes are exactly offset by half but the circle (I only drew a semi circle otherwise it would not have been discernable) is perfectly overlapped. This is b/c in HTML Canvas, the circle coordinates (x,y) refer to the origin and not the top left. I did not bother with the triangle b/c my trigonometry is a bit rusty. I personally think it's misleading to use the terms top and left, when x and y would have been more representative and shorter.
Yes, this is highly unexpected and even more undocumented.
Workaround:
Set
originX: "left"
originY: "top"
for each created object.
edit: or use kangax simpler solution in the comment below.
I want to comment but lack the reputation to do so. So anyway, here is what happens when I do the following:
fabric.Object.prototype.originX = "left";
fabric.Object.prototype.originY = "top";
The shape gets rendered fine but when I select it for resizing or moving, it gets offset to a different location. The best approach seems to be to set the coordinates for every object separately using the set() method.