ADS图像缩放与剪裁(只是完成了前台的功能,传送数据到后台的功能待完成)

HTML Code:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <meta charset="utf-8">
    <title>Image Editor Test Pages</title>
    <style>
        ul{ list-style: none; }
        li {  400px; }
        form {
            margin-bottom: 1em;
            padding-bottom: 1em;
            border-bottom: 2px solid gray;
        }
        form div {
            clear: both;
        }

        img {
            margin: 0;
            border: 1px solid gray;
            padding: 4px;
             23%;
            float: left;
            clear: none;
        }

        fieldset {
            float: right;
             60%;
            margin-bottom: 1em;
            border: 1px dotted gray;
        }

        legend {
            font-size: 0.95em;
        }

        label {
            display: block;
            font-weight: bold;
        }

        .buttons {
            text-align: center;
        }

        form.ADSImageEditorModified {
            margin: 10px;
            padding: 0;
            border: 0;
        }
        form.ADSImageEditorModified * {
            position: absolute;
            left: -2000px;
        }

        form.ADSImageEditorModified img {
            position: inherit;
            left: auto;
        }


        li {
            list-style:none;
            margin:30px;
            overflow:hidden;
            zoom:1;
        }
        li img {
            float:left;
            270px;
            height:400px;
            display:inline;
            margin-right:30px;
        }
    </style>
</head>
<body>
<h1>Edit Your Images </h1>
<ul>
    <li>
        <form method="post" action="" class="ADSImageEditor">
            <img id="mintImage" src="images/mint.jpg" alt="">
            <fieldset>
                <legend>New Size</legend>
                <div>
                    <label for="newWidth">Width</label>
                    <input id="newWidth" name="newWidth" type="text">
                </div>
                <div>
                    <label for="newHeight">Height</label>
                    <input id="newHeight" name="newHeight" type="text">
                    <p>The width and height applies to the original uncropped image</p>
                </div>
            </fieldset>
            <fieldset>
                <legend>Trim Edges</legend>
                <div>
                    <label for="cropTop">Top</label>
                    <input id="cropTop" name="cropTop" type="text">
                </div>
                <div>
                    <label for="cropRight">Rigt</label>
                    <input name="cropRight" id="cropRight" type="text">
                </div>
                <div>
                    <label for="cropLeft">Left</label>
                    <input name="cropLeft" id="cropLeft" type="text">
                </div>
            </fieldset>
            <div class="buttons">
                <input value="Apply" type="submit">
                <input value="Reset" type="reset">
            </div>
        </form>
    </li>
    <li>
        <form action=""  class="ADSImageEditor">
            <img id="babyImage" src="images/baby.jpg" alt="">
            <fieldset>
                <legend>New Size</legend>
                <div>
                    <label for="newWidth2">Width</label>
                    <input id="newWidth2" name="newWidth" type="text">
                </div>
                <div>
                    <label for="newHeight2">Height</label>
                    <input name="newHeight" id="newHeight2" type="text">
                    <p>The width and height applies to the original uncropped image</p>
                </div>
            </fieldset>
            <fieldset>
                <legend>Trim Edges</legend>
                <div>
                    <label for="cropTop2">Top</label>
                    <input id="cropTop2" name="cropTop" type="text">
                </div>
                <div>
                    <label for="cropRight2">Rigt</label>
                    <input name="cropRight" id="cropRight2" type="text">
                </div>
                <div>
                    <label for="cropLeft2">Left</label>
                    <input name="cropLeft" id="cropLeft2" type="text">
                </div>
            </fieldset>
            <div class="buttons">
                <input value="Apply" type="submit">
                <input value="Reset" type="reset">
            </div>
        </form>
    </li>
</ul>
<!--
<script src="../ADS.js"></script>
<script src="../myLogger.js"></script>
<script src="imageEditor.js"></script>
-->
<script src="imageEditor-test.js"></script>
<script>

</script>
</body>
</html>


JS Code:
/**
 * mageEditor-test.js
 * User: ldp
 * Date: 12-12-22
 * project: 图像缩放与剪裁
 */

