JavaScript简易缩放程序

一、前言:

上一篇随笔中已经把拖动程序完成了,这篇主要把缩放程序完成,后面合并后可以做成一个图片裁剪的功能

简易缩放程序DEMO:http://jsfiddle.net/UN99R/
限制缩放程序DEMO:http://jsfiddle.net/kHWQZ/


二、设计思路:

1、在一个可以缩放元素中,共有8个触发点(上、下、左、右、左上、右上、左下、右下),首先分别设置好它们的CSS属性cursor值。

2、同拖放程序一样,在触发点上绑定鼠标按下事件,在文档(document)上绑定鼠标移动、弹起事件处理程序,在移动事件中,完成拖放元素css的操作,
在鼠标弹起事件中,解绑移动事件处理程序。

主要难点:在于如何处理拖放元素的CSS属性

 

三、源码实现细节:

在8个触发点的事件处理程序中,diffX, diffY 分别获取的是鼠标在移动与按下过程时指针的差值

var diffX = e.clientX - clientX, // 负数代表向左移动,反之向右

    diffY = e.clientY - clientY; // 负数代表想上移动,反之向下


在鼠标按下事件处理中,w, h, l, t 分别记录的是拖放元素的width, height, left, top 属性值,下面讲一下鼠标移动处理程序
举一个示例:

up事件程序代码:

up = function(e){

    var diffY = e.clientY - clientY;

    $target.css({

        height: h - diffY + 'px',

        top: t + Math.min(diffY, h) + 'px'

    });

    e.preventDefault();

};

1、在up事件程序中,拖放元素变动的是height, top属性;

2、如果鼠标向上移动,diffY为负数,而height应增,因此 height = h - diffY, top则相反,top = t + diffY;

3、反之,diffY为正数,而height应减,因此 height = h - diffY, top = t + diffY;

4、为了让top值不为负数,top = t + Math.min(diffY, h);

最后阻止默认浏览器事件,避免鼠标拖动过程中出现禁止icon

处理完up事件后,其他down, left, right事件处理同理,而后 upLeft, upRight, downLeft, downRight 这些事件处理都是在叠加前四个事件处理就行了

 

主程序代码:

jQuery.fn.extend({

    /**

     *   Autor: 博客园华子yjh 2014/02/26

     */

    resize: function(options) {

        var controlSelector = '.cursor-north, .cursor-south, .cursor-west, .cursor-east,' +

                              '.cursor-north-west, .cursor-north-east, .cursor-south-west, .cursor-south-east';

        $(this).each(function(){

            var 

                // 上、下、左、右、左上、右上、左下、右下 八个点的鼠标拖动时的事件处理程序

                up, down, left, right, upLeft, upRight, downLeft, downRight,



                // 鼠标拖动时的事件处理程序

                handleEvent,



                // 记录鼠标按下时鼠标的位置

                clientX, clientY,



                // 记录鼠标按下时元素的大小及位置

                w, h, l, t,



                // 目标元素

                $target = $(this), self = this;



            up = function(e){

                var diffY = e.clientY - clientY;

                $target.css({

                    height: h - diffY + 'px',

                    top: t + Math.min(diffY, h) + 'px'

                });

                e.preventDefault();

            };

            down = function(e){

                var diffY = e.clientY - clientY;

                $target.css({

                    height: h + diffY + 'px'

                });

                e.preventDefault();

            };

            left = function(e){

                var diffX = e.clientX - clientX;

                $target.css({

                    width: w - diffX + 'px',

                    left: l + Math.min(diffX, w) + 'px'

                });

                e.preventDefault();

            };

            right = function(e){

                var diffX = e.clientX - clientX;

                $target.css({

                    width: w + diffX + 'px'

                });

                e.preventDefault();

            };

            upLeft = function(e){

                var diffX = e.clientX - clientX,

                    diffY = e.clientY - clientY;

                $target.css({

                    height: h - diffY + 'px',

                    top: t + Math.min(diffY, h) + 'px',

                    width: w - diffX + 'px',

                    left: l + Math.min(diffX, w) + 'px'

                });

                e.preventDefault();

            };

            upRight = function(e){

                var diffX = e.clientX - clientX,

                    diffY = e.clientY - clientY;

                $target.css({

                    height: h - diffY + 'px',

                    top: t + Math.min(diffY, h) + 'px',

                    width: w + diffX + 'px'

                });

                e.preventDefault();

            };

            downLeft = function(e){

                var diffX = e.clientX - clientX,

                    diffY = e.clientY - clientY;

                $target.css({

                    width: w - diffX + 'px',

                    left: l + Math.min(diffX, w) + 'px',

                    height: h + diffY + 'px'

                });

                e.preventDefault();

            };

            downRight = function(e){

                var diffX = e.clientX - clientX,

                    diffY = e.clientY - clientY;

                $target.css({

                    width: w + diffX + 'px',

                    height: h + diffY + 'px'

                });

                e.preventDefault();

            };            



            $target.delegate(controlSelector, 'mousedown', function(e){

                var className = $(this).attr('class');

                clientX = e.clientX;

                clientY = e.clientY;



                w = $target.width(),

                h = $target.height(),

                l = $target.get(0).offsetLeft,

                t = $target.get(0).offsetTop;



                // 根据触发元素的className选择要触发的事件处理程序

                switch (className) {

                    case 'cursor-north':

                        handleEvent = up;

                        break;



                    case 'cursor-south':

                        handleEvent = down;

                        break;



                    case 'cursor-west':

                        handleEvent = left;

                        break;



                    case 'cursor-east':

                        handleEvent = right;

                        break;



                    case 'cursor-north-west':

                        handleEvent = upLeft;

                        break;



                    case 'cursor-north-east':

                        handleEvent = upRight;

                        break;



                    case 'cursor-south-west':

                        handleEvent = downLeft;

                        break;



                    case 'cursor-south-east':

                        handleEvent = downRight;

                        break;



                    default: 

                        break;

                }



                $(document)

                .bind('mousemove', handleEvent)

                .bind('mouseup', function(){

                    $(document).unbind('mousemove', handleEvent);

                    $target.removeData('data-resize'); // 移除标志

                });

                $target.data('data-resize', true); // 缓存标志

            });

        });

        return this;

    }

});

 

