user2718671 user2718671 - 7 months ago 57
Javascript Question

How to pass aspectRatio option to alsoResize Object in jQuery UI's resizable function?

Alright, to make it short, here you can see the problem:
http://jsfiddle.net/EgBh3/

When resizing the slider on the left side the video on the right is resizing too. It's not implemented in the jQuery UI that the other div size is inverted when resizing. I found this useful function here: jQuery UI Resizable alsoResize reverse

The problem is that the aspect ratio of the video changes. If you play it after resizing you see that the control bar is longer than the video itself for example.

The normal resizable() function offers the option to set an aspectRatio that should be kept. But is it possible to pass such an option to the alsoResizeReverse function? If yes, how?

Here's the code:
HTML:

<div id="wrapper">
<div id="pdf_presentation">
<div id="slider">
<ul class="bxslider">
<li class="12302">
<img src="http://www.projectorcentral.com/images/articles/4-3%20Bristlecone%20Pines.jpg" alt="page 0" />
</li>
<li class="12302">
<img src="http://img3.wikia.nocookie.net/__cb20060423235201/tovid/images/0/00/4_3_grid.jpg" alt="page 1" />
</li>
<li class="12302">
<img src="http://www.freecomputerdesktopwallpaper.com/new_wallpaper/5_4_3_2_1_Happy_New_Year_freecomputerdesktopwallpaper_p.jpg" alt="page 2" />
</li>
<li class="12302">
<img src="http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/image/tests/images/imageHoriz.jpg" alt="page 3" />
</li>
<li class="12302">
<img src="http://4.bp.blogspot.com/-cVEz-BBU5Mw/U8uLaEKhdCI/AAAAAAAAJxQ/ZG06K9VPj9A/s1600/P1130206.JPG" alt="page 4" />
</li>
<li class="12302">
<img src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcSKccu9ixyiNsVR7cHZNdQNUiTRwMMEvkGFbaU_eFC1FaW_DTMCNw" alt="page 5" />
</li>
</ul>
<div id="custom_pager">
<ul id="custom_pager_list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</div>
</div>
<div id="video_wrapper">
<video preload="none" id="movie" controls>
<source id="mp4" type="video/mp4" src="http://www.w3schools.com/html/mov_bbb.mp4"></source>
<source id="webm" type="video/ogg" src="http://www.w3schools.com/html/mov_bbb.ogg"></source>
</video>
</div>
</div>


CSS:

*{
padding: 0;
margin: 0;
}

body{
font-family: Arial, Helvetica, Verdana, sans-serif;
font-size: 12px;
}

#wrapper{
width: 980px;
height: 1000px;
margin: 0 auto;
margin-top: 20px;
box-shadow: 0 0 10px #ccc;
}

#slider{
width: 400px;
height: 300px;
float: left;
margin-left: 10px;
}

#video_wrapper{
float: right;
margin-right: 10px;

}

#video_wrapper video{
width: 548px;
height: 308px;
}

.bx-pager{
display: none;
}

#custom_pager{
float: left;
width: 400px;
height: auto;
}

#custom_pager li{
float: left;
list-style-type: none;
cursor: pointer;
padding: 0 3px;
}

#custom_pager li:hover {
font-weight: bold;
}

.bx-wrapper{
margin-bottom: 0 !important;
}

.current_slide{
font-weight: bold;
}

.ui-resizable-se{
z-index: 300000 !important;
}


Javascript/jQuery:

$('.bxslider').bxSlider({
mode: 'fade',
infiniteLoop: false,
hideControlOnEnd: true,
keyboardEnabled: true,
useCSS: false,
controls: false
});

$('#slider').resizable({
aspectRatio: 750 / 577,
handles: 'se',
containment: '#wrapper',
autoHide: true,
alsoResizeReverse: "#movie",
resize: function (e, ui) {
$('.bxslider img, .bx-viewport, .bx-wrapper').css({
width: ui.size.width,
height: ui.size.height
});
$('.bx-wrapper img').css({
maxWidth: ui.size.width
});
$('#custom_pager').css({
width: ui.size.width
});
//console.log($('#custom_pager').height());
var custom_pager_height = $('#custom_pager').height();
$('#slider').css({
height: ui.size.height + custom_pager_height
});
}
});


