petit lustucru
petit lustucru

Reputation: 11

Guides when resizing jquery-ui-resizable boxes

I'm trying to show guides while resizing boxes, based on this answer.

$('.resizable').resizable({
    start: function( event, ui ) {
        guides = $.map($('.resizable').not(this), computeGuidesForElement);
        innerOffsetX = event.originalEvent.offsetX;
        innerOffsetY = event.originalEvent.offsetY;
    }, 
    resize: function( event, ui ){
        // iterate all guides, remember the closest h and v guides
        var guideV, guideH, distV = MIN_DISTANCE+1, distH = MIN_DISTANCE+1, offsetV, offsetH; 
        var chosenGuides = { top: { dist: MIN_DISTANCE+1 }, left: { dist: MIN_DISTANCE+1 } }; 
        var $t = $(this); 
        var pos = { top: event.originalEvent.pageY - innerOffsetY, left: event.originalEvent.pageX - innerOffsetX }; 
        var w = $t.outerWidth() - 1; 
        var h = $t.outerHeight() - 1; 
        var elemGuides = computeGuidesForElement( null, pos, w, h ); 
        $.each( guides, function( i, guide ){
            $.each( elemGuides, function( i, elemGuide ){
                if( guide.type == elemGuide.type ){
                    var prop = guide.type == "h"? "top":"left"; 
                    var d = Math.abs( elemGuide[prop] - guide[prop] ); 
                    if( d < chosenGuides[prop].dist ){
                        chosenGuides[prop].dist = d; 
                        chosenGuides[prop].offset = elemGuide[prop] - pos[prop]; 
                        chosenGuides[prop].guide = guide; 
                    }
                }
            } ); 
        } );

        if( chosenGuides.top.dist <= MIN_DISTANCE ){
            $( "#guide-h" ).css( "top", chosenGuides.top.guide.top ).show(); 
            ui.position.top = chosenGuides.top.guide.top - chosenGuides.top.offset;
        } else {
            $( "#guide-h" ).hide(); 
            ui.position.top = pos.top; 
        }

        if (chosenGuides.left.dist <= MIN_DISTANCE) {
            $( "#guide-v" ).css( "left", chosenGuides.left.guide.left ).show(); 
            ui.position.left = chosenGuides.left.guide.left - chosenGuides.left.offset; 
        } else {
            $("#guide-v").hide(); 
            ui.position.left = pos.left; 
        }
    }, 
    stop: function( event, ui ){
        $( "#guide-v, #guide-h" ).hide(); 
    }
});

For some reason, while resizing, the boxes are both resized and dragged at the same time (meaning that they move around the page).

Why is the dragging event triggered? What am I doing wrong?

Upvotes: 0

Views: 49

Answers (1)

Twisty
Twisty

Reputation: 30883

Consider the following example.

$(function() {
  function makeGuides(el) {
    return $(el).data("guides", {
      h: $("<div>", {
        class: "h-guide"
      }).css({
        borderTop: "2px dashed #AAF",
        borderBottom: "2px dashed #AAF",
        position: "absolute",
        width: "100%",
        height: $(el).outerHeight()
      }).appendTo("body").position({ of: el
      }),
      v: $("<div>", {
        class: "v-guide"
      }).css({
        borderLeft: "2px dashed #AAF",
        borderRight: "2px dashed #AAF",
        position: "absolute",
        left: $(el).position.left + "px",
        top: "0px",
        width: $(el).outerWidth(),
        height: "100%"
      }).appendTo("body").position({ of: el
      })
    });
  }

  function moveGuides(el, pos) {
    $(el).data("guides").h.css({
      height: pos.height
    })
    $(el).data("guides").v.css({
      width: pos.width
    });
  }

  $(".resizable").resizable({
    grid: 5,
    start: function(evemt, ui) {
      if ($(this).data("guides") == undefined) {
        makeGuides(this);
      }
      $(this).data("guides").h.show();
      $(this).data("guides").v.show();
    },
    resize: function(event, ui) {
      moveGuides(this, $.extend(ui.position, {
        width: $(this).outerWidth(),
        height: $(this).outerHeight()
      }))
    },
    stop: function() {
      $(this).data("guides").h.hide();
      $(this).data("guides").v.hide();
    }
  });
});
.resizable {
  width: 150px;
  height: 150px;
  padding: 0.5em;
}

#resizable h3 {
  text-align: center;
  margin: 0;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>

<div id="box-1" class="resizable ui-widget-content">
  <h3 class="ui-widget-header">Resizable</h3>
</div>
<div id="box-2" class="resizable ui-widget-content">
  <h3 class="ui-widget-header">Resizable</h3>
</div>

This makes two boxes: one for horizontal guides, one for vertical guides.

The horizontal box should be 100% as tall as the screen and be as wide as the resized element. The vertical should be 100% wide and as tall as the element.

Using .data(), we can make elements and store them with the primary element. This way you can have multiple guides for multiple elements.

Using grid option, we can make sure the resize can snap to other elements.

Upvotes: 0

Related Questions