Closed manojdcoder closed 5 years ago
Hi @manojdcoder, thank you for your comment.
The lines are added to <body>
element, not window.
To allow definite lines drawing and positioning accurately, those should be positioned based on document. And those should avoid being affected by other elements or something.
The option that changes the structure makes many problems.
Could you explain your case (e.g. with image)? Then, I might be able to help you.
Or, you can move the element to another element from <body>
if you really want it. However it is not supported.
Thanks for the quick response @anseki
I have a tab based application, the tabs are fixed at top - Screenshot 01
The content inside tab will be scrollable, so while scrolling the lines are shown above tab headers & menu as it's drawn on document - Screenshot 02
Any thoughts how this issue can be resolved?
The most easy way to solve the issue is the using <iframe>
element for the scrollable area.
The <iframe>
element has own document, therefore the lines are added to the document of <iframe>
element.
The application is huge and built using ExtJS, I doubt about separating this one tab content & all it's functionality into separate application (then only I may able to load it into iframe
).
Is there any other solution? How hard it will be to move the lines from body to particular div, I tried it once but it completely broke the positioning.
I see.
You can move the SVG element to another element from <body>
if you really want it.
For example:
document.getElementById('container').appendChild(document.querySelector('.leader-line'));
Note that it is not supported.
@anseki Doing so collapses the layout, I see you have already mentioned it's not supported.
Do you have an estimate to implement the support for setting custom parent element while creating line, we can work it out if that's within my budget.
As I said, that option that changes the structure makes many problems.
Why you can work it out? That is, what's different about the appendChild
method and the option that changes container element?
Using appendChild
doesn't position the lines properly.
It turns out the lines were not positioned properly because my container element has a fixed space left at top for headers / menu bar. If I remove that, the line is positioned properly. May be I will have to adjust the SVG's top position accordingly once it's rendered.
Sorry, my English is poor.
I mean, what's different about the using appendChild
method and the option to change container element? I couldn't understand why you can solve the issue by the option and not using appendChild
method.
Yes, I can solve it with appendChild
.
But the only problem is that the top position of the SVG element is incorrect, that is because the container element has a fixed space left at the top, something like (top: 140px
). If I reduce this space from SVG's top position, then it looks good.
Why the position problem is solved by the option? That is, what's different about the appendChild
method and the option that changes container element?
You said that the issue is solved by the option but I don't think so because the position issue is caused by your style definitions.
To avoid being affected by something (e.g. your style definitions), the lines should be positioned based on document. (See https://github.com/anseki/leader-line/issues/54#issuecomment-498088482)
In other words, if you understand your page (or app) (e.g. style definitions) and you can adjust those (e.g. position) as necessary, you can move the lines to another element that you want. That is, if you can't adjust that, you should not move the lines regardless of the ways (using appendChild
method or the option to change the container). The results are the same.
Another way, you can use clip (mask) if you understand SVG. For example: https://jsfiddle.net/heuj7mso/
I get your point, thanks for the fiddle. I will debug further with these inputs and update here.
Do you mean that the example did not work? Please tell me that problem, then I will find the bug which makes the problem, and I debug that.
Sorry I meant that example seems nice and might work. I will give it a go, in case if it fails, I will write a sample fiddle for you to take a look at the issue.
I see. I hope that the example helps you. :smile:
If it's not too much, may I ask you to update the example with multiple lines, at least with two. There should be one clip path for each line?
Are there multiple lines in one scrollable frame?
Yes, it's like a flow diagram so there will be multiple lines connecting multiple points within the scrollable frame.
A shape of the clip can be shared if there is one scrollable frame. And reference is required to separate the position of each line. https://jsfiddle.net/z5qw7a91/ Also, this example doesn't use Screen-CTM.
FYI, this is an example for the appendChild
method that I suggested before.
https://jsfiddle.net/op2gnk0t/
appendChild
seems to be the perfect solution except when I the start / end element is moved post creation of the line and line.position()
is called.
In my application, user will be able to drag and move the start / end elements anywhere within the scrollable region. As per docs, I used line.position()
but that doesn't seem to work as expected.
In order to demonstrate the issue, I have updated the fiddle - https://jsfiddle.net/cvyu0e42/
Thank you for your continuous support and patience!
Unfortunately your code didn't work.
Maybe you wanted to move the element to top: 55px
after 1 second, right?
You have to specify '55px'
(not 55
) for style.top
property.
https://jsfiddle.net/9d3hoyfL/
It was not only top, but also scrollTo
. line.position()
doesn't position properly when the document is scrolled.
The position
method worked correctly.
You should solve that when you understand why the wrapper is required. (See: https://github.com/anseki/leader-line/issues/54#issuecomment-498088482)
The example code does not consider that the position is changed.
You have to only update the position of the wrapper also when the position of the line is updated.
https://jsfiddle.net/1Lanrmct/
(The style.top
is not required because it is moved by wrapper only.)
Note that this fixPosition
function updates the transform
property twice per every calling.
If you want performance for your app, you'd better save current position to check new position.
Thanks, updating the position of wrapper solved the issue.
I'm glad if I could help you. :smile: FYI, this is an example for considering performance that I said. https://jsfiddle.net/d8ehp1qz/
@anseki I'm applying some scale on the parent div to simulate zoom in / out in which case I'm unable to apply the right transformation on the wrapper div. I have tried several options so far, nothing worked out. Do you have any thoughts?
That is very simple.
Maybe you are misunderstanding the transform
. That affects an element's appearance, and that never changes the element itself.
See: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function
Therefore, the element's moving also be affected.
For example, when you specify transform: scale(1.5)
, an element that was moved 10 pixels is shown as moving 15 pixels in the screen. If you want to move the element 10 pixels in the screen (i.e. scaled distance), you have to specify 10 / 1.5
pixels. Or you can move that before it is scaled.
For example: https://jsfiddle.net/quLx6p37/
No reply came. :cry: However that should have already solved.
Sorry, I couldn't get back sooner as I was given other priority items.
I really appreciate your support here, the above solution works but it's very laggy did not exactly suit my requirements.
User will be able to drag and move the start and end elements on the screen, when they do the position should be recalculated. The given solution requires resetting transform every time which makes the UI very slow and the line path is not accurate sometimes.
Is there any other workaround you could think of which may not require resetting transform (zoom) on parent element?
Yes, of course the resetting the transform
is not required as I said.
Sorry, I tried that already (commented the code for resetting transform on frame
) but lines seems not positioned properly.
Of course the lines are not positioned properly if you comment out the code because the second way was designed for positioning without scaling. Maybe you are misunderstanding the two ways I indicated. See again: https://github.com/anseki/leader-line/issues/54#issuecomment-504363557
BTW, perhaps, did you call the fixPosition
function frequently when the user drags an element?
If so, is that really required?
That is laggy naturally if you call the fixPosition
function wastefully.
I will try to apply the math (distance / scale). And yes I have to call fixPosition as long user drags the start / end point in order to keep the line moving along.
I don't know why you call the fixPosition
function when the user drags an element, anyway that should be solved if you remove the resetting the transform
.
As I already mentioned, the lines should move along with the start / end point as user drag it, so I have to call fixPosition
on every move to make the lines follow the moving points.
It may take a while for me to work on this transform, I will update you once I do. Thanks for the support.
I mean, I don't know why you call the fixPosition
function that fixes the wrapper and resets the transform
. I don't know whether that is required for the dragging or not.
Anyway that has no problem maybe even if that is called because that is replaced for the scaling.
hello @anseki and @manojdcoder i was also facing the same issue of scrolling and i have solved it using appendTo method of jquery, i know whenever we use this method line position collapsed from original position but when i have used
svg.leader-line {
position: fixed
},
it solved my issue, may be it can help anyone using that library, and i also want to thank @anseki for that library.
Hi @logicalravii, thank you for your comment. Do you mean that a problem was solved by adding that CSS declaration to the example? And what is the problem in your case? That is, is there a problem in the example? In other words, do you mean that this issue is not solved by the solution I proposed? If so, could you show me an example in https://jsfiddle.net/ ?
@anseki I was able to solve the improper positioning when a scale is applied on parent div, with the solution you had pointed out.
Yet, I'm back with another issue due to this approach - appending SVG to specific div. Unless .remove()
is called, there is disconnected element exception thrown upon resizing window. If I do call remove, then there it throws exception too as the SVG is moved to a div but the remove method tries to remove it from document. Since the variable (insProps) that holds the active lines are encapsulated, it seems impossible to handle this situation without editing the library itself - may be use,
props.svg.parentNde.removeChild(props.svg);
instead of
props.baseWindow.document.body.removeChild(props.svg);
Do you have any other suggestion?
Hi @manojdcoder,
So, your code doesn't work. What is props
? Also parentNde
.
Could you show me an example in https://jsfiddle.net/ ?
@anseki sorry for late response, The issue was whenever we place lines inside the particular div, the position of lines collapse and set on random location. And when changed the css of lines as I have described above, it fixed now lines stick to where they should be, and I can't replicate it on jsfiddle because of the complexity, thanks.
Hi @logicalravii, thank you for the reply. I don't recommend your solution using CSS because that should make other problems. I recommend the solution I proposed.
@anseki I was referring to this line of code.
Do you mean that the parentNde
is written in the source code?
Yes, remove()
method tries to remove the line from document but we removed from document and inserted it into a div to solve the other issue. I may want to remove one specific line form a number of lines drawn on interface. So appending the line before remove may not work as there is no way to select identify SVG of specific line.
Is it possible to configure the parent container (which is window by default)? Only portions of my screen is scrollable, so the arrows overlap with main content when the start / end point is scrolled behind the main content.
Thanks for the wonderful library!