$.ui.plugin.add("resizable", "alsoResizeReverse", {

start: function(event, ui) {

var self = $(this).data("resizable"), o = self.options;

var _store = function(exp) {
$(exp).each(function() {
$(this).data("resizable-alsoresize-reverse", {
width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
});
});
};

if (typeof(o.alsoResizeReverse) == 'object' && !o.alsoResizeReverse.parentNode) {
if (o.alsoResizeReverse.length) { o.alsoResize = o.alsoResizeReverse[0]; _store(o.alsoResizeReverse); }
else { $.each(o.alsoResizeReverse, function(exp, c) { _store(exp); }); }
}else{
_store(o.alsoResizeReverse);
}
},

resize: function(event, ui){
var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;

var delta = {
height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
},

_alsoResizeReverse = function(exp, c) {
$(exp).each(function() {
var el = $(this), start = $(this).data("resizable-alsoresize-reverse"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];

$.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
var sum = (start[prop]||0) - (delta[prop]||0); // subtracting instead of adding
if (sum && sum >= 0)
style[prop] = sum || null;
});

//Opera fixing relative position
if (/relative/.test(el.css('position')) && $.browser.opera) {
self._revertToRelativePosition = true;
el.css({ position: 'absolute', top: 'auto', left: 'auto' });
}

el.css(style);
});
};

if (typeof(o.alsoResizeReverse) == 'object' && !o.alsoResizeReverse.nodeType) {
$.each(o.alsoResizeReverse, function(exp, c) { _alsoResizeReverse(exp, c); });
}else{
_alsoResizeReverse(o.alsoResizeReverse);
}
},

stop: function(event, ui){
var self = $(this).data("resizable");

//Opera fixing relative position
if (self._revertToRelativePosition && $.browser.opera) {
self._revertToRelativePosition = false;
el.css({ position: 'relative' });
}

$(this).removeData("resizable-alsoresize-reverse");
}
});

Answer

By default, alsoResizeReverse does not have an option for setting an aspect ratio, but you can add one. Change your configuration of the resizable to include the option alsoResizeReverseAspectRatio:true:

$('#slider').resizable({
    aspectRatio: 750 / 577,
    handles: 'se',
    containment: '#wrapper',
    autoHide: true,
    alsoResizeReverse: "#movie",
    alsoResizeReverseAspectRatio:true,
    resize: function (e, ui) {
        $('.bxslider img, .bx-viewport, .bx-wrapper').css({
            width: ui.size.width,
            height: ui.size.height
        });
        $('.bx-wrapper img').css({
            maxWidth: ui.size.width
        });
        $('#custom_pager').css({
            width: ui.size.width
        });
        //console.log($('#custom_pager').height());
        var custom_pager_height = $('#custom_pager').height();
        $('#slider').css({
            height: ui.size.height + custom_pager_height
        });
     }
});

And then change the code within the alsoResizeReverse modification to support this option. These lines:

$.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
    var sum = (start[prop]||0) - (delta[prop]||0); // subtracting instead of adding
    if (sum && sum >= 0)
        style[prop] = sum || null;
});

should be changed to this:

if(o.alsoResizeReverseAspectRatio) {
    $.each(css || ['width', 'top', 'left'], function(i, prop) {
        var sum = (start[prop]||0) - (delta[prop]||0); // subtracting instead of adding
        if (sum && sum >= 0)
            style[prop] = sum || null;
    });

    // Handle height differently since we want it based on the original width
    var sum;
    if(o.alsoResizeReverseAspectRatio === true)
        sum = (start['height']||0) - ((delta['width']||0) * start['height']/start['width']);
    else
        sum = (start['height']||0) - ((delta['width']||0) * 1 / o.alsoResizeReverseAspectRatio);

    if(sum && sum >= 0)
        style['height'] = sum || null;
} else {
    $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
        var sum = (start[prop]||0) - (delta[prop]||0); // subtracting instead of adding
        if (sum && sum >= 0)
            style[prop] = sum || null;
    });
}

The JSFiddle can be found here: http://jsfiddle.net/EgBh3/1/.

Comments