I am working on a fairly typical image "reveal" effect using jQuery UI’s draggable() method; I’m having a lot of trouble making it work in a responsive environment:
http://codepen.io/ProfessorSamoff/pen/qEaNMM
As you’ll see, the reveal functionality works correctly at full size as well as when the browser window size is reduced. But the draggable handle doesn’t always snap to the proper position when the browser window is resized. (Although it does so when it’s clicked and dragged.)
Likewise, you’ll see that I have some commented code that checks against the browser window size:
if($(this).width() != width)
{
}
This works in order to get the draggable handle to the correct place when resizing the browser window, but it breaks the draggable functionality.
I have tried a few of the suggestions on Stack Overflow concerning draggable() and resizable(), but none of them work.
take a look here:
http://codepen.io/anon/pen/LEmgBP
javascript now appears in this way:
var $reveal = $(".reveal");
$reveal.draggable({
axis: "x",
containment: "parent",
iframeFix: true,
refreshPositions: true,
drag: function()
{
var position = $(this).position();
var parentWidth = $(this).parent().width();
var width = (position.left / parentWidth) * 100
$(".featured").width(width + "%");
}
});
$(window).resize(function() {
$reveal.css('left', $(".featured").width()+'px')
});
It's not elegant but it seems to work.
basically I did 2 things:
1) I've setted $(".featured") width with %
2) on windows resize I change the position of the cursor with
$reveal.css('left', $(".featured").width()+'px')
note: point 2) is a workaround but I didn't find any way to move the cursor programatically. Maybe using a library to emulate the drag event (like https://github.com/mattheworiordan/jquery.simulate.drag-sortable.js/blob/master/README.md) you could find something better
Related
I am using jQuery ui resizable with an aspect ratio set to 16/9.
$(".select").resizable({
containment: "#container",
aspectRatio: 16 / 9,
grid: 1,
stop: function (e, ui) {},
});
I want to be able to drag the resizable element full width to match the container but if never quite reaches it see this image.
You should notice the gap far right.
Here is a working demo I am testing with.
https://output.jsbin.com/cimorikefu/2/
I want to be able to drag the element full width any suggestions?
What you encounter seems to be caused by combination of miscalculations in jQuery UI Resizable plugin. It's hard to label those as 'bugs': when it was written, the code worked just fine.
Some of those issues are covered in the ticket created 9 (!) years ago. The last message there was written 5 years ago, so there's little chance of fixing that; the world has moved on.
Here's the suspicious parts of the code (1.12 source is analyzed):
// in _mouseStart()
this.sizeDiff = {
width: el.outerWidth() - el.width(),
height: el.outerHeight() - el.height()
};
// ... in resize()
woset = Math.abs( that.sizeDiff.width + // ... )
This part seems to ignore the fact that elements might have different box-sizing models, always attempting to process those based on content-box - and take border width into account.
While the behavior of outerWidth() and width() has been corrected in jQuery 1.8, the corresponding adjustments didn't reach Resizable source in time. Now the PR prepared and listed in the linked ticket is no longer applicable (after the code has been refactored in ~1.10).
Still, there's more:
if ( woset + that.size.width >= that.parentData.width ) {
that.size.width = that.parentData.width - woset;
if ( pRatio ) {
that.size.height = that.size.width / that.aspectRatio;
continueResize = false;
}
}
// ...
if ( !continueResize ) {
that.position.left = that.prevPosition.left;
that.position.top = that.prevPosition.top;
that.size.width = that.prevSize.width;
that.size.height = that.prevSize.height;
}
In this case pRatio is set, which means whenever your resizing operation is about to make the resizable object the same size as container, its width is reset to the previous size. So if you move your mouse fast enough, the resizable element gets stuck way before the hitting the container's borders.
While the first issue here might be mitigated a bit by replacing border with outline when styling .ui-widget-content, the only way to fix the second part is to fix the plugin's code.
I have app where i need only snap element to top and bottom edges of parent element. I try to find how to do it in stack but i can't find it!
el.draggable({
start: function(){
var snapped = $(this).data('draggable').snapElements;
snapped.forEach(function(el){
el.width = 1000000;
el.left = -50000;
});
}
})
One approach is doing the snapping manually instead of relying on the draggable's functionality. E.g. you can disable the snapping and in your drag handle implement it by changing the object's position whenever it's close enough to whatever location you like.
Here's a solution for the similar request: Getting jQuery draggable to snap to specific grid
I have a web page with a couple div elements that are resizable and draggable through the jquery ui library.
$('#myDiv').draggable({ containment: "parent" }).resizable({ aspectRatio: true});
Dragging and resizing work fine, but I would like the divs to resize to maintain their relative size to the window as the window is resized. For example if drag div 1 to the top right and size it to 50% of the screen width, is there a way to maintain that sizing as the window resizes? I can't seem to find any options within jquery or jquery ui to allow me to force the elements to size based on percentage. Is there a way to do this with jquery, or do I need to write code that gets called on window resize that can handle this?
What I have done is following the answer of this question:
stackoverflow.com/questions/37328053/draggable-object-goes-outside-the-container-when-the-window-is-resized
What they propose is on stop the dragging event, convert to % positions you would like to keep, in the above exeample I converted left and top.
$('#myDiv').draggable({containment: "parent",
stop: function(e, ui) {
var percLeft = ui.position.left/ui.helper.parent().width()*100;
var percTop = ui.position.top/ui.helper.parent().height()*100;
ui.helper.css('left', percLeft + '%');
ui.helper.css('top', percTop + '%');
}
}).resizable({ aspectRatio: true});
Is there a way to reinitialize stellar.js on browser/window resize so that the element offsets get readjusted?
First of all, it sounds like you might be having an issue with horizontal alignment (assuming it's a vertical site). If so, it's likely that you only need to disable horizontal scrolling:
$.stellar({
horizontalScrolling: false
});
If this doesn't solve your issue, Stellar.js has an undocumented feature that allows you to refresh the plugin.
For example, let's assume you used Stellar.js like this:
$.stellar();
You can refresh it with the following:
$.stellar('refresh');
So, to refresh it on resize, you could do something like this:
$(window).resize(function() {
$.stellar('refresh');
});
Hopefully this should fix everything for you.
After a bit of sleuthing, I've figured this one out. In my case, I have 'slides', which contain my stellar elements, and they are sized to full width/height of the viewport. I needed to resize them for tablet orientation change.
$(window).resize(function(){
winHeight = $(window).height();
$("#scrollWrapper > div").height(winHeight);
// Find out all my elements that are being manipulated with stellar
var particles = $(window).data('plugin_stellar').particles;
// Temporarily stop stellar so we can move our elements around
// data('plugin_stellar') let's me access the instance of stellar
// So I can use any of its methods. See stellar's source code
$(window).data('plugin_stellar').destroy();
$.each(particles, function(i, el){
// destroy() sets the positions to their original PIXEL values.
// Mine were percentages, so I need to restore that.
this.$element.css('top', '');
// Once the loop is finished, re-initialize stellar
if(particles.length - 1 == i){
$(window).data('plugin_stellar').init();
}
});
});
If it doesn't matter that the elements get set to their original pixel values for left/top, then you can just call destroy & init one after the other:
$(window).data('plugin_stellar').destroy();
$(window).data('plugin_stellar').init();
If you instantiate stellar on an element (i.e., $("#element").stellar(); instead of $.stellar();) then replace "window" with your selector.
I also noticed odd offsets on mobiles that may be caused by the way Firefox/Chrome resizes the webview when scrolling down, when the location bar becomes visible again?
The answer to your question is in a section of the documentation: "Configuring everything":
// Refreshes parallax content on window load and resize
responsive: false,
So, this is false by default. To enable this, use .stellar( {responsive:true} )
The real question is... why is this disabled by default? It seemed to fix the problem I was noticing, except for iOS.
I'm having issue with VML (which I use as fallback for svg)
I use jQuery UI draggable to let user be able to move an element around. The problem occurs when I resize the image (which is a v:image) by changing the style attribute of height and width.
What happen at this point is that the element get stuck at the left top corner of it's container and cannot be dragged anymore.
A strange thing is that when I ask for the position (top, left) of the draggable element in the JavaScript console, I get value, and those values change when I click and drag - even though the element isn't visually moving...
Anyone run into this problem before?
Here's where I change then size of my element.
$($image)
.css({
'width' : zoomInPx_width + "px",
'height' : zoomInPx_height + "px"
});
The draggable is set pretty straight forward
$($image).draggable({
drag: function () { /*callback here*/ }
})
Finaly I manage to make this work.
Seems that VML crash on IE 8 when we change size of a draggable element. So, I had to destroy the element and recreate it from scratch when sliding occurs...
That's not really performant, but that's the only fix to work for me up here.
By the way, .detach() didn't work, you have to destroy it and recreate it from scratch.
You can get some info there too: http://www.acumen-corp.com/Blog/tabid/298/EntryId/26/Using-jqueryRotate-ui-draggable-and-resizable-images-in-IE7-IE8-and-any-other-browser.aspx
on my application I used this code:
var $cloned_image = $($image).clone().get(0);
$($image).remove();
// need add draggable again
$($cloned_image).draggable();
document.getElementById('k').appendChild($cloned_image);
$image = $cloned_image;