如何查找图片的原始位置?

时间:2015-06-24 22:52:08

标签: javascript interact.js

我正在使用interact.js库进行拖放功能。我使用原始图像而不是div作为我的可拖动对象,这似乎工作正常:

<img id="drag4" src="images/SVG/ksTire.svg" class="draggable js-drag" style="width:85px">

我无法弄清楚如何在拖动开始之前将图像返回到其原始起点。我需要将原始坐标存储在js变量中,并根据某些事件将图像返回到其确切的原始起始位置。我在事件上尝试了各种x / y坐标,并尝试了getElementById,没有运气。每当我尝试将图像返回到原始位置时,有些方法会在第一次将其恢复原状,但是当我再次开始拖动它时,它会在一个陌生的地方离开,而不是在鼠标指针下面。

有人可以提供一些示例代码,说明如何不断将可拖动对象捕捉回其初始位置吗?我已经在代码中找到了调用它的位置,我需要的是如何将图像恢复到正确的位置,然后在发生后继续正常运行。

注意:interact.js不是基于jquery构建的,所以在这种特殊情况下我更喜欢非jquery解决方案。

以下是我的dropzone.js的全部内容,大多数相关内容都与此问题相关:

(function(interact) {

    'use strict';

    var transformProp;
    var startPos = null;
    var startX = 0;
    var startY = 0;
    var validDrop = false;

    interact.maxInteractions(Infinity);

    // setup draggable elements.


    /* block below was copied from https://github.com/taye/interact.js/issues/79 -- try to get this working */

    // setup drop areas.

    setupDropzone('#drop1', '#drag1, #drag2, #drag4');
    setupDropzone('#drop2', '#drag4');
    setupDropzone('#drop4', '#drag4');
    setupDropzone('#drop5', '#drag1, #drag2, #drag4');
    setupDropzone('#drop6', '#drag3');
    setupDropzone('#drop7', '#drag1');


    /* SNAP code was copied from http://kundprojekt.soonce.com/lintex/zonbuilder/ and https://github.com/taye/interact.js/issues/79 -- try to get this working */

    // dropzone #1 accepts draggable #1
    //setupDropzone('#drop1', '#drag1');
    // dropzone #2 accepts draggable #1 and #2
    //setupDropzone('#drop2', '#drag1, #drag2');
    // every dropzone accepts draggable #3
    //setupDropzone('.js-drop', '#drag3');

    /**
     * Setup a given element as a dropzone.
     *
     * @param {HTMLElement|String} el
     * @param {String} accept
     */
    function setupDropzone(el, accept) {
        interact(el)
            .dropzone({
                accept: accept,
                ondropactivate: function(event) {
                    addClass(event.relatedTarget, '-drop-possible');
                },
                ondropdeactivate: function(event) {
                    removeClass(event.relatedTarget, '-drop-possible');
                }
            })
            .snap({
                mode: 'anchor',
                anchors: [],
                range: Infinity,
                elementOrigin: {
                    x: 0.5,
                    y: 0.5
                },
                endOnly: true
            })
            .on('dropactivate', function(event) {
                var active = event.target.getAttribute('active') | 0;

                // change style if it was previously not active
                if (active === 0) {
                    addClass(event.target, '-drop-possible');
                    //event.target.textContent = 'Drop me here!';
                }

                event.target.setAttribute('active', active + 1);
            })
            .on('dropdeactivate', function(event) { // this fires after each drop, whether a drop into a valid drop zone occurs or not
                var active = event.target.getAttribute('active') | 0;

                // change style if it was previously active
                // but will no longer be active
                if (active === 1) {
                    removeClass(event.target, '-drop-possible');
                    //event.target.textContent = 'Dropzone';
                }

                event.target.setAttribute('active', active - 1);

                if (!validDrop) {
                    //document.getElementById("drag4").style.position = 'absolute';
                    //document.getElementById("drag4").style.left = startX + "px";
                    //document.getElementById("drag4").style.top = startY + "px";
                }

            })

        .on('dragstart', function(event) {
            // snap to the start position

            if (!startPos) {
                var rect = interact.getElementRect(event.target);

                // record center point when starting the very first a drag
                startPos = {
                    x: rect.left + rect.width / 2,
                    y: rect.top + rect.height / 2
                }
            }
            event.interactable.snap({
                anchors: [startPos]
            });
        })
        .on('dragenter', function(event) {
                addClass(event.target, '-drop-over');


                var dropRect = interact.getElementRect(event.target),
                    dropCenter = {
                        x: dropRect.left + dropRect.width / 2,
                        y: dropRect.top + dropRect.height / 2
                    };

                event.draggable.snap({
                    anchors: [dropCenter]
                });


                //event.relatedTarget.textContent = 'I\'m in';
            })
            .on('dragleave', function(event) {
                removeClass(event.target, '-drop-over');

                event.draggable.snap(false);

                // when leaving a dropzone, snap to the start position
                event.draggable.snap({
                    anchors: [startPos]
                });

                var svgFilename = getSVGFilename(event.relatedTarget.src);

                if (document.getElementById("message").innerHTML) {
                    document.getElementById("message").innerHTML = document.getElementById("message").innerHTML.replace(svgFilename + "<br>", "");
                }

                //event.relatedTarget.textContent = 'Drag me…';
            })
            .on('drop', function(event) { // this only fires when an object is dropped into a valid drop zone for that object
                validDrop = true;
                removeClass(event.target, '-drop-over');
                var svgFilename = getSVGFilename(event.relatedTarget.src);
                document.getElementById("message").innerHTML += svgFilename + "<br>";

                //event.relatedTarget.textContent = 'Dropped';
            });
    }

    function getAbsolutePosition(el) {
        var el2 = el;
        var curtop = 0;
        var curleft = 0;
        if (document.getElementById || document.all) {
            do {
                curleft += el.offsetLeft - el.scrollLeft;
                curtop += el.offsetTop - el.scrollTop;
                el = el.offsetParent;
                el2 = el2.parentNode;
                while (el2 != el) {
                    curleft -= el2.scrollLeft;
                    curtop -= el2.scrollTop;
                    el2 = el2.parentNode;
                }
            } while (el.offsetParent);

        } else if (document.layers) {
            curtop += el.y;
            curleft += el.x;
        }
        return [curleft, curtop];
    };

    function getSVGFilename(url) {
        if (url.indexOf("/") > -1)
            return url.substr(url.lastIndexOf('/') + 1);
        else
            return "";
    }

    function addClass(element, className) {
        if (element.classList) {
            return element.classList.add(className);
        } else {
            element.className += ' ' + className;
        }
    }

    function removeClass(element, className) {
        if (element.classList) {
            return element.classList.remove(className);
        } else {
            element.className = element.className.replace(new RegExp(className + ' *', 'g'), '');
        }
    }

    interact('.js-drag')
        .draggable({
            max: Infinity
        })
        .on('dragstart', function(event) {
            validDrop = false;

            event.interaction.x = parseInt(event.target.getAttribute('data-x'), 10) || 0;
            event.interaction.y = parseInt(event.target.getAttribute('data-y'), 10) || 0;

            var absolutePosition = getAbsolutePosition(event.target);
            startX = absolutePosition[0];
            startY = absolutePosition[1];

        })
        .on('dragmove', function(event) {
            event.interaction.x += event.dx;
            event.interaction.y += event.dy;

            if (transformProp) {
                event.target.style[transformProp] =
                    'translate(' + event.interaction.x + 'px, ' + event.interaction.y + 'px)';
            } else {
                event.target.style.left = event.interaction.x + 'px';
                event.target.style.top = event.interaction.y + 'px';
            }
        })
        .on('dragend', function(event) {
            event.target.setAttribute('data-x', event.interaction.x);
            event.target.setAttribute('data-y', event.interaction.y);
        });

    interact(document).on('ready', function() {
        transformProp = 'transform' in document.body.style ? 'transform' : 'webkitTransform' in document.body.style ? 'webkitTransform' : 'mozTransform' in document.body.style ? 'mozTransform' : 'oTransform' in document.body.style ? 'oTransform' : 'msTransform' in document.body.style ? 'msTransform' : null;
    });

}(window.interact));

