canvas仿知乎头像裁剪

1 篇文章 0 订阅

canvas实现图片裁剪,
裁剪效果图

<head lang="en">
    <meta charset="UTF-8">
    <title>仿知乎头像裁剪</title>
    <link rel="stylesheet" href="imgCut.css" type="text/css" />
    <style>
        .su_body{
            border:1px solid blue;
            position:relative;
            width:500px;
            height:500px;
            padding:20px 0;
        }
        .su_imgCut{
            border:1px solid green;
            width:300px;
            height:300px;
            margin: 0 auto 30px;
            cursor: move;
            position: relative;
        }
        /*.mark{*/
            /*position:absolute;*/
            /*height:100px;*/
            /*width:100px;*/
            /*left:50%;*/
            /*top:50%;*/
            /*margin:-50px -50px;*/
            /*z-index:10;*/
            /*border:1px solid #000;*/
            /*cursor:move;*/
        /*}*/
    </style>
</head>
<body>

边界 有bug
<input type="range" step="0.1" min="1" max="2" class="RangeInput" value="1" id="rangIput" oninput="canvasSize()">


<div class="su_body">
    <div class="su_imgCut" id = "su_imgCut">
        <canvas id="c1" style="width: 300px; height: 300px;"></canvas>
    </div>
    <input type="file" value="上传文件" >

    <div class="su_scale">
        <span class="su_scale_left" onClick="scaleAdd(-10, 200, 0)"> - </span>
        <!--进度条-->
        <div id="su_scale_down">
            <!--条-->
            <div id="su_scale_top" style="width:10px;">
            </div>
            <!-- 点-->
            <span id="su_scale_dot"></span>
        </div>
        <span class="su_scale_right" onClick="scaleAdd(+10, 200, 0)"> + </span>
    </div>
</div>

<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="../imgCut.js"></script>
</body>
</html>
</body>
</html>
body{
    padding:50px;
}

#c1, #c3{
    padding: 50px;
    border: 1px solid red;
}
.su_scale{
    display: -webkit-flex; /* Safari */
    display: flex;
    flex-flow: row nowrap;
    align-items: center;

    border:1px solid red;
    height:50px;
}

.su_scale .su_scale_left,
.su_scale .su_scale_right{
    width:40px;
    height:40px;
    margin: 0 10px;
    border-radius:50%;
    background-color:#f4f4f4;
    font-size:40px;
    text-align:center;
    line-height:40px;
    color:red;
}
.su_scale div{
    width:209px;
    height: 5px;
    background-color:#f4f4f4;
}
.su_scale #su_scale_down{
    display: -webkit-flex; /* Safari */
    display: flex;
    flex-flow: row nowrap;
}

.su_scale #su_scale_top{
    background-color:red;
}
.su_scale #su_scale_dot{
    width: 10px;
    height: 10px;
    position: relative;
    top: -2.5px;
    left: -1px;
    display: block;
    border-radius:50%;
    background-color: red;
    cursor:pointer;
}


var  urlData;
$('input[type=file]').change(function(){
    var file=this.files[0];
    var reader=new FileReader();
    reader.function(){
        // 通过 reader.result 来访问生成的 DataURL
        var url=reader.result;
        urlData = url;
        showImg()
    };
    reader.readAsDataURL(file);
});

var canvas1 = document.getElementById("c1")//原图
var oMark = document.getElementById("mark")//裁剪框
canvas1.height = 300;
canvas1.width=300;
var imgurl = "";

/**
 *  裁剪图片 关键代码
 *   避免 canvas.getImageData()  画布污染跨域问题 改为传入Base64
 * [showImg description]
 * @param  {[type]} url_a [description]
 * @return {[type]}       [description]
 */

//x y 位置, w h 大小
const img_x = 50, img_y =50, img_w = 200, img_h = 200; //裁剪图片位置大小
var x = img_x, y = img_y, w = img_w, h = img_h;//canvas内图片 位置 大小
function showImg(){

    var cxt1 = canvas1.getContext("2d")
    var img = new Image();
    img.src = urlData;

    var canvas2 = document.createElement("canvas")
    var cxt2=canvas2.getContext("2d")
    img.onload = function(){
        canvas1.height=canvas1.height;//清空 画布


        console.log(" 画图时 x:"+x + " y"+y + " w" + w +" h"+h);
        cxt1.drawImage(img,x,y,w, h);

        var dataImg = cxt1.getImageData(img_x,img_y,img_w,img_h)

        canvas2.width =img_w ;
        canvas2.height = img_h;
        cxt2.putImageData(dataImg,0,0);

        var img2 = canvas2.toDataURL("image/png");
        var img3 = new Image();
        img3.src = img2;
        img3.onload  = function(){

            //设置模糊边框
            cxt1.globalAlpha=0.8;
            cxt1.fillStyle="#f4f4f4";
            cxt1.fillRect(0,0,canvas1.width,canvas1.height);

            cxt1.drawImage(img3,img_x,img_y,img_w,img_h);
            console.log(img2)
            $("body").append("<img src='"+img2+"'>");
        }
    }
}

/**
 * 剪切 框 移动事件(canvas 大小)
 * [windowMove description]
 * @return {[type]} [description]
 */
// oMark.function(ev){
//     console.log(ev);
//     var disX=ev.clientX-oMark.offsetLeft
//     var disY=ev.clientY-oMark.offsetTop
//
//     console.log("disX:"+disX + "  disY:"+disY);
//     document.function(ev){
//         var l=ev.clientX-disX
//         var t=ev.clientY-disY
//         console.log("l:"+l + "  t:"+t);
//         oMark.style.left=l+'px'
//         oMark.style.top=t+'px'
//
//         cutCanvas();
//     }
//     document.function(){
//         document.null;
//         document.null
//     }
// }

