Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jsPanel not working inside a container which is scaled by css transfrom #46

Closed
akstek opened this issue Jul 31, 2018 · 24 comments
Closed

Comments

@akstek
Copy link

akstek commented Jul 31, 2018

If I create a jsPanel inside a container which has a scale transformation applied and you drag or resize the panel, the position or the size is calculated wrong, because the delta of the mouse movement does not take the applied scale factor into account. Also syncMarging does not work as expected.
Demonstration: https://jsfiddle.net/kh5xj6f9/35/

@Flyer53
Copy link
Owner

Flyer53 commented Jul 31, 2018

@akstek
Hi there ... and thanks for the report.
I have to admit that this is a scenario I never considered. Before I can say anything useful I need to deal with css tranformations a bit ...
I don't even know whether this should be considered a bug or merely a imperfection.

@akstek
Copy link
Author

akstek commented Aug 6, 2018

@Flyer53 Thank you for your fast reply. If you need further information or any other assistence pls let me know,

@Flyer53
Copy link
Owner

Flyer53 commented Aug 7, 2018

@akstek
Thanks for your offer to help :) ... might come back to you ...

I made a little bit of research myself and think it's not just the mouse delta causing this. For positioning, dragging and resizing the scripts needs "true and current" readings of left/top and/or width/height values. But the only way to get those values after a css tranformation seems to be getBoundingClientRect() which returns left, top, right, bottom values relative to left-top of the viewport. Style attributes don't get updated and even getComputedStyle() doesn't return correct values after using transform: scale().

Do I miss something? Do you know another way to get proper values after a css transformation?

@akstek
Copy link
Author

akstek commented Aug 7, 2018

@Flyer53
Our approach is to always use unscaled values (offsetTop/Left/Width/Height) to do the positioning and needed calculation. The browser it self scales down the values when the transform is applied. The only thing where we do take the scale factor into account is when we calculate the delta of the mouse movement. For this I would recommend to calculate the scale factor by getting the scaled width or height by getBoundingClientRect and the unscaled values by offsetWidth/Heigth of the container.
const scaleFactor = container.getBoundingClientRect().width / container.offsetWidth;

@Flyer53
Copy link
Owner

Flyer53 commented Aug 8, 2018

@akstek
Thanks a lot for your infos :)
Before I start making changes concerning this issue I need to deal with this whole topic some more. But I don't have a lot of time during the next weeks, so there won't be a quick fix for this.
However, I hope you can continue to work with jsPanel.

@akstek
Copy link
Author

akstek commented Aug 8, 2018

@Flyer53
Thx for the info. For now we run JS Panel in the body tag and not in the window container of our app, to avoid the quirx. But our app should scale on different devices and is resolution independant, So we are looking forward to see this "enhancement" gets implemented :-)

@akstek
Copy link
Author

akstek commented Aug 23, 2018

@Flyer53
I updated the fiddle. It uses now a patched version (based on 4.1.2) which supports to run panels inside a scaled container. It is not fully implemented, more a proof of cocept. If panels are created in the body they do not take the scalefactor into account. I also did no testing with a grid or containment applied. Both options do not work for me (also the demos in your api docs seem to be broken).
https://jsfiddle.net/kh5xj6f9/77

@Flyer53
Copy link
Owner

Flyer53 commented Sep 17, 2018

Just wanted to take a look at your latest fiddle. It seems the jsPanel script is not loaded.
I get a ReferenceError: jsPanel is not defined

@akstek
Copy link
Author

akstek commented Sep 18, 2018

Sorry for that, but it seems we have a company policy applied that removes public shares from our personal one drive storage periodically. So here is the updated fiddle.
https://jsfiddle.net/kh5xj6f9/78/
Just in case it's still not working I attache the file.
sig-jspanel.zip

@Flyer53
Copy link
Owner

Flyer53 commented Sep 20, 2018

@akstek
Just opened your modified file the first time.
I have yet to see how it works out, but you made some serious work 👍
I appreciate that a lot 😄

@akstek
Copy link
Author

akstek commented Sep 21, 2018

Let me now if you need any assistence

@Flyer53
Copy link
Owner

Flyer53 commented Sep 26, 2018

Spent some time with your modifications:

  • containement works fine for dragging/resizing when container and panel are scaled
  • does not work as perfect when, for whatever reason, only the panel is scaled but not the container (maybe easy to fix with a modification of the scale factor ... didn't check that yet though)
  • does not work when a second transformation, e.g. rotate, is applied. But I don't think it makes a lot of sense to try to make it work with ALL variations ... For me amateur programer it's already hard enough to understand my own code sometimes ;)

