• 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({
                         w - diffX + 'px',
                        left: l + Math.min(diffX, w) + 'px'
                    });
                    e.preventDefault();
                };
                right = function(e){
                    var diffX = e.clientX - clientX;
                    $target.css({
                         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',
                         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',
                         w + diffX + 'px'
                    });
                    e.preventDefault();
                };
                downLeft = function(e){
                    var diffX = e.clientX - clientX,
                        diffY = e.clientY - clientY;
                    $target.css({
                         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({
                         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({
                         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({
                         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',
                         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',
                         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({
                         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({
                         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,谢谢!

  • 相关阅读:
    怎样解决:未找到路径“……”的控制器或该控制器未实现 IController?
    错误:org.springframework.jdbc.support.SQLErrorCodesFactory
    springbean的生命周期
    注解到处excel
    nio读取文件,输出文件
    AtomicReference
    唯一id
    hashmap1.7的死锁模拟
    数组模拟stack
    环形队列
  • 原文地址:https://www.cnblogs.com/yangjunhua/p/3570417.html
Copyright © 2020-2023  润新知