如何在jQuery UI的可调整大小的函数中将aspectRatio选项传递给alsoResize对象?

时间:2014-07-31 14:31:20

标签: javascript jquery jquery-ui resize

好吧,为了缩短它,在这里你可以看到问题: http://jsfiddle.net/EgBh3/

当调整左侧滑块的大小时,右侧的视频也会调整大小。在调整大小时,在jQuery UI中没有实现另一个div大小被反转。我在这里找到了这个有用的功能:jQuery UI Resizable alsoResize reverse

问题是视频的宽高比发生了变化。如果您在调整大小后播放它,则会看到控制栏比视频本身长。

普通的resizable()函数提供了设置应保留的aspectRatio的选项。但是可以将这样的选项传递给alsoResizeReverse函数吗?如果是,怎么样?

这里是代码: 的 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");
    }
});    

2 个答案:

答案 0 :(得分:1)

默认情况下,alsoResizeReverse没有设置宽高比的选项,但您可以添加一个。更改resizable的配置以包括选项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
        });
     }
});

然后更改alsoResizeReverse修改中的代码以支持此选项。这些行:

$.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;
});

应改为:

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;
    });
}

JSFiddle可以在这里找到:http://jsfiddle.net/EgBh3/1/

答案 1 :(得分:0)

这对我有用。如果我正确理解你的问题,我的问题是类似的:我有一个可以左右移动的垂直屏幕分割和左视图中的一些图像应该相应调整大小 - 保持纵横比。因此,当屏幕较小时,图像会越来越“缩略”(然后可以看到更多图像)。

$( "#leftView" ).resizable({
 alsoResizeKeepAspectRatio: ".divWithImage"
}); 

为此,你必须添加这个自定义插件(它是一个改编版的fromResize插件,从jQueryui JS文件中获取)。

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

    start: function() {
        var that = $(this).resizable( "instance" ),
            o = that.options;

        $(o.alsoResizeKeepAspectRatio).each(function() {
            var el = $(this);
            el.data("ui-resizable-alsoresize", {
                width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
                left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
            });
        });
    },

    resize: function(event, ui) {
        var that = $(this).resizable( "instance" ),
            o = that.options,
            os = that.originalSize,
            op = that.originalPosition,
            delta = {
                height: (that.size.height - os.height) || 0,
                width: (that.size.width - os.width) || 0,
                top: (that.position.top - op.top) || 0,
                left: (that.position.left - op.left) || 0
            };

            $(o.alsoResizeKeepAspectRatio).each(function() {
                var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
                    css = el.parents(ui.originalElement[0]).length ?
                            [ "width", "height" ] :
                            [ "width", "height", "top", "left" ];

                $.each(css, function(i, prop) {
                    console.log("alsoResizeKeepAspectRatio i:"+i+" prop: "+prop+" h:"+el.height()+" w:"+el.width());
                    var deltaAR = 0;
                    if(prop == "width"){
                        deltaAR = delta[prop]
                    }
                    else // height --> This is the change in comparison to original
                    {
                        deltaAR=delta["width"]*el.height()/el.width();
                    }
                    var sum = (start[prop] || 0) + (deltaAR || 0);
                    if (sum && sum >= 0) {
                        style[prop] = sum || null;
                    }
                });

//              $.each(css, function(i, prop) {
//                      var sum = (start[prop] || 0) - (delta[prop] || 0);
//                      if (sum && sum >= 0) {
//                          style[prop] = sum || null;
//                      }
//                  });

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

    stop: function() {
        $(this).removeData("resizable-alsoresize");
    }
});