带限制范围缩放代码:

jQuery.fn.extend({

    /**

     *   Autor: 博客园华子yjh 2014/02/26

     */

    resize: function(options) {

        var defaultOptions, boundaryElem, limitObj, controlSelector;

        controlSelector = '.cursor-north, .cursor-south, .cursor-west, .cursor-east, .cursor-north-west, .cursor-north-east, .cursor-south-west, .cursor-south-east';    

        defaultOptions = { // 默认配置项

            boundaryElem: 'body' // 边界容器

        };

        options = jQuery.extend( defaultOptions, options || {} );

        boundaryElem = $(options.boundaryElem).get(0);

        limitObj = {

            _left: boundaryElem.offsetLeft,

            _top: boundaryElem.offsetTop,

            _right: boundaryElem.offsetLeft + boundaryElem.clientWidth,

            _bottom: boundaryElem.offsetTop + boundaryElem.clientHeight

        };



        $(this).each(function(){

            var up, down, left, right, upLeft, upRight, downLeft, downRight,

                clientX, clientY, w, h, l, t,

                $target = $(this), self = this,

                handleEvent = function(){};



            up = function(e){

                var diffY = e.clientY - clientY;

                $target.css({

                    height: h + Math.min(0 - diffY, t) + 'px',

                    top: Math.max(t + Math.min(diffY, h), 0) + 'px'

                });

                e.preventDefault();

            };

            down = function(e){

                var diffY = e.clientY - clientY;

                $target.css({

                    height: h + Math.min(diffY, limitObj._bottom - limitObj._top - t - h) + 'px'

                });

                e.preventDefault();

            };

            left = function(e){

                var diffX = e.clientX - clientX;

                $target.css({

                    width: w  + Math.min(0- diffX, l) + 'px',

                    left: Math.max(l + Math.min(diffX, w), 0) + 'px'

                });

                e.preventDefault();

            };

            right = function(e){

                var diffX = e.clientX - clientX;

                $target.css({

                    width: w + Math.min(diffX, limitObj._right - limitObj._left - l - w) + 'px'

                });

                e.preventDefault();

            };

            upLeft = function(e){

                var diffX = e.clientX - clientX,

                    diffY = e.clientY - clientY;

                $target.css({

                    height: h + Math.min(0 - diffY, t) + 'px',

                    top: Math.max(t + Math.min(diffY, h), 0) + 'px',

                    width: w  + Math.min(0- diffX, l) + 'px',

                    left: Math.max(l + Math.min(diffX, w), 0) + 'px'

                });

                e.preventDefault();

            };

            upRight = function(e){

                var diffX = e.clientX - clientX,

                    diffY = e.clientY - clientY;

                $target.css({

                    height: h + Math.min(0 - diffY, t) + 'px',

                    top: Math.max(t + Math.min(diffY, h), 0) + 'px',

                    width: w + Math.min(diffX, limitObj._right - limitObj._left - l - w) + 'px'

                });

                e.preventDefault();

            };

            downLeft = function(e){

                var diffX = e.clientX - clientX,

                    diffY = e.clientY - clientY;

                $target.css({

                    width: w  + Math.min(0- diffX, l) + 'px',

                    left: Math.max(l + Math.min(diffX, w), 0) + 'px',

                    height: h + Math.min(diffY, limitObj._bottom - limitObj._top - t - h) + 'px'

                });

                e.preventDefault();

            };

            downRight = function(e){

                var diffX = e.clientX - clientX,

                    diffY = e.clientY - clientY;

                $target.css({

                    width: w + Math.min(diffX, limitObj._right - limitObj._left - l - w) + 'px',

                    height: h + Math.min(diffY, limitObj._bottom - limitObj._top - t - h) + 'px'

                });

                e.preventDefault();

            };            

            

            $target.delegate(controlSelector, 'mousedown', function(e){

                var className = $(this).attr('class');

                clientX = e.clientX;

                clientY = e.clientY;



                w = $target.width(),

                h = $target.height(),

                l = $target.get(0).offsetLeft,

                t = $target.get(0).offsetTop;



                switch (className) {

                    case 'cursor-north':

                        handleEvent = up;

                        break;



                    case 'cursor-south':

                        handleEvent = down;

                        break;



                    case 'cursor-west':

                        handleEvent = left;

                        break;



                    case 'cursor-east':

                        handleEvent = right;

                        break;



                    case 'cursor-north-west':

                        handleEvent = upLeft;

                        break;



                    case 'cursor-north-east':

                        handleEvent = upRight;

                        break;



                    case 'cursor-south-west':

                        handleEvent = downLeft;

                        break;



                    case 'cursor-south-east':

                        handleEvent = downRight;

                        break;



                    default: 

                        break;

                }

                $(document)

                .bind('mousemove', handleEvent)

                .bind('mouseup', function(){

                    $(document).unbind('mousemove', handleEvent);

                    $target.removeData('data-resize'); // 移除标志

                });

                $target.data('data-resize', true); // 缓存标志

            })            

        });

        return this;

    }

});
View Code

 

PS: 如有描述错误,请帮忙指正,如果你们有不明白的地方也可以发邮件给我,

  如需转载,请附上本文地址及出处:博客园华子yjh,谢谢!

你可能感兴趣的:(JavaScript)