I am applying a CSS transform (and the browser specific -webkit, -o etc):
transform: matrix(0.5 , 0 , 0, 0.5, 0 , 0);
to a div then using jQuery\'s draggable
I was trying the transform scale() fix for resizable posted by gungfoo on a element displayed at 10% of its actual size and the method didin't work. The cursor still moved away from the element during resizing.
I changed the last two lines of the resizeFix method to directly update the element's width and height and this solved my issue.
function resizeFix(event, ui) {
var changeWidth = ui.size.width - ui.originalSize.width; // find change in width
var newWidth = ui.originalSize.width + changeWidth / zoomScale; // adjust new width by our zoomScale
var changeHeight = ui.size.height - ui.originalSize.height; // find change in height
var newHeight = ui.originalSize.height + changeHeight / zoomScale; // adjust new height by our zoomScale
ui.originalElement.width(newWidth);
ui.originalElement.height(newHeight);
}
None of these solutions worked for me, as for one, I could not transform the parent of the draggables - only the draggables themselves were transformed.
This is how I fixed this issue:
$('.draggable').draggable(
{
cancel: '.restrict-drag',
scroll: false,
containment: '#contain',
start: function(event, ui)
{
ui.position.left = 0;
ui.position.top = 0;
},
drag: function(event, ui)
{
ui.position.left = ui.position.left - ($(event.target).width() * Zoom);
ui.position.top = ui.position.top - ($(event.target).height() * Zoom);
}
});
Zoom is by default 0.
To scale the draggables I did the following:
function changeZoom(zoom)
{
$('.draggable').each(function() { $(this).css('transform-origin', '50% 50%'); $(this).css('transform', 'scale(' + zoom + ')'); });
Zoom = zoom; // Global Zoom-variable
}
And everything seems to work allright.
My own "answer" was on this occasion was to adapt jQuery UI draggable to make a separate interaction, called "traggable".
https://github.com/paullth/JS-libs
http://jsfiddle.net/paul_herve/ws27C/4/
Would still like to hear about any alternatives...
For a long time I wonder why @GungFoo
solution not working for me for Jquery Resizable but some people told it was worked. Finally I found out there are 4 points for using jQuery Draggable and Resizable with CSS Transform Scale:
Check some of this problems:
function resizeDiv(event, ui) {
debugger;
var changeWidth = ui.size.width - ui.originalSize.width;
var newWidth = ui.originalSize.width + changeWidth / 4;
var changeHeight = ui.size.height - ui.originalSize.height;
var newHeight = ui.originalSize.height + changeHeight / 4;
ui.size.width = newWidth;
ui.size.height = newHeight;
};
$('#box').resizable({
minWidth: -($(this).width()) * 10,
minHeight: -($(this).height()) * 10,
resize: resizeDiv
});
$('#box2').resizable({
minWidth: -($(this).width()) * 10,
minHeight: -($(this).height()) * 10,
resize: resizeDiv
});
$('#box3').resizable({
minWidth: -($(this).width()) * 10,
minHeight: -($(this).height()) * 10,
resize: resizeDiv
});
$('#box4').resizable({
minWidth: -($(this).width()) * 10,
minHeight: -($(this).height()) * 10,
resize: resizeDiv
});
.box{
position:absolute;
width:30px;
height:30px;
border:1px solid black;
font-size:3pt;
overflow:hidden;
-webkit-transform:scale(4);
direction:ltr;
}
#box{
transform-origin: top left;
top: 0;
left:0;
}
#box2{
transform-origin: bottom left;
top: 250px;
left:0;
}
#box3{
direction:rtl;
left: 250px;
top: -10px;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
<div id= 'box' class="box">
True styles
</div>
<div id= 'box2' class="box">
Bad transform-orgin
</div>
<div id= 'box3' class="box">
Bad direction
</div>
Thanks to @Guy ;)
Here is my solution. Some of the code posted above did not work for me.
I have a dragable image and I apply CSS transform rotate and scale onto that image. Once I scale/rotate it the position is off at drag-start. To fix it I calculate the setpoint difference from stop to start and on-drag apply a new setpoint with the difference factored in.
var $img = $("#my-image-id");
$img.posLeft = 0;
$img.posTop = 0;
$img.diffLeft = 0;
$img.diffTop = 0;
$img.draggable({
start: function( event, ui ) {
//check the difference from start to stop setpoints
$img.diffLeft = $img.posLeft-ui.position.left;
$img.diffTop = $img.posTop-ui.position.top;
//console.log('start x: '+Math.floor(ui.position.left)+' y: '+Math.floor(ui.position.top));
//console.log('diff x: '+Math.floor($img.posLeft-ui.position.left)+' y: '+Math.floor($img.posTop-ui.position.top));
},
drag: function( event, ui ) {
//fix the offset bug that is applied after CSS transform, to do that just add the value difference
ui.position.left = ui.position.left+$img.diffLeft;
ui.position.top = ui.position.top+$img.diffTop;
//console.log('drag x: '+ui.position.left+' y: '+ui.position.top);
},
stop: function( event, ui ) {
//save the last applied setpoints
$img.posLeft = ui.position.left;
$img.posTop = ui.position.top;
//console.log('stop x: '+Math.floor(ui.position.left)+' y: '+Math.floor(ui.position.top));
}
});
The CSS transform-origin trick does fixes the bug for scale only. Rotation should be around center so you want to keep the default 50% 50%.
For different resize corner
$('.rect-item').resizable({
handles: 'n,e,s,w,ne,se,sw,nw',
resize: (e, ui) => {
const zoomScale = Your scale;
const changeWidth = ui.size.width - ui.originalSize.width; // find change in width
const newWidth = ui.originalSize.width + changeWidth / zoomScale; // adjust new width by our zoomScale
const changeHeight = ui.size.height - ui.originalSize.height; // find change in height
const newHeight = ui.originalSize.height + changeHeight / zoomScale; // adjust new height by our zoomScale
ui.size.width = newWidth;
ui.size.height = newHeight;
// here
const posOrigin = ui.originalPosition;
if (posOrigin.left !== ui.position.left) {
ui.position.left = posOrigin.left - changeWidth / zoomScale;
}
if (posOrigin.top !== ui.position.top) {
ui.position.top = posOrigin.top - changeHeight / zoomScale;
}
}
});