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
773 stars 99 forks source link

Thank you and a question. #133

Closed g40 closed 1 year ago

g40 commented 1 year ago

This is nifty work, nice stuff. Thank you.

Is it possible to put each of the examples used on https://anseki.github.io/plain-draggable/ into the repo individually? Saves breaking down the page source code,

MTIA

anseki commented 1 year ago

Hi @g40, thank you for the comment. The source code of all examples were already put individually in the HTML code. That is, those are separated based on each example with comments such as ex-040. See the HTML source code.

g40 commented 1 year ago

@anseki Thank you for the prompt response.

I understand your intention. I suspect having all of the examples inline in one page on another site may slow adoption.

I have been going through looking at how to split out into bite sized chunks of markup and code. I'd be happy to provide a PR when I understand things a bit more clearly. But some comments follow:

  1. Given there are no external dependencies, provide the simplest, most minimal example (template) as a starter. 2 The template makes it very easy to see how things work
  2. The template makes experimentation simple. It can be extended incrementally without worrying about another 2000 lines of code.
  3. Having a template makes it simpler to submit an issue or ask questions.
  4. Actually working out the boundaries of each example is a bit tedious. I am doing it now.
  5. There are no surprises like the one below which does reference external sources (ex 40 I believe):
    <script src="js/path-data-polyfill.js"></script>
    <script src="js/bezier.min.js"></script>

Many thanks for listening.

g40 commented 1 year ago

Hello @anseki. Please find below an extracted snippet from one of the examples.

It has a variety of problems out of the box. Apologies for the size of the images but there is a lot to convey.

  1. The markup/code will not load unless the minified plain-draggable.js is used.

image

  1. Using the minified code, there is a problem with mClassList - which is not visible in the top level script

image

  1. This is very frustrating. This is a great library, extremely useful, but adapting code for one's own use case, even the simplest, is proving a challenge.

Thanks again for listening.


<!DOCTYPE html>
<html>
<head>
    <!-- will only load with minified .js file -->
    <script src="plain-draggable.min.js"></script>
    <title>PlainDraggable</title>
</head>
<body>

        <!-- include "ex-060.html" -->
        <!-- ================ ex -->
        <div class="cols2">
            <div class="col">
                <p>Since PlainDraggable only changes the position to be dragged, you can do additional something for the draggable element. For example, add animation effects to it.</p>
            </div>
            <div class="col">

                <div id="ex-060-stage" class="stage-m">
                    <div id="ex-060-port"></div>
                    <div id="ex-060-grid"></div>
                    <div id="ex-060-draggable" class="draggable">Drag This</div>
                </div>

            </div>
        </div>

        <script>
mClassList.ignoreNative = true;

window.addEventListener('load', function() {
  'use strict';

  var target = document.getElementById('ex-060-draggable'),
    bBox = target.getBoundingClientRect(),
    port = document.getElementById('ex-060-port'),
    portPosition = port.getBoundingClientRect(),
    inAnim = false,
    DURATION = 0.2,
    snapped;

  port.style.width = bBox.width + 'px';
  port.style.height = bBox.height + 'px';
  portPosition = {
    left: portPosition.left + window.pageXOffset,
    top: portPosition.top + window.pageYOffset
  };

  function animMode(toOn) {
    if (toOn !== inAnim) {
      inAnim = toOn;
      mClassList(target)[inAnim ? 'add' : 'remove']('ex-060-anim');
    }
  }

  var draggable = new PlainDraggable(target, {
    snap: {x: {step: 40, start: 180}, y: {step: 40}},
    onDrag: function(moveTo) {
      animMode(!!(snapped = moveTo.snapped));
    },
    onDragEnd: function() {
      if (!snapped) {
        animMode(true);
        this.left = portPosition.left;
        this.top = portPosition.top;
      }
    }
  });

  (function(listener) {
    ['transitionend', 'webkitTransitionEnd', 'oTransitionEnd', 'otransitionend'].forEach(function(type) {
      target.addEventListener(type, listener, true);
    });
  })(function(event) {
    if (inAnim && event.target === target && event.elapsedTime >= DURATION) {
      animMode(false);
      draggable.position();
    }
  });

});
</script>
        <!-- ================ /ex -->
        <!-- /include "ex-060.html" -->
</body>
</html>
anseki commented 1 year ago

Sorry, my English is poor. Do you mean that you want to implement a feature like ex-060 for your app? If so, could you explain about the problem and show me your code?

g40 commented 1 year ago

Not a problem. No I am not trying to implement a specific feature yet. I am just looking to run the basic examples.

anseki commented 1 year ago

This document about basic usage may help you: https://anseki.github.io/plain-draggable/#usage For example: https://jsfiddle.net/xte8cvhw/ Note: You might have to click "Run" button to fix the position of the "port" element because this example doesn't consider frames.

g40 commented 1 year ago

Hello @anseki.

So. The problem with copying from the .io site is that there is no easy way to associate the source code with the example of interest. And since the page source is not in your root repository no one can fork and send you pull requests to fix the documentation/examples.

Let me give you a concrete example of both a snippet and an unexpected result. This is based on your suggestion to reuse the code from the .io page. Out of the box that code will not work correctly as the draggable element has the same width as the container and thus cannot be dragged along the X axis.

Thanks for listening!

<!DOCTYPE html>
<html>
<head>
    <script src="plain-draggable.min.js"></script>
    <style>
    body {
        font-size: 100%;
        font-family: Verdana, Arial, Helvetica, sans-serif;
        color: #000000;
        background-color: #FFFFFF;
    }
    </style>
    <title>PlainDraggable</title>
</head>
<body>
    <div id="outer_t" style="background-color: lightblue; width: 400px; height:200px;">
            <div id="draggable_t" style="background-color: white;">Drag this</div>
        </div>

        <div id="outer_l" style="background-color: yellow; width: 400px; height:200px;">
            <div id="draggable_l" style="background-color: white; width:80px;">Drag that</div>
        </div>
        <script>
            // the unexpected
            let target_t = document.getElementById('draggable_t');
            var draggable_t = new PlainDraggable(target_t, { snap: { x: { step: 40, start: 100 }, y: { step: 40 } } });
            draggable_t.containment = document.getElementById('outer_t');
            // and the good stuff
            let target_l = document.getElementById('draggable_l');
            var draggable_1 = new PlainDraggable(target_l, { snap: { x: { step: 40, start: 100 }, y: { step: 40 } } });
            draggable_l.containment = document.getElementById('outer_l');
        </script>
</body>
</html>
anseki commented 1 year ago

Sorry, my English is poor. Do you mean that you want to specify width to the container? When the draggable element has the same width as the container, the moving on X axis is restricted correctly. https://anseki.github.io/plain-draggable/#options-containment Also, we don't need separated files of examples, then you don't have to send PR of course. The code of examples that are shown on the document are basic examples that are able to be copied and used, and the code of examples that are not shown on the document (you can read those on source code) are application cases that should not be copied easily and used.

g40 commented 1 year ago

@anseki Let me close this one. I think we are somewhat at cross-purposes. Not a problem. Thank you.

anseki commented 1 year ago

Thank you :smile: