Search code examples
javascriptjqueryhtmlbackground-imagedraggable

Javascript draggable div background


I got a little problem, I tried to modify the code for like one day.. without success.



The problem is that: Draggable works good, I can drag without problem the image.. but it goes even further the image make me see the blue of background color.

I know right is a problem about bounds, but I really don't know to.. resolve that problem, I tried to grab X and Y from Image but without success.

$(document).ready(function(){
var $bg = $('.bg-img'),
    data = $('#data')[0],
    elbounds = {
        w: parseInt($bg.width()), 
        h: parseInt($bg.height())
    },
    bounds = {w: 2350 - elbounds.w, h: 1750 - elbounds.h},
    origin = {x: 0, y: 0},
    start = {x: 0, y: 0},
    movecontinue = false;

function move (e){
    var inbounds = {x: false, y: false},
        offset = {
            x: start.x - (origin.x - e.clientX), 
            y: start.y - (origin.y - e.clientY)
        };

    data.value = 'X: ' + offset.x + ', Y: ' + offset.y;

    inbounds.x = offset.x < 0 && (offset.x * -1) < bounds.w;
    inbounds.y = offset.y < 0 && (offset.y * -1) < bounds.h;

    if (movecontinue && inbounds.x && inbounds.y) {
        start.x = offset.x;
        start.y = offset.y;

        $(this).css('background-position', start.x + 'px ' + start.y + 'px');
    }

    origin.x = e.clientX;
    origin.y = e.clientY;

    e.stopPropagation();
    return false;
}

function handle (e){
    movecontinue = false;
    $bg.unbind('mousemove', move);

    if (e.type == 'mousedown') {
        origin.x = e.clientX;
        origin.y = e.clientY;
        movecontinue = true;
        $bg.bind('mousemove', move);
    } else {
        $(document.body).focus();
    }

    e.stopPropagation();
    return false;
}

function reset (){
    start = {x: 0, y: 0};
    $(this).css('backgroundPosition', '0 0');
}

$bg.bind('mousedown mouseup mouseleave', handle);
$bg.bind('dblclick', reset);
});

Example code: https://jsfiddle.net/zt1jjzqL/3/


Solution

  • Here I only modify a couple of things;

    • New function to calculate image dimensions
    • Calculate the most Left and Up the image can move.
    • limit the movement up and left with those.

    $(document).ready(function() {
      var $bg = $('.bg-img'),
        data = $('#data')[0],
        elbounds = {
          w: parseInt($bg.width()),
          h: parseInt($bg.height())
        },
        bounds = {
          w: 2350 - elbounds.w,
          h: 1750 - elbounds.h
        },
        origin = {
          x: 0,
          y: 0
        },
        start = {
          x: 0,
          y: 0
        },
        movecontinue = false;
      bgSize($bg, function(w, h) { //act on and store the most up and left
        console.log(`image dimensions => width:${w}, height:${h}`);
        $bg.data("mostleft", (elbounds.w * -1) + w);
        $bg.data("mostup", (elbounds.h * -1) + h);
      });
    
    
      function move(e) {
        var inbounds = {
            x: false,
            y: false
          },
          offset = {
            x: start.x - (origin.x - e.clientX),
            y: start.y - (origin.y - e.clientY)
          };
    
        data.value = 'X: ' + offset.x + ', Y: ' + offset.y;
    
        inbounds.x = offset.x < 0 && (offset.x * -1) < bounds.w;
        inbounds.y = offset.y < 0 && (offset.y * -1) < bounds.h;
    
        if (movecontinue && inbounds.x && inbounds.y) {
          // ensure that up and left are limited appropriately
          start.x = offset.x < ($bg.data("mostleft") * -1) ? ($bg.data("mostleft") * -1) : offset.x;
          start.y = offset.y < ($bg.data("mostup") * -1) ? ($bg.data("mostup") * -1) : offset.y;
    
          $(this).css('background-position', start.x + 'px ' + start.y + 'px');
        }
    
        origin.x = e.clientX;
        origin.y = e.clientY;
    
        e.stopPropagation();
        return false;
      }
    
      function handle(e) {
        movecontinue = false;
        $bg.unbind('mousemove', move);
    
        if (e.type == 'mousedown') {
          origin.x = e.clientX;
          origin.y = e.clientY;
          movecontinue = true;
          $bg.bind('mousemove', move);
        } else {
          $(document.body).focus();
        }
    
        e.stopPropagation();
        return false;
      }
    
      function reset() {
        start = {
          x: 0,
          y: 0
        };
        $(this).css('backgroundPosition', '0 0');
      }
    
      $bg.bind('mousedown mouseup mouseleave', handle);
      $bg.bind('dblclick', reset);
    });
    //function to accurately calculate image size.
    function bgSize($el, cb) {
      $('<img />')
        .load(function() {
          cb(this.width, this.height);
        })
        .attr('src', $el.css('background-image').match(/^url\("?(.+?)"?\)$/)[1]);
    }
    div.bg-img {
      background-image: url(http://i.imgur.com/ZCDMWnX.gif);
      background-position: 0 0;
      background-repeat: no-repeat;
      background-color: blue;
      border: 1px solid #aaa;
      width: 500px;
      height: 250px;
      margin: 25px auto;
    }
    
    p,
    #data {
      text-align: center;
    }
    
    #data {
      background: red;
      font-weight: bold;
      color: white;
      padding: 5px;
      font-size: 1.4em;
      border: 1px solid #ddd;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="bg-img"></div>
    <p>
      <input type="text" id="data" />
    </p>