Question:
Is there any special reason why you added the code to cache the scale factors? It's not strictly needed to make it work.

Your file modified:
sig-jspanel.zip
I added some code to jsPanel.position() in order to achieve a correct initial positioning within the scaled container. Was not as simple as I thought at first. Just applying the scale factors for left/top didn't do it when the container has borders. Not fully tested yet but looks not bad so far.
Would appriciate if you gave it a try :)

@akstek
Copy link
Author

akstek commented Sep 27, 2018

Thank you! I highly appreciate your hard work. The reason why I cache the scale factors is, that the calculation forces the browser to layout and reflow. So this directly impacts the rendering performance.
See https://gist.github.com/paulirish/5d52fb081b3570c81e3a
As our application needs to run on low end industrial hardware we do this with most of the values to get a acceptable frame rate. I will check your new version and leave the feedback here.

@Flyer53
Copy link
Owner

Flyer53 commented Sep 27, 2018

... but in jsPanel.dragit() you put const scaleFactor = .... in the function dragElmt() which runs within the mousemove handler. I would move it up to the mousedown handler as you did it in jsPanel.resizeit(). Put in the mousedown handler the scale factor is only calculated once per dragstart/resizestart and once it has to be calculated anyhow.

My current development file (don't mind the version number) that does without caching and where the scale factor calculation is done in the mousedown handlers:
jspanel.zip

I even think of moving the scale factor calculation to a point just after the panel was inserted to its container. So it runs only once during the lifetime of the panel and you would only have to do a recalc only if the scaling changes ...

Thanks for the link ... very interesting :)

@Flyer53
Copy link
Owner

Flyer53 commented Sep 27, 2018

Options position, dragit and resizeit seem to work fine with the test file including optional parameters like containment, grid, snap, minWidth, maxWidth etc.
I'm sure there are things that don't work but it looks pretty good so far.

@akstek
Copy link
Author

akstek commented Sep 28, 2018

Cool, i am a bit busy right now, but i will test your code during the weekend.

@akstek
Copy link
Author

akstek commented Oct 8, 2018

OK, I found some time and tested your version in our scaled enviroment and everthing seems to work as it shoud (at least for the features we use). Good to see that the getscalectorfactor() method is now a method of the panel itself, was easy to override and integrate with our central variable cache system. Good work @Flyer53 !

@Flyer53
Copy link
Owner

Flyer53 commented Oct 9, 2018

Sounds good to me :)
So it will be part of the next release ...
I currently work on an optional feature to maintain aspect ratio when resizing a panel with mouse.

@akstek
Copy link
Author

akstek commented Oct 10, 2018

Sounds cool. Looking forward to get the hands on the new release!

@Flyer53
Copy link
Owner

Flyer53 commented Oct 19, 2018

If you want to take a look at the latest 4.3.0-alpha just go to https://alpha.jspanel.de/index.html
The docs there are updated as well ...

Changelog:

  • added event jspanelcloseduser which is fired when a panel is closed using the header control
  • added panel method .overlaps()
  • added parameter aspectRatio to option resizeit
  • updated panel method .close() - it now has a return value depending on whether the panel was closed successfully or not
  • option.container default value is changed to 'window'. This might need a change in existing code when container: doccument.body is used even though this was the default previously
  • option.maximizedMargin now accepts a function as value
  • options position, dragit and resizeit now correctly position, drag and resize panels appended to a container using css transform: scale() if both container and panel are scaled
  • bugfix in global color methods
  • tooltip extension:
    • added method jsPanel.tooltip.reposition() to reposition existing tooltips
    • added parameter autoshow for tooltips
    • added support for tooltips positioned relative to another element than target
    • improved tooltip connectors
    • a few bugfixes in the tooltip extension
    • tooltip extension will load a MouseEvent() polyfill for IE11

Download latest alpha
I think it works quite well and is ready for release unless I find a bug in some testing I still have to do.

@akstek
Copy link
Author

akstek commented Oct 19, 2018

Thank you @Flyer53! Currently I am on vacation but I will take a look after my return next week!

@Flyer53
Copy link
Owner

Flyer53 commented Oct 19, 2018

@akstek Enjoy the days off 😃

@akstek
Copy link
Author

akstek commented Oct 28, 2018

@Flyer53 We tested your new alpha and it works fine in our enviroment

@Flyer53
Copy link
Owner

Flyer53 commented Nov 10, 2018

Issue solved with release of v4.3.0

@Flyer53 Flyer53 closed this as completed Nov 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants