skip to Main Content

I have a div that has been scaled using transform, and within it another div that is draggable. When the scale of the transformed div is not 1, the draggable div essentially disassociates from the mouse. JSFiddle here

I don’t have any control over the javascript (it is a third party component being embedded in the page). Is there a CSS solution to this, or maybe a "global" jquery solution to set the container to the body?

Relevant CSS my side:

-webkit-transform: scale(1.5);

JQuery called in 3rd party component

$('.draggable').draggable();

2

Answers


  1. Going over the jQuery UI – Draggable documentation (https://api.jqueryui.com/draggable/).

    Seems like your only chance without going custom is to alter the data with the drag event (more information on https://api.jqueryui.com/draggable/#event-drag ).

    The documentation quotes the following:

    Triggered while the mouse is moved during the dragging, immediately before the current move happens.

    The example shows is as follows:

    jQuery Draggable Example – Drag Event

    Initialize the draggable with the drag callback specified:

    $( ".selector" ).draggable({
      drag: function( event, ui ) {}
    });
    

    Bind an event listener to the drag event:

    $( ".selector" ).on( "drag", function( event, ui ) {} );
    
        
    

    Constrain movement via ui.position:

    $( ".selector" ).draggable({
      drag: function( event, ui ) {
     
        // Keep the left edge of the element
        // at least 100 pixels from the container
        ui.position.left = Math.min( 100, ui.position.left );
      }
    });
    

    And possibly altering the example to take the position and reduce it by 1.5.

    Login or Signup to reply.
  2. This is a workaround/alternative to your code and may not be what you are looking for…

    At first I thought your issue was due to the fact that scaling does not automatically scale the orginal space an element occupies and caused some mousepos offset discrepancy. Usually this can be corrected by calculating a positive or negative margin relative to the scale applied. Positive for a scaled up, negative for a scaled down element and assign that to the scaled elements margin.

    However, testing this with your Fiddle it did not have the expected result, so I opted to work around the issue:

    • Instead of transform: scale(..) or scale: .., introduce a CSS custom property with a scale factor (--scale-factor: 1.5)
    • calc(..)ulate all relevant sizes relative to the current value of --scale-factor

    snippet, Fiddle, Codepen.

    $('.draggable').draggable();
    :root {
        --scale-factor: 1.5;   /* Initial scale factor */
        --base-size   : 1rem;  /* 16px, or whatever you require */
    }
    
    #parent {
        /* Base size relative to current scale factor */
        --scaled-size : calc(var(--scale-factor) * var(--base-size));
    
        /* Element is a square, using just one calc(..) */
        --element-size: calc(12.5 * var(--scaled-size)); /* 12.5 * 1rem (scaled!) = 200px */
    
        width    : var(--element-size); /* from 200px */
        height   : var(--element-size);
        font-size: var(--scaled-size); /* [OPTIONAL] */
    
        background: yellow;
    
        margin: calc(1.25 * var(--scaled-size)); /* [OPTIONAL], from 20px */
    }
    
    .draggable {
        height: 25%; /* from  50px */
        width : 50%; /* from 100px */
        /* Set these to original values if they should not be scaled */
        /* font-size: var(--base-size); /* dito, set to required size, here: 1rem */
    
        text-align: center;
    
        background: red;
        color: #fff;
    }
    
    /*************/
    /* DEMO only */
    /*************/
    *    { outline: 1px dashed black } /* for debugging */
    
    *    { box-sizing: border-box }
    
    
    body { padding-top: 5rem; margin: 0 }
    
    label {
        position: fixed; top: 0; left: 0; z-index: 9999;
        display: inline-flex; flex-direction: column;
        width: 100%; padding: 1rem; font-size: 1rem;
        background-color: hsl(0,0%,96%,.95); cursor: pointer;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
    
    <label><span id="info-scale">Scale factor: 1.5</span>
      <input type="range" min="0.5" max="3" value="1.5" step="0.01" oninput="document.documentElement.style.setProperty('--scale-factor', this.value);
                        document.getElementById('info-scale').innerHTML = 'Scale factor: ' + this.value;"></label>
    
    
    <div id="parent">
      <div class="draggable">Example</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search