写了个基于Jquery的头像裁剪插件

预览图:

说明:

此插件没有做兼容处理,做的过程中只是做思路逻辑分析,至于IE下,没有兼容开发,可在其他标准浏览器下运行,查看源代码

DOM:

<head>
<script src="jquery.js"></script>
<script src="clip.js"></script>
</head> 
<body>
    <div class="clip-wrapper">
        <div id="J_ClipPicture" class="clip-box">
            <img class="clip-layer-bg" src="3.jpg" height="100%" width="100%">
            <img class="clip-layer" src="3.jpg" height="100%" width="100%">
            <div class="clip-move">
                <span class="left-up"></span>
                <span class="up"></span>
                <span class="right-up"></span>
                <span class="right"></span>
                <span class="right-down"></span>
                <span class="down"></span>
                 <span class="left-down"></span>
                <span class="left"></span>
            </div>
        </div> 
        <div class="clip-view">
             <img class="clip-layer" src="3.jpg" height="100%" width="100%">
        </div>
    </div>
</body>

CSS:

.clip-wrapper{ padding:20px; position:relative;width:600px;height:600px; background-color:#eee;}
.clip-box{ position:relative;width:200px;height:300px; text-align:center;background-color:#333;}
.clip-box img{ position:absolute;left:0;top:0;}
.clip-box img.clip-layer-bg{opacity:0.3;}
.clip-box img.clip-layer{ clip:rect(0 100px 150px 0);}
.clip-move{ position:absolute;left:0;top:0;width:100px;height:150px;border:1px solid #fff; box-sizing:border-box; cursor:move;}
.clip-move span{ position:absolute; display:block;width:8px;height:8px;border-radius:4px;background-color:#fff;}
.clip-move .left-up{left:-4px;top:-4px; cursor:nw-resize;}
.clip-move .up{left:50%;top:-4px;margin-left:-4px; cursor:n-resize;}
.clip-move .right-up{right:-4px;top:-4px;margin-left:-4px; cursor:ne-resize;}
.clip-move .right{right:-4px;top:50%;margin-top:-4px; cursor:e-resize;}
.clip-move .right-down{right:-4px;bottom:-4px; cursor:se-resize;}
.clip-move .down{left:50%;bottom:-4px; margin-left:-4px;cursor:s-resize;}
.clip-move .left-down{left:-4px;bottom:-4px;cursor:sw-resize;}
.clip-move .left{left:-4px;top:50%; margin-top:-4px;cursor:w-resize;}

.clip-view{ position:absolute;left:230px;top:20px;;width:200px;height:300px; overflow:hidden}
.clip-view img.clip-layer{ position:absolute; clip:rect(0 100px 150px 0);}

JS:

/**
*头像剪裁功能
*此插件没有做兼容处理,做的过程中只是做思路逻辑分析,至于IE下,没有兼容开发,可在其他标准浏览器下运行,查看源代码
*name:杨永
*QQ  :377746756
*/
;(function($){

    var ClipPicture=function(clipWrap,setting){
        var _this_=this;
        //设置配置参数
        this.setting={
                     clipWidth:50,
                     clipHeight:50
                     };
        //扩展默认参数
        $.extend(this.setting,setting);
        //保存传递进来的剪切区域
        this.clipWrap=clipWrap;
        //保存剪裁区域相对于页面的偏移和剪裁区域的尺寸
        this.clipMainOffset=clipWrap.offset();
        this.clipScale={clipWrap.width(),height:clipWrap.height()};
        //获取预览区域
        this.clipScaleView=clipWrap.next();
        this.viewImg=this.clipScaleView.find(".clip-layer")[0];
        
        //获取需要操作的DOM
        this.clipMoveDiv=clipWrap.find(".clip-move");
        this.clipImg=clipWrap.find(".clip-layer")[0];
        this.resizeClipBtn=this.clipMoveDiv.find("span");
        
        //初始化拖动功能
        this.initDrag();
        //初始化调整剪裁区域大小功能
        this.initClipScale();
    };
    ClipPicture.prototype={
        //初始化调整剪裁区域大小功能
        initClipScale:function(){
            var self=this,
                resizeClipBtn=this.resizeClipBtn,
                doc=$(document),
                diffOpts=null,
                curBtn=null;//记录偏移量和宽度
                
            
            //绑定事件
            resizeClipBtn.mousedown(function(evt){
                var _this=curBtn=this;
                //取消事件冒泡
                evt.stopPropagation();
                evt.preventDefault();
                //更具点击的方位设置相对哪个点进行定为
                self.setPostion($(this));
                //设置偏移量可宽度
                diffOpts={
                         positionLeft:self.clipMoveDiv.position().left,
                         positionTop:self.clipMoveDiv.position().top,
                         offsetLeft:self.clipMoveDiv.offset().left,
                         offsetTop:self.clipMoveDiv.offset().top,
                         self.clipMoveDiv.width(),
                         height:self.clipMoveDiv.height()
                         };
                //绑定doc事件
                doc.bind("mousemove",mousemoveHandle);
                doc.bind("mouseup",mouseupHandle);
                    
            });
            var mousemoveHandle=function(evt){
                    self.scale(evt,$(curBtn),diffOpts);
                };
            var mouseupHandle=function(){
                    doc.unbind("mousemove",mousemoveHandle);
                    doc.unbind("mouseup",mouseupHandle);
                };
        },
        scale:function(evt,curBtn,diffOpts){
            var self=this;
            var clipMoveDiv=this.clipMoveDiv;
            //根据按钮类型执行函数
            if(curBtn.hasClass("right")){
                self.scaleXAdd(evt,diffOpts);
            };
            if(curBtn.hasClass("left")){
                self.scaleXMin(evt,diffOpts);
            };
            if(curBtn.hasClass("down")){
                self.scaleYAdd(evt,diffOpts);
            };
            if(curBtn.hasClass("up")){
                self.scaleYMin(evt,diffOpts);
            };
            if(curBtn.hasClass("right-up")){
                self.scaleXAdd(evt,diffOpts);
                self.scaleYMin(evt,diffOpts);
            };
            if(curBtn.hasClass("right-down")){
                self.scaleXAdd(evt,diffOpts);
                self.scaleYAdd(evt,diffOpts);
            };
            if(curBtn.hasClass("left-down")){
                self.scaleYAdd(evt,diffOpts);
                self.scaleXMin(evt,diffOpts);
            };
            if(curBtn.hasClass("left-up")){
                self.scaleYMin(evt,diffOpts);
                self.scaleXMin(evt,diffOpts);
            };    
            //调整剪裁区域this.viewImg
            this.clipImg.style.clip="rect("+clipMoveDiv.position().top+"px "+(clipMoveDiv.position().left+clipMoveDiv.width()+2)+"px "+(clipMoveDiv.position().top+clipMoveDiv.height()+2)+"px "+clipMoveDiv.position().left+"px)";
            
            this.viewImg.style.clip="rect("+clipMoveDiv.position().top+"px "+(clipMoveDiv.position().left+clipMoveDiv.width()+2)+"px "+(clipMoveDiv.position().top+clipMoveDiv.height()+2)+"px "+clipMoveDiv.position().left+"px)";
            
            $(self.viewImg).css({
                                left:-clipMoveDiv.position().left,
                                top:-clipMoveDiv.position().top
                                });
        },
        scaleXAdd:function(evt,diffOpts){
            var width=evt.pageX-diffOpts.offsetLeft;
                width=width+diffOpts.positionLeft>this.clipScale.width?this.clipScale.width-diffOpts.positionLeft:width;
            this.clipMoveDiv.css("width",width);    
        },
        scaleXMin:function(evt,diffOpts){
            var offsetRight=this.clipScale.width-diffOpts.width-diffOpts.positionLeft;
            var width=diffOpts.offsetLeft+diffOpts.width-evt.pageX;
                width=width+offsetRight>this.clipScale.width?this.clipScale.width-offsetRight+2:width;    
            this.clipMoveDiv.css("width",width);    
        },
        scaleYAdd:function(evt,diffOpts){
            var height=evt.pageY-diffOpts.offsetTop;
                height=height+diffOpts.positionTop>this.clipScale.height?this.clipScale.height-diffOpts.positionTop:height;
            this.clipMoveDiv.css("height",height);    
        },
        scaleYMin:function(evt,diffOpts){
            var offsetTop=this.clipScale.height-diffOpts.height-diffOpts.positionTop;
            var height=diffOpts.offsetTop+diffOpts.height-evt.pageY;
                height=height+offsetTop>this.clipScale.height?this.clipScale.height-offsetTop+2:height;    
            this.clipMoveDiv.css("height",height);    
        },
        //更具点击的方位设置相对哪个点进行
        setPostion:function(curBtn){
            var self=this;
            var clipMoveDiv=this.clipMoveDiv;

            //获取相对父元素的偏移和自身的宽高
            var position=clipMoveDiv.position(),
                right=self.clipScale.width-(position.left+clipMoveDiv.width())-2,
                bottom=self.clipScale.height-(position.top+clipMoveDiv.height())-2;
            //根据class来定位
            if(curBtn.hasClass("left-up")){
                clipMoveDiv.css({left:"auto",top:"auto",right:right+"px",bottom:bottom});
            };
            if(curBtn.hasClass("right-up")){
                clipMoveDiv.css({left:position.left,top:"auto",right:"auto",bottom:bottom});
            };
            if(curBtn.hasClass("right-down")){
                clipMoveDiv.css({left:position.left,top:position.top,right:"auto",bottom:"auto"});
            };
            if(curBtn.hasClass("left-down")){
                clipMoveDiv.css({left:"auto",top:position.top,right:right,bottom:"auto"});
            };
            if(curBtn.hasClass("left")||curBtn.hasClass("up")){
                clipMoveDiv.css({left:"auto",top:"auto",right:right,bottom:bottom});
            };
            if(curBtn.hasClass("right")||curBtn.hasClass("down")){
                clipMoveDiv.css({left:position.left,top:position.top,right:"auto",bottom:"auto"});
            };
        },
        //拖动功能
        initDrag:function(){
            var self=this
                clipMoveDiv=self.clipMoveDiv,
                doc=$(document),
                layerOffset=null;
            clipMoveDiv.mousedown(function(evt){
                evt.preventDefault();
                //获取鼠标layerX,layerY
                layerOffset=self.getLayerOffset(evt);
                //在document上绑定mousemove,mouseup
                doc.bind("mousemove",mousemoveHandle);
                doc.bind("mouseup",mouseupHandle);
            });
            //移动操作函数
            var mousemoveHandle=function(evt){
                    self.move(evt,layerOffset);
                };
            var mouseupHandle=function(){
                    doc.unbind("mousemove",mousemoveHandle);
                    doc.unbind("mouseup",mouseupHandle);
                };
        },
        //move
        move:function(evt,layerOffset){
            var self=this;
            var moveDiv=this.clipMoveDiv;
            var left=this.getMoveOffset(evt,layerOffset).left,
                top=this.getMoveOffset(evt,layerOffset).top;
            var maxW=this.clipScale.width-moveDiv.width()-2,
                maxH=this.clipScale.height-moveDiv.height()-2;
            //通过指定区域去限制拖动的范围
            left=left<0?0:left>maxW?maxW:left;
            top=top<0?0:top>maxH?maxH:top;
            moveDiv.css({
                        left:left,
                        top:top
                        });
            $(self.viewImg).css({
                        left:-left,
                        top:-top
                        });
            self.moveClipRect(left,top);
        },
        //驱动剪裁区域
        moveClipRect:function(left,top){
            //clip:rect(0 100px 100px 0);
            this.clipImg.style.clip="rect("+top+"px "+(left+this.clipMoveDiv.width()+2)+"px "+(top+this.clipMoveDiv.height()+2)+"px "+left+"px)";    
        this.viewImg.style.clip="rect("+top+"px "+(left+this.clipMoveDiv.width()+2)+"px "+(top+this.clipMoveDiv.height()+2)+"px "+left+"px)";        
        },
        //获取移动的left,top
        getMoveOffset:function(evt,layerOffset){
            return {
                    left:evt.pageX-this.clipMainOffset.left-layerOffset.layerX,
                    top:evt.pageY-this.clipMainOffset.top-layerOffset.layerY
                    };    
        },
        //获取鼠标layerX,layerY
        getLayerOffset:function(evt){
            //就是鼠标的相对页面的偏移减去当前层相对于页面的偏移
            return {
                    layerX:evt.pageX-this.clipMoveDiv.offset().left,
                    layerY:evt.pageY-this.clipMoveDiv.offset().top
                   };
        }
    };
    //注册到全局
    window.ClipPicture=ClipPicture;
})(jQuery);

创建方式:

<script>
$(function(){
        new ClipPicture($("#J_ClipPicture"),{clipWidth:50,clipHeight:500});
});
</script>
原文地址:https://www.cnblogs.com/yangliulang/p/3974972.html