这是我的基本html文件:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <title>WorkScreen Prototype #1</title>
   <script src="js/interact.js"></script>
   <script src="js/dropzones.js"></script>
   <link rel="stylesheet" href="css/dropzones.css">
</head>
<body style="background-color: #CCC; height: 852px">
   <a href="ShowSVGs.aspx" target="_blank">View All SVGs</a>
   <div style="margin-top:55px">
      <div style="float: left; vertical-align: top">
         <img id="drag1" src="images/SVG/ksBatteryBox.svg" class="draggable js-drag" style="width:80px"><br />
         <img id="drag2" src="images/SVG/ksBumper6308700.svg" class="draggable js-drag" style="width:85px"><br />
         <img id="drag3" src="images/SVG/ksHood8090130.svg" class="draggable js-drag" style="width:165px"><br />
         <img id="drag4" src="images/SVG/ksTire.svg" class="draggable js-drag" style="width:85px"><br />
      </div>
      <div style="float: left;vertical-align:top;margin-left:-72px">
         <div style ="margin-left:100px;">

            <div id="drop1" class="dropzone js-drop" style="margin-left:186px;"></div>
            <div id="drop2" class="dropzone js-drop" style="margin-left:90px"></div>

            <div style="">
               <div id="drop6" class="dropzone js-drop" style="clear: both; margin-left: 0px; margin-top: 37px"></div>
               <div style="float:left"><img src="images/BaseTruck.png" /></div>
               <div id="drop7" class="dropzone js-drop" style="float: left; margin-left: 251px; margin-top: 153px; position: absolute;"></div>
               <div id="drop3" class="dropzone js-drop" style="float:left; margin-left:10px;margin-top:37px"></div>
            </div>

            <div id="drop5" class="dropzone js-drop" style="clear: both; margin-left: 186px;"></div>
            <div id="drop4" class="dropzone js-drop" style="margin-left: 90px;"></div>

            <br /><br />
            <div id="message" style="clear: both; margin-left: 0px; margin-top: 44px; width: 245px; display: inherit; border: 2px solid gray; padding: 7px;"></div>

         </div>
      </div>
   </div>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

这是解决方案以防万一。无需确定相对于窗口的确切位置,以便将元素返回到其加载时间位置。就这样做:

function resetCoords(evt) {
    evt.relatedTarget.style.left = "0px";
    evt.relatedTarget.style.top = "0px";
    evt.interaction.x = 0;
    evt.interaction.y = 0;
}

然后像这样调用resetCoords:

.on('dropdeactivate', function(event) { // this fires after each drop, whether a drop into a valid drop zone occurs or not
    var active = event.target.getAttribute('active') | 0;

    // change style if it was previously active
    // but will no longer be active
    if (active === 1) {
        removeClass(event.target, '-drop-possible');
        //event.target.textContent = 'Dropzone';
    }

    event.target.setAttribute('active', active - 1);

    if (!validDrop) {
        resetCoords(event);
    }

})

.on('drop...)事件中,您将validDrop设置为true,否则它将为false。