(function () {
    if (!window.ADS) {
        window.ADS = {};
    }

    function addEvent(node, type, listener) {
        if (node.addEventListener) {
            node.addEventListener(type, listener, false);
            return true;
        } else if (node.attachEvent) {
            node['e' + type + listener] = listener;
            node[type + listener] = function () {
                node['e' + type + listener](window.event);
            };
            node.attachEvent('on' + type, node[type + listener]);
            return true;
        } else {
            return false;
        }
    }

    window.ADS.addEvent = addEvent;

    function addLoadEvent(loadEvent, waitForImages) {
        //如果等待标记是true则使用常规的添加事件的方法
        if (waitForImages) {
            return addEvent(window, 'load', loadEvent);
        }

        //否则使用一些不同的方式包装loadEvent()方法
        //以便为this关键字制定正确的内容,同时确定
        //事件不会被执行两次
        var init = function () {
            //如果这个函数已经被调用过了则返回
            if (arguments.callee.done) {
                return;
            }

            //标记这个函数以便检测它是否运行过
            arguments.callee.done = true;

            //在document的环境中运行载入事件
            loadEvent.apply(document, arguments);
        };

        //为DOMContentLoaded事件注册事件侦听器
        if (document.addEventListener) {
            document.addEventListener('DOMContentLoaded', init, false);
        }

        //对于safari,使用setInterval()函数检测
        //document是否载入完成
        if (/WebKit/i.test(navigator.userAgent)) {
            var _timer = setInterval(function () {
                if (/loaded|complete/.test(document.readyState)) {
                    clearInterval(_timer);
                    init();
                }
            }, 10);
        }

        //对于IE(使用条件注释)
        //附加一个在载入过程最后执行的脚本
        //并检测该脚本是否载入完成
        /*@cc_on @*/
        /*@if (@_win32)
         document.write("<script id=_ie_onload defer src=javascript:void(0)><\/script>");
         var script = document.getElementById('_ie_onload');
         script.onreadystatechange = function(){
         if(this.readyState === 'complete'){
         init();
         }
         };
         /*@end @*/
        return true;
    }

    window.ADS.addLoadEvent = addLoadEvent;

    function removeEvent(node, type, listener) {
        if (node.removeEventListener) {
            node.removeEventListener(type, listener, false);
            return true;
        } else if (node.detachEvent) {
            node.detachEvent('on' + type, node[type + listener]);
            node[type + listener] = null;
            return true;
        }
        return false;
    }

    window.ADS.removeEvent = removeEvent;

    function getEvent(event) {
        return event || window.event;
    }

    window.ADS.getEvent = getEvent;

    function getPointerPositionInDocument(event) {
        event = event || getEvent(event);
        var x = event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
        var y = event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
        return {
            x: x,
            y: y
        };
    }

    window.ADS.getPointerPositionInDocument = getPointerPositionInDocument;

    function stopPropagation(event) {
        event = event || getEvent(event);
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    }

    window.ADS.stopPropagation = stopPropagation;

    function preventDefault(event) {
        event = event || getEvent(event);
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    }

    window.ADS.preventDefault = preventDefault;

    function getElementsByClassName(searchClass, node, tag) {
        if (document.getElementsByClassName) {
            var nodes = (node || document).getElementsByClassName(searchClass),
                result = nodes;
            if (tag !== undefined) {
                result = [];
                for (var i = 0; node = nodes[i]; i++) {
                    if (tag !== '*' && node.tagName.toLowerCase() === tag.toLowerCase()) {
                        result.push(node);
                    } else if (tag === '*') {
                        return nodes;
                    }
                }
            }
            return result;
        } else {
            node = node || document;
            tag = tag || '*';
            var classes = searchClass.split(' '),
                elements = node.getElementsByTagName(tag),
                patterns = [],
                returnElements = [],
                current,
                match;
            var i = classes.length;
            while (--i >= 0) {
                patterns.push(new RegExp('(^|\\s)' + classes[i] + '(\\s|$)'));
            }
            var j = elements.length;
            while (--j >= 0) {
                current = elements[j];
                match = false;
                for (var k = 0, kl = patterns.length; k < kl; k++) {
                    match = patterns[k].test(current.className);
                    if (!match) break;
                }
                if (match) {
                    returnElements.push(current);
                }
            }
            return returnElements;
        }
    }

    window.ADS.getElementsByClassName = getElementsByClassName;

    function getWinSize() {
        var de = document.documentElement;
        return {
             (window.innerWidth || (de && de.clientWidth) || document.body.clientWidth),
            height: (window.innerHeight || (de && de.clientHeight) || document.bodu.clientHeight)
        };
    }

    window.ADS.getWinSize = getWinSize;

    function setStyleById(element, styles) {
        for (var prop in styles) {
            if (!styles.hasOwnProperty(prop)) {
                continue;
            }
            if (element.style.setProperty) {
                element.style.setProperty(uncamelize(prop, '-'), styles[prop], null);
            } else {
                element.style[camelize(prop)] = styles[prop];
            }
        }
        return true;
    }

    window.ADS.setStyle = setStyleById;
    window.ADS.setStyleById = setStyleById;

    function camelize(s) {
        return s.replace(/-(\w)/g, function (strMatch, p1) {    //strMatch为正则匹配的字符
            //p1为\w匹配的一个字符
            return p1.toUpperCase();
        });
    }

    window.ADS.camelize = camelize;

    function uncamelize(property, splitChar) {
        return property.replace(/([a-z])([A-Z])/, '$1' + splitChar + '$2').toLowerCase();
    }

    window.ADS.uncamelize = uncamelize;


})();