/**
 *  裁剪canvas 事件
 */
function cutCanvas(){
    var srcX = oMark.offsetLeft-canvas1.getBoundingClientRect().left;
    var srcY = oMark.offsetTop-canvas1.getBoundingClientRect().top;
    var sWidth = oMark.offsetWidth;
    var sHeight = oMark.offsetHeight;

    var canvas2 = document.createElement("canvas")
    var cxt2=canvas2.getContext("2d")
    canvas2.width = sWidth;
    canvas2.height = sHeight;

    var cxt1 = canvas1.getContext("2d");
    var dataImg = cxt1.getImageData(srcX,srcY,sWidth,sHeight);
    cxt2.putImageData(dataImg,0,0,0,0,canvas2.width,canvas2.height)

    var img2 = canvas2.toDataURL("image/png");
    var cxt3=canvas3.getContext("2d")
    var img3 = new Image();
    img3.src = img2;
    img3.onload  = function(){
        cxt3.drawImage(img3,0,0,canvas3.width,canvas3.height)
        // console.log(canvas3.toDataURL("image/png"))
    }
}

/**
 *  通过Id 获取标签
 * @param id
 * @returns {Element}
 */
var getId = function(id){return document.getElementById(id)}


/**
 *   进度条 变大变小
 * @param w  change
 * @param max 最大长度
 * @param min 最小长度
 */
function scaleAdd(w, max, min ){
    let top = getId("su_scale_top");//进度条  条
    console.log("width:"+top.style.width+" w:"+w)
    let width= parseInt(parseInt(top.style.width) + w );
    top.style.width= ( (width <= max && width >= min) ? width : (width < min ? min : (width > max ? max : width) ) ) +'px';
}



/**
 *  标签移动
 * @param ev 鼠标
 * @param e  标签
 * @param callback  移动过程中回调函数
 */
function eleMove(ev, e, callback){
    let disX=ev.clientX-e.offsetLeft
    let disY=ev.clientY-e.offsetTop

    console.log("disX:"+disX + "  disY:"+disY);
    document.function(ev){
        let l=ev.clientX-disX
        let t=ev.clientY-disY
        console.log("l:"+l + "  t:"+t);
        e.style.left=l+'px'
        e.style.top=t+'px'
        //判断callback是否为 function
        if(callback instanceof Function ){
            callback();
        }
    }
    document.function(){
        document.null;
        document.null
    }
}

/**
 *  剪切框移动事件
 * @param ev
 */
// oMark.onmousedown = function(ev){
//     eleMove(ev, oMark, cutCanvas);
// }

getId("su_imgCut").onmousedown = function(ev){
    let disX=ev.clientX;
    let disY=ev.clientY;

    console.log("disX:"+disX + "  disY:"+disY);
    document.function(ev){
        let l=ev.clientX-disX
        let t=ev.clientY-disY
        console.log("l:"+l + "  t:"+t);
        console.log("移动前 x:"+x + " y:"+y);
        x = x + l ;
        y = y + t;

        // x = x > (img_x*imgSize) ? (img_x*imgSize) : x;
        // y = y  > (img_y*imgSize) ? (img_y*imgSize) : y;
        //
        // x = x < - (img_x*imgSize) ? -(img_x*imgSize) : x;
        // y = y < - (img_y*imgSize) ? -(img_y*imgSize) : y;

        //向右下 移动时边界
        x = x > img_x ? img_x : x;
        y = y > img_y ? img_y : y;
        //向左上移动事边界
        y = y < -( ( h-img_h ) / 2 )? -( ( h-img_h ) / 2 ) : y;
        x = x < -( (w-img_w) / 2) ? -( (w-img_w) / 2) : x;

        // x = x < img_x ? img_x : x;
        // y = y < img_y ? img_y : y;

        console.log("移动后 x:"+ x+"  y:"+y);
        showImg();//图片移动事件

    }
    document.function(){
        document.null;
        document.null
    }
 }
/**
 *  点移动事件
 * @param ev
 */
getId("su_scale_dot").function(ev){
    var e = getId("su_scale_dot");
    let disX=ev.clientX-e.offsetLeft
    let disY=ev.clientY-e.offsetTop

    console.log("disX:"+disX + "  disY:"+disY);
    document.function(ev){
        let c_width=ev.clientX-disX-getId("su_scale_top").offsetLeft;
        getId("su_scale_top").style.width= Math.max(0, Math.min( 200,c_width)) +'px';
    }
    document.function(){
        document.null;
        document.null
    }
}

/**
 *  canvas 图片 放大缩小
 */
var imgSize ;
function canvasSize(){
    var value = document.getElementById('rangIput').value ;
    console.log(value)

    imgSize = (1- value) ;

    let w2 = w, h2 = h;//变化前 图片大小
    w = img_w *value;
    h = img_h *value;//canvas 位置 大小
    console.log("放大前 x:"+ x+"  y:"+y);

    x = x + ((w2 - w) / 2);
    y = y + ((h2 - h) / 2);

    //左上缩小放大 后 防止图片越界
    x = x > img_x ? img_x :x;
    y = y > img_y ? img_y : y;
    //右下缩小放大 后 防止图片越界
    // y = y < -( ( h-img_h ) / 2 ) + img_y ? -( ( h-img_h ) / 2 ) + img_y  : y;
    // x = x < -( (w-img_w) / 2) + img_x  ? -( (w-img_w) / 2) + img_x  : x;

     y = y < -( ( h-img_h ) ) + img_y ? -( ( h-img_h ) ) + img_y  : y;
     x = x < -( (w-img_w)) + img_x  ? -( (w-img_w) ) + img_x  : x;
    console.log("放大后 x:"+ x+"  y:"+y);
    showImg();
}

待完善

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值