anseki / plain-draggable

The simple and high performance library to allow HTML/SVG element to be dragged.
https://anseki.github.io/plain-draggable/
MIT License
765 stars 96 forks source link

issue with css zoom property (element and cursor position not match) #1

Closed stmkjp closed 6 years ago

stmkjp commented 6 years ago

Hello, thanks for the great script!

It works without problem when use with normal css zoom (i.e. 100%), but when used with css zoom property different than 1.0, position of target draggable element is not coordinated with mouse(cursor) position.

Could you help on this issue?

anseki commented 6 years ago

Hi @stmkjp, thank you for the comment.

There are two zooms in CSS:

The zoom CSS descriptor specification is in "Working Draft" status. https://drafts.csswg.org/css-device-adapt/#zoom-desc

The zoom CSS property is "Non-Standard", it is supported by Microsoft Internet Explorer. https://msdn.microsoft.com/en-us/library/ms531189(v=vs.85).aspx

Therefore you should not use both the zoom CSS Descriptor and the zoom CSS property. And, PlainDraggable also should not support the zoom CSS property currently. And also, I think that moving the target element in a zoomed-in/out distance (e.g. the element is moved in a distance twice as long as the distance the mouse moved when zoom 2.0; is specified) is correct behavior because this is used to zoom-in/out the view.

anseki commented 6 years ago

Or, if you really want to use the zoom, you can adjust the position in onDrag event handler.

For example:

const elm = document.getElementById('item'),
  zoom = elm.style.zoom || 1, // It maybe has to be changed
  onDrag = newPosition => {
    const rect = this.rect
    newPosition.left = rect.left + (newPosition.left - rect.left) / zoom;
    newPosition.top = rect.top + (newPosition.top - rect.top) / zoom;
  };
stmkjp commented 6 years ago

@anseki , thanks for the quick & detailed reply!

I had to set zoom css property on the parent element(container) for it's WxH should be 768 * 1024 which makes somewhat too long for the small screen- I mean, the container is just a part of a page, not occupying the whole page.

I tried to put the code you suggested in my html, but it seems not working properly. draggable object moves like shivering ( and still not match with cursor), I guess it's competing with your plain-draggable.js for the onDrag event?

anseki commented 6 years ago

I see. I recommend to you again, you should not use the zoom CSS property to support the small screen. As I said, that doesn't work in some web browsers because it is non-standard. Also, that might make more other problems. Irrespective of PlainDraggable, I recommend "Responsive Web Design" (RWD) that is used typically, and it is more easy and simple way. In many cases, the RWD is used to make the web page support the small screen, big screen and more environments.

For example:

/* small-layout */
#container {
  width: 960px;
}

@media only screen and (min-width: 1200px) {
  /* wide-layout */
  #container {
    width: 1024px;
  }
}
stmkjp commented 6 years ago

@anseki , thank you for the advise. I guess I'll have to think of another way instead of zoom property. I don't consider RWD way though, for the absolute coordination of objects in 768x1024 environment is critical. Maybe I should shrink the container size to 1/2 and then double the coordinates and sizes of the objects when it comes to actual presentation (real 768x1024).

Thanks again!

anseki commented 6 years ago

It seems that I made you misunderstand because my English is poor. You can design the 768x1024 view by using RWD, the height also can be specified, not only width. And the RWD is the best way now, to adjust the layout (and style) of a web page.

For example, a small #container element is shown when you access to the page with small screen (or window), and a wide one is shown when you access the page with large screen (or window) (or you resize the window, to be large). All of those adjusting is done automatically.

/* small-layout */
#container {
  width: 960px;
  height: 480px;
}

/* For 1024px width viewport, more width is required because scroll bars may be shown */

@media only screen and (min-width: 1200px) {
  /* wide-layout */
  #container {
    width: 1024px;
    height: 512px;
  }
}
anseki commented 6 years ago

If you don't want to use the RWD for some reason or other, you can choose another way. That is:

  1. For web browsers other than Internet Explorer, you should not use the zoom CSS property that is non-standard.
  2. The RWD is your best bet that is used typically, and that's the most easy and simple way.
  3. But you don't like using the RWD.

Then, you can use SVG to zoom-in/out an element. The SVG is supported by Internet Explorer and others. Therefore the SVG works fine in almost web browsers, also PlainDraggable supports the SVG. For example, see https://anseki.github.io/plain-draggable/ (second example). Move a red vertical slider to zoom in/out a view.

stmkjp commented 6 years ago

@anseki , oh I didn't think of SVG before. I'll look into that, Many many thanks!!

anseki commented 6 years ago

But I recommend this, not SVG. https://github.com/anseki/plain-draggable/issues/1#issuecomment-336631033

Anyway, it seems that this issue was solved, right? And I close this issue.