/*------------- ImageEditor   ------------------*/
(function () {
    /**
     * 返回一个对象,以所提供元素的宽度,高度
     * 顶部边距和左侧边距作为属性
     * @param {Element} e
     * @return {Object}
     */
    function getDimensions(e) {
        return {
            top: e.offsetTop,
            left: e.offsetLeft,
             e.offsetWidth,
            height: e.offsetHeight
        };
    }

    /**
     * 设置并自动匹配px单位的css属性
     * @param {Element} e 元素
     * @param {Object} dim 包含css属性和值的对象
     * @param {Boolean} updateMsg 是否显示尺寸信息
     */
    function setNumericStyle(e, dim, updateMsg) {
        updateMsg = updateMsg || false;
        var style = {};
        for (var i in dim) {
            if (!dim.hasOwnProperty(i)) {
                continue;
            }
            style[i] = (dim[i] || '0') + 'px';
        }
        ADS.setStyle(e, style);
        if (updateMsg) {
            ImageEditor.elements.cropSizeDisplay.firstChild.nodeValue = dim.width + ' x ' + dim.height;
        }
    }

    /**
     * 构造器
     */
    function ImageEditor() {
    }

    ImageEditor.info = {
        resizeCropArea: false,      // 当为true时启动剪裁区域拖动,否则只是缩放
        pointerStart: null,     // 记录开始时的指针x和y值
        resizeeStart: null,     // 记录开始时黑色半透明层下的图片的偏移属性
        cropAreaStart: null,        // 记录开始时剪裁区域的偏移属性
        imgSrc: null        // 图片地址
    };

    ImageEditor.elements = {
        backdrop: null,     // 背景幕
        editor: null,       // 编辑器
        resizee: null,      // 图片
        resizeeCover: null,     // 半透明黑色背景层
        resizeHandle: null,     // 图片缩放手柄
        cropArea: null,     // 裁剪区域层
        resizeeClone: null,     // 裁剪区域的明亮图片
        cropSizeDisplay: null,      // 包含裁剪尺寸信息的元素
        cropResizeHandle: null,     // 裁剪缩放手柄
        saveHandle: null,       // 保存手柄
        cancelHandle: null      // 取消手柄
    };

    // 这个方法会按照需要注册事件及修改DOM
    // 它会在window载入时自动运行
    ImageEditor.load = function (event) {
        // 取得页面中所有带ADSImageEditor类名的表单元素
        var forms = ADS.getElementsByClassName('ADSImageEditor', document, 'form');
        // 在符合条件的表单中查找图像
        for (var i = 0, len = forms.length; i < len; i++) {
            // 查找表单中的图像
            var images = forms[i].getElementsByTagName('img');
            if (!images[0]) {
                // 这个表单中不包含图像,跳过
                continue;
            }

            // 为图像添加imageEditor.imgeClick事件
            ADS.addEvent(images[0], 'click', ImageEditor.imageClick);

            // 修改类名以便CSS按照需要修改其样式
            forms[i].className += ' ADSImageEditorModified';
        }
    };

    ImageEditor.unload = function (event) {
        // 移除编辑及背景幕(backdrop)
        document.body.removeChild(ImageEditor.elements.backdrop);
        document.body.removeChild(ImageEditor.elements.editor);
    };

    ImageEditor.imageClick = function (event) {
        // 创建新的js Image对象
        // 以便确定图像的宽度和高度
        var image = new Image();
        // this引用被单击的图像元素
        image.src = ImageEditor.info.imgSrc = this.src;

        // 为放置背景幕和居中编辑器而取得页面大小
        var windowSize = ADS.getWinSize();

        /*
         Build the DOM structure and append it to the document
         This will reproduce the following markup with size based
         around the clicked image's size:

         <div><!-- backdrop --></div>
         <div>
         <!-- editor -->
         <div><!-- resize handle --></div>
         <img src="/path/to/image.jpg">
         <div><!-- translucent cover --></div>
         <div>
         <!-- crop area -->
         <img src="/path/to/image.jpg">
         <div><!-- crop size display --></div>
         <div><!-- crop handle --></div>
         <div><!-- save handle --></div>
         <div><!-- cancel handle --></div>
         </div>
         </div>
         */

        // 创建背景幕div,并使其撑满整个页面
        var backdrop = document.createElement('div');
        backdrop.id = 'backdrop';
        ImageEditor.elements.backdrop = backdrop;
        ADS.setStyle(backdrop, {
            'width': '100%',
            'height': '100%',
            'position': 'absolute',
            'background-color': 'black',
            'opacity': 0.8,
            'filter': 'alpha(opacity=80)',
            'z-index': 10000
        });
        setNumericStyle(backdrop, {
            'left': 0,
            'top': 0
        });

        // 创建编辑器div以包含编辑工具的GUI
        var editor = document.createElement('div');
        editor.id = 'editor';
        ImageEditor.elements.editor = editor;
        ADS.setStyle(editor, {
            'position': 'absolute',
            'z-index': 10001
        });
        setNumericStyle(editor, {
            'left': Math.ceil((windowSize.width - image.width) / 2),
            'top': Math.ceil((windowSize.height - image.height) / 2),
            'width': image.width,
            'height': image.height
        });

        // 创建缩放手柄
        var resizeHandle = document.createElement('div');
        resizeHandle.id = 'resizeHandle';
        ImageEditor.elements.resizeHandle = resizeHandle;
        ADS.setStyle(resizeHandle, {
            'position': 'absolute',
            'background': 'url(interface/handles.gif) no-repeat 0 0'
        });
        setNumericStyle(resizeHandle, {
            'right': -10,
            'bottom': -10,
            'width': 28,
            'height': 28
        });

        // 创建可缩放的图像
        var resizee = document.createElement('img');
        resizee.id = 'resizee';
        ImageEditor.elements.resizee = resizee;
        resizee.src = ImageEditor.info.imgSrc;
        ADS.setStyle(resizee, {
            'position': 'absolute',
            'margin': 0,
            'padding': 0,
            'border': 0
        });
        setNumericStyle(resizee, {
            'left': 0,
            'top': 0,
            'width': image.width,
            'height': image.height
        });

        // 创建半透明的蒙板(cover)
        var resizeeCover = document.createElement('div');
        resizeeCover.id = 'resizeeCover';
        ImageEditor.elements.resizeeCover = resizeeCover;
        ADS.setStyle(resizeeCover, {
            'position': 'absolute',
            'background-color': 'black',
            'opacity': 0.8,
            'filter': 'alpha(opacity=80)'
        });
        setNumericStyle(resizeeCover, {
            'left': 0,
            'top': 0,
            'width': image.width,
            'height': image.height
        });

        // 创建裁剪大小显示区域
        var cropSizeDisplay = document.createElement('span');
        cropSizeDisplay.id = 'cropSizeDisplay';
        ImageEditor.elements.cropSizeDisplay = cropSizeDisplay;
        ADS.setStyle(cropSizeDisplay, {
            'position': 'absolute',
            'background-color': 'black',
            'color': 'white'
        });
        setNumericStyle(cropSizeDisplay, {
            'top': 0,
            'left': 0,
            'padding': 4,
            'font-size': 12,
            'line-height': 14
        });
        cropSizeDisplay.appendChild(
            document.createTextNode('size:')
        );

        // 创建裁剪区域容器
        var cropArea = document.createElement('div');
        cropArea.id = 'cropArea';
        ImageEditor.elements.cropArea = cropArea;
        ADS.setStyle(cropArea, {
            'position': 'absolute',
            'overflow': 'hidden'
        });
        setNumericStyle(cropArea, {
            'left': 0,
            'Top': 0,
            'width': image.width,
            'height': image.height
        }, true);

        // 在剪裁区域中创建图像的副本
        var resizeeClone = resizee.cloneNode(false);
        resizeeClone.id = 'resizeeClone';
        ImageEditor.elements.resizeeClone = resizeeClone;

        // 创建裁剪缩放手柄
        var cropResizeHandle = document.createElement('a');
        cropResizeHandle.id = 'cropResizeHandle';
        cropResizeHandle.href = 'javascript:void(0);';
        ImageEditor.elements.cropResizeHandle = cropResizeHandle;
        ADS.setStyle(cropResizeHandle, {
            'position': 'absolute',
            'background': 'url(interface/handles.gif) no-repeat 0 0'
        });
        setNumericStyle(cropResizeHandle, {
            'right': 0,
            'bottom': 0,
            'width': 18,
            'height': 18
        });

        // 创建保存手柄
        var saveHandle = document.createElement('a');
        saveHandle.id = 'saveHandle';
        saveHandle.href = 'javascript:void(0);';
        ImageEditor.elements.saveHandle = saveHandle;
        ADS.setStyle(saveHandle, {
            'position': 'absolute',
            'background': 'url(interface/handles.gif) no-repeat -40px 0'
        });
        setNumericStyle(saveHandle, {
            'left': 0,
            'bottom': 0,
            'width': 16,
            'height': 18
        });

        // 创建取消缩放手柄
        var cancelHandle = document.createElement('a');
        cancelHandle.id = 'cancelHandle';
        ImageEditor.elements.cancelHandle = cancelHandle;
        ADS.setStyle(cancelHandle, {
            'position': 'absolute',
            'background': 'url(interface/handles.gif) no-repeat -29px -11px',
            'cursor': 'pointer'
        });
        setNumericStyle(cancelHandle, {
            'right': 0,
            'top': 0,
            'width': 18,
            'height': 16
        });

        // 添加到DOM文档里
        document.body.appendChild(backdrop);
        document.body.appendChild(editor);
        editor.appendChild(resizeHandle);
        editor.appendChild(resizee);
        editor.appendChild(resizeeCover);
        editor.appendChild(cropArea);
        cropArea.appendChild(resizeeClone);
        cropArea.appendChild(cropSizeDisplay);
        cropArea.appendChild(cropResizeHandle);
        cropArea.appendChild(saveHandle);
        cropArea.appendChild(cancelHandle);

        // 向DOM元素添加事件

        // 缩放手柄的翻转图
        ADS.addEvent(resizeHandle, 'mouseover', function (event) {
            ADS.setStyle(this, {
                'background-position': '0 -29px'
            });
        });
        ADS.addEvent(resizeHandle, 'mouseout', function (event) {
            ADS.setStyle(this, {
                'background-position': '0 0'
            });
        });

        // 裁剪手柄的翻转图
        ADS.addEvent(cropResizeHandle, 'mouseover', function (event) {
            ADS.setStyle(this, {
                'background-position': '0px -29px'
            });
        });
        ADS.addEvent(cropResizeHandle, 'mouseout', function (event) {
            ADS.setStyle(this, {
                'background-position': '0px 0px'
            });
        });

        // 保存手柄的翻转图
        ADS.addEvent(saveHandle, 'mouseover', function (event) {
            ADS.setStyle(this, {
                'background-position': '-40px -29px'
            });
        });
        ADS.addEvent(saveHandle, 'mouseout', function (event) {
            ADS.setStyle(this, {
                'background-position': '-40px 0px'
            });
        });

        // 取消手柄的翻转图
        ADS.addEvent(cancelHandle, 'mouseover', function () {
            ADS.setStyle(this, {
                'background-position': '-29px -40px'
            });
        });
        ADS.addEvent(cancelHandle, 'mouseout', function () {
            ADS.setStyle(this, {
                'background-position': '-29px -11px'
            });
        });


        // 启动图像缩放事件流
        ADS.addEvent(resizeHandle, 'mousedown', ImageEditor.resizeMouseDown);

        // 启动裁剪区域拖动事件流
        ADS.addEvent(cropArea, 'mousedown', ImageEditor.cropMouseDown);

        // 启动裁剪区域缩放事件流
        ADS.addEvent(cropResizeHandle, 'mousedown', function (event) {
            // 因为会触发上面的事件,设置标记表明启动缩放
            ImageEditor.info.resizeCropArea = true;
        });

        // 防止保存手柄启动裁剪拖动事件流
        ADS.addEvent(saveHandle, 'mousedown', function (event) {
            ADS.stopPropagation(event);
        });
        // 防止取消手柄启动裁剪拖动事件流
        ADS.addEvent(cancelHandle, 'mousedown', function (event) {
            ADS.stopPropagation(event);
        });

        // 在单击保存手柄或双击
        // 裁剪区域时保存图像
        ADS.addEvent(saveHandle, 'click', ImageEditor.saveClick);
        ADS.addEvent(cropArea, 'dblclick', ImageEditor.saveClick);
        // 在单击时取消改变
        ADS.addEvent(cancelHandle, 'click', ImageEditor.cancelClick);

        // 如果窗口大小改变则调正背景幕的大小
        ADS.addEvent(window, 'resize', function (event) {
            var windowSize = ADS.getWinSize();
            setNumericStyle(backdrop, {
                'left': 0,
                'top': 0,
                'width': windowSize.width,
                'height': windowSize.height
            });
        });
    };

    ImageEditor.resizeMouseDown = function (event) {
        // 保存当前位置的尺寸
        ImageEditor.info.pointerStart = ADS.getPointerPositionInDocument(event);
        ImageEditor.info.resizeeStart = getDimensions(
            ImageEditor.elements.resizee
        );
        ImageEditor.info.cropAreaStart = getDimensions(
            ImageEditor.elements.cropArea
        );

        // 添加其余事件以启用拖动
        ADS.addEvent(document, 'mousemove', ImageEditor.resizeMouseMove);
        ADS.addEvent(document, 'mouseup', ImageEditor.resizeMouseUp);

        // 停止事件流
        ADS.stopPropagation(event);
        ADS.preventDefault(event);
    };

    ImageEditor.resizeMouseMove = function (event) {
        var info = ImageEditor.info;

        // 取得当前鼠标指针所在位置
        var pointer = ADS.getPointerPositionInDocument(event);

        // 基于鼠标指针来计算
        // 图像信的宽度和高度
        var width = (info.resizeeStart.width + pointer.x - info.pointerStart.x),
            height = (info.resizeeStart.height + pointer.y - info.pointerStart.y);

        // 最小尺寸是42平方像素
        if (width < 42) {
            width = 42;
        }
        if (height < 42) {
            height = 42;
        }

        // 计算基于原始值的百分比
        var widthPercent = (width / info.resizeeStart.width),
            heightPercent = (height / info.resizeeStart.height);

        // 如果按下了Shift键,则按比例缩放
        if (ADS.getEvent(event).shiftKey) {
            if (widthPercent > heightPercent) {
                heightPercent = widthPercent;
                height = Math.ceil(info.resizeeStart.height * heightPercent);
            } else {
                widthPercent = heightPercent;
                width = Math.ceil(info.resizeeStart.width * widthPercent);
            }
        }

        // 计算裁剪区域的新尺寸
        var cropWidth = Math.ceil(info.cropAreaStart.width * widthPercent),
            cropHeight = Math.ceil(info.cropAreaStart.height * heightPercent),
            cropLeft = Math.ceil(info.cropAreaStart.left * widthPercent),
            cropTop = Math.ceil(info.cropAreaStart.top * heightPercent);

        // 缩放对象
        setNumericStyle(
            ImageEditor.elements.editor,
            {
                'width': width,
                'height': height
            }
        );
        setNumericStyle(
            ImageEditor.elements.resizee,
            {
                'width': width,
                'height': height
            }
        );
        setNumericStyle(
            ImageEditor.elements.resizeeCover,
            {
                'width': width,
                'height': height
            }
        );
        setNumericStyle(
            ImageEditor.elements.resizeHandle,
            {
                'left': (width - 18),
                'top': (height - 18)
            }
        );
        setNumericStyle(
            ImageEditor.elements.cropArea,
            {
                'left': cropLeft,
                'top': cropTop,
                'width': cropWidth,
                'height': cropHeight
            },
            true
        );
        setNumericStyle(
            ImageEditor.elements.resizeeClone,
            {
                'left': (cropLeft * -1),
                'top': (cropTop * -1),
                'width': width,
                'height': height
            }
        );

        // 停止事件流
        ADS.stopPropagation(event);
        ADS.preventDefault(event);
    };

    ImageEditor.resizeMouseUp = function (event) {
        // 移除事件侦听器以停止拖动
        ADS.removeEvent(document, 'mousemove', ImageEditor.resizeMouseMove);
        ADS.removeEvent(document, 'mouseup', ImageEditor.resizeMouseUp);

        // 停止事件流
        ADS.stopPropagation(event);
        ADS.preventDefault(event);
    };

    // 裁剪区域上的mousedown事件侦听器
    ImageEditor.cropMouseDown = function (event) {
        // 包含缩放以限制裁剪区域的移动
        ImageEditor.info.pointerStart = ADS.getPointerPositionInDocument(event);
        ImageEditor.info.cropAreaStart = getDimensions(
            ImageEditor.elements.cropArea
        );

        // 包含缩放以限制裁剪区域的移动
        var resizeeStart = getDimensions(
            ImageEditor.elements.resizee
        );
        ImageEditor.info.maxX = resizeeStart.left + resizeeStart.width;
        ImageEditor.info.maxY = resizeeStart.top + resizeeStart.height;

        ADS.addEvent(document, 'mousemove', ImageEditor.cropMouseMove);
        ADS.addEvent(document, 'mouseup', ImageEditor.cropMouseUp);

        ADS.stopPropagation(event);
        ADS.preventDefault(event);
    };

    // 裁剪区域上的mousemove事件侦听器
    ImageEditor.cropMouseMove = function (event) {
        var pointer = ADS.getPointerPositionInDocument(event);

        if (ImageEditor.info.resizeCropArea) {
            // 缩放裁剪区域
            var width = (
                    ImageEditor.info.cropAreaStart.width
                        + pointer.x
                        - ImageEditor.info.pointerStart.x
                    ),
                height = (
                    ImageEditor.info.cropAreaStart.height
                        + pointer.y
                        - ImageEditor.info.pointerStart.y
                    );

            // 如果按下了Shift键,则按比例缩放
            // 计算基于原始值的百分比
            var widthPercent = (width / ImageEditor.info.cropAreaStart.width),
                heightPercent = (height / ImageEditor.info.cropAreaStart.height);

            if (ADS.getEvent(event).shiftKey) {
                if (widthPercent > heightPercent) {
                    heightPercent = widthPercent;
                    height = Math.ceil(ImageEditor.info.cropAreaStart.height * heightPercent);
                } else {
                    widthPercent = heightPercent;
                    width = Math.ceil(ImageEditor.info.cropAreaStart.width * widthPercent);
                }
            }

            // 检查新位置是否超出了边界
            if (ImageEditor.info.cropAreaStart.left + width > ImageEditor.info.maxX) {
                width = ImageEditor.info.maxX - ImageEditor.info.cropAreaStart.left;
            } else if (width < 36) {
                width = 36;
            }
            if (ImageEditor.info.cropAreaStart.top + height > ImageEditor.info.maxY) {
                height = ImageEditor.info.maxY - ImageEditor.info.cropAreaStart.top
            } else if (height < 36) {
                height = 36;
            }

            setNumericStyle(
                ImageEditor.elements.cropArea,
                {
                    'width': width,
                    'height': height
                },
                true
            );
        } else {
            // 移动裁剪区域
            var left = (
                    ImageEditor.info.cropAreaStart.left
                        + pointer.x
                        - ImageEditor.info.pointerStart.x
                    ),
                top = (
                    ImageEditor.info.cropAreaStart.top
                        + pointer.y
                        - ImageEditor.info.pointerStart.y
                    );

            // 检查新位置是否超出了边界
            // 如有必要则加以限制
            var maxLeft = ImageEditor.info.maxX - ImageEditor.info.cropAreaStart.width,
                maxTop = ImageEditor.info.maxY - ImageEditor.info.cropAreaStart.height;

            if (left < 0) {
                left = 0;
            } else if (left > maxLeft) {
                left = maxLeft;
            }
            if (top < 0) {
                top = 0;
            } else if (top > maxTop) {
                top = maxTop;
            }

            if (ADS.getEvent(event).shiftKey) {
                // 按住shiftKey水平移动
                    setNumericStyle(
                        ImageEditor.elements.cropArea,
                        {
                            'left': left
                        }
                    );
                    setNumericStyle(
                        ImageEditor.elements.resizeeClone,
                        {
                            'left': (left * -1)
                        }
                    );


            } else if(ADS.getEvent(event).ctrlKey){
                // 按住ctrl键垂直移动
                setNumericStyle(
                    ImageEditor.elements.cropArea,
                    {
                        'top': top
                    }
                );
                setNumericStyle(
                    ImageEditor.elements.resizeeClone,
                    {
                        'top': (top * -1)
                    }
                );
            } else {
                setNumericStyle(
                    ImageEditor.elements.cropArea,
                    {
                        'left': left,
                        'top': top
                    }
                );
                setNumericStyle(
                    ImageEditor.elements.resizeeClone,
                    {
                        'left': (left * -1),
                        'top': (top * -1)
                    }
                );
            }


        }
    };

    ImageEditor.cropMouseUp = function (event) {
        // 移除所有事件
        ImageEditor.info.resizeCropArea = false;

        ADS.removeEvent(document, 'mousemove', ImageEditor.cropMouseMove);
        ADS.addEvent(document, 'mouseup', ImageEditor.cropMouseUp);
    };

    ImageEditor.saveClick = function (event) {
        // 此处只是发出一个警告
        alert('This should save the information back to the server.');

        // 如果成功则卸载编辑器
        ImageEditor.unload(event);
    };

    ImageEditor.cancelClick = function (event) {
        if (confirm('Are you sure you want to cancel your changes?')) {
            // 卸载编辑器
            ImageEditor.unload(event);
        }
    };

    window.ADS.ImageEditor = ImageEditor;
})();

ADS.addLoadEvent(ADS.ImageEditor.load);
原文地址:https://www.cnblogs.com/webFrontDev/p/2830180.html