Skip to content

简单限定裁剪区域始终在图片范围内

小豆豆 edited this page Sep 2, 2018 · 1 revision

功能概述

一般程序设定用户选择一张图片要裁成指定大小,那么大部分情况下都是希望在完整图片中截取一部分,而且用户大部分也是希望从图片中截取完整的一部分;如果拖动cropbox能跑出图片范围(大部分是无意义的空白,甚至1px这种很难察觉),这会给用户带来很大的麻烦,因为要绝对定位人是很难完成的(包括鼠标操作),非常抓鸡。

readme中并未介绍如何实现限定cropbox始终在图片范围内的方法,经过一番研究,写了一段代码。

支持

限定cropbox只能在图片范围内拖动;如果图片旋转,cropbox不超过最高点和最低点围成的矩形(==getCanvasData的大小范围),可以让用户裁剪到四个有意义的空白三角形区域(要排除这几个空白,好像蛮复杂的计算,不会写,围观issues/401)。

实现

不要在意那些变量名细节(捂脸

var cropper=new Cropper(img,{
    ......
    ,crop:function(e){
            //限定裁剪范围为图片区域或旋转包含部分空白
            var box=cropper.getContainerData();
            var bg=cropper.getCanvasData();
            var crop=cropper.getCropBoxData();
            
            var obj=xpc(box,bg,crop);
            
            if(obj.x||obj.y){
                crop=xpc(box,bg,okPos);
                if(!obj.x){//一边分量有效
                    crop.left=obj.left;
                    crop.width=obj.width;
                }else if(!obj.y){
                    crop.top=obj.top;
                    crop.height=obj.height;
                };
                cropper.setCropBoxData(crop);
            }else{
                okPos=obj;
            };
        }
    }
);

var okPos;
var xpc=function(box,bg,crop){
    var obj=Object.assign({},crop);
    xp(obj,"left",bg.left,bg.width+bg.left,1,"x");
    xp(obj,"top",bg.top,bg.height+bg.top,1,"y");
    
    xp(obj,"width",obj.left,bg.width+bg.left,0,"x");
    xp(obj,"height",obj.top,bg.height+bg.top,0,"y");
    return obj;
};
var xp=function(obj,key,min,max,mod,xy){
    var cur=obj[key];
    if(!mod){
        if(cur+min>max){
            obj[xy]=true;
            obj[key]=max-min;
        };
    }else if(cur<min||cur>max){
        obj[xy]=true;
        obj[key]=min;
    };
};