【javascript】html5中使用canvas编写头像上传截取功能

【javascript】html5中使用canvas编写头像上传截取功能 

本人对canvas很是喜欢,于是想仿照新浪微博头像上传功能(前端使用canvas)
 

本程序目前在谷歌浏览器和火狐浏览器测试可用,ie浏览器无法支持。
因为ie的安全机制不允许img使用本地路径,所以若想ie支持本程序,必须先将图片上传,然后给img对象上传后的图片地址。
我在这里没写,是因为暂时没写上传功能的后端代码,并且还不确定有没有更好的解决办法。

 

一、如下是新浪的头像截取功能预览图:

 

 

二、如下是我做的截取部分

javascript代码(cavas_img_upload.js):

var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d'),
    
    canvas2 = document.getElementById('canvas_dp'),
    context2 = canvas2.getContext('2d'),

    image = new Image(),//document.getElementById('myimg'),
    
    imageData,
    scale,//缩放比例
    
    rubberbandRectangle = {left:10,top:20,width:180,height:150},
    resize = 1;
    oldRubberbandRectangle = {};
    dragging = false,
    extending = false,
    mousedown = {};

// Functions.....................................................
function windowToCanvas(canvas, x, y) {
   var canvasRectangle = canvas.getBoundingClientRect();
   
   return {
             x: x - canvasRectangle.left,
             y: y - canvasRectangle.top
          };
}

//将截取的图片画在小的canvas中
function captureCanvasPixels() {
     context2.drawImage(image,rubberbandRectangle.left/scale,rubberbandRectangle.top/scale,rubberbandRectangle.width/scale,rubberbandRectangle.height/scale,0,0,180,150);
}


function drawRubberband() {
    context.save();
    context.beginPath();//开始新的路径
       rect(rubberbandRectangle.left,
          rubberbandRectangle.top,
          rubberbandRectangle.width,
          rubberbandRectangle.height);
    context.fillStyle='rgba(255,255,255,0.5)';                  
    addRectanglePath();
    context.fill();//填充路径
    context.fillStyle='rgba(255,255,255,1)'; 
    
    captureCanvasPixels();//将选取的图像copy到预览canvas中
    
    context.beginPath();
    context.strokeStyle = '#333333';
    context.lineWidth = 1.0;
    context.arc(rubberbandRectangle.left+rubberbandRectangle.width,rubberbandRectangle.top+rubberbandRectangle.height,5,0,Math.PI*2,true);
    context.fill();//填充路径
    context.stroke();//填充路径
    context.restore();
}

function rect(x, y, w, h, direction){
    if(direction){//逆时针
        context.moveTo(x, y);
        context.lineTo(x, y + h);
        context.lineTo(x + w, y + h);
        context.lineTo(x + w, y);
    }else{//顺时针
        context.moveTo(x, y);
        context.lineTo(x + w, y);
        context.lineTo(x + w, y + h);
        context.lineTo(x, y + h);
    }
    context.closePath();
}
function addRectanglePath(){
    rect(0,0,canvas.width,canvas.height,true);
}

function startDragging(loc){
    mousedown.x = loc.x;
    mousedown.y = loc.y;
    oldRubberbandRectangle.left = rubberbandRectangle.left;
    oldRubberbandRectangle.top = rubberbandRectangle.top;
}
function updateRubberbandRectangle(loc){
    var left = oldRubberbandRectangle.left + loc.x-mousedown.x;
    var top = oldRubberbandRectangle.top + loc.y - mousedown.y;
    rubberbandRectangle.left = (left<0) ? 0 : left;
    rubberbandRectangle.top = (top < 0) ? 0: top;
    
    if(rubberbandRectangle.left + rubberbandRectangle.width > image.width * scale)rubberbandRectangle.left = image.width * scale - rubberbandRectangle.width; 
    if(rubberbandRectangle.top + rubberbandRectangle.height > image.height * scale)rubberbandRectangle.top = image.height * scale - rubberbandRectangle.height;
    drawRubberband();
}
function startExtendSelection(loc){
    mousedown.x = loc.x;
    mousedown.y = loc.y;
    oldRubberbandRectangle.width = rubberbandRectangle.width;
    oldRubberbandRectangle.height = rubberbandRectangle.height;
}
function extendSelection(loc){
    var width = parseInt(oldRubberbandRectangle.width) + parseInt(loc.x)-parseInt(mousedown.x);
    var height = parseInt(parseInt(oldRubberbandRectangle.height) * parseInt(width)/parseInt(oldRubberbandRectangle.width));
    
    rubberbandRectangle.width = width;
    rubberbandRectangle.height = height;
    drawRubberband();
}
function clearRubberbandRectangle(){
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.putImageData(imageData, 0 ,0);
}

// Event handlers...............................................
canvas.onmousedown = function(e){
    e.preventDefault();
    var loc = windowToCanvas(canvas, e.clientX, e.clientY);
    if(rubberbandRectangle.left < loc.x && rubberbandRectangle.top < loc.y && (rubberbandRectangle.left + rubberbandRectangle.width) > loc.x && (rubberbandRectangle.top + rubberbandRectangle.height) > loc.y){
        dragging = true;
        startDragging(loc);
    }else if((rubberbandRectangle.left + rubberbandRectangle.width - 3) < loc.x && (rubberbandRectangle.top + rubberbandRectangle.height - 3) < loc.y && (rubberbandRectangle.left + rubberbandRectangle.width +3) > loc.x && (rubberbandRectangle.top + rubberbandRectangle.height + 3) > loc.y){
        extending = true;
        startExtendSelection(loc);
    }
    
}

canvas.onmousemove = function (e) {
   e.preventDefault();
   
   var loc = windowToCanvas(canvas, e.clientX, e.clientY);
    if(rubberbandRectangle.left < loc.x && rubberbandRectangle.top < loc.y && (rubberbandRectangle.left + rubberbandRectangle.width) > loc.x && (rubberbandRectangle.top + rubberbandRectangle.height) > loc.y){
        canvas.style.cursor='move';
        
    }else if((rubberbandRectangle.left + rubberbandRectangle.width - 3) < loc.x && (rubberbandRectangle.top + rubberbandRectangle.height - 3) < loc.y && (rubberbandRectangle.left + rubberbandRectangle.width +3) > loc.x && (rubberbandRectangle.top + rubberbandRectangle.height + 3) > loc.y){
        canvas.style.cursor='nw-resize';
        
    }else{
        canvas.style.cursor='';
    }
   
   if (dragging) {
       
       clearRubberbandRectangle();
      updateRubberbandRectangle(loc);
    }
   if(extending){
       canvas.style.cursor='nw-resize';
       clearRubberbandRectangle();
       extendSelection(loc);
   }
}

canvas.onmouseup = function(e){
    e.preventDefault();
    dragging = false;
    extending = false;
}



// Initialization..............................................

var myfileInput = document.getElementById('myfileInput');
myfileInput.onchange=function(){
    setImage(myfileInput);
};




function setImage(fileObj){
    if (fileObj.files && fileObj.files[0]) {
        //火狐下,谷歌下都是支持的
        image.src = window.URL.createObjectURL(fileObj.files[0]);
    } else {
        alert('对不起,您的浏览器不支持');
    }
}



image.src = '';
image.onload = function () {
    console.log(image);
    var w,h;
    
    //计算图片缩放比例
    if(image.width>canvas.width){
        console.log(1);
        w = canvas.width;
        h = canvas.width*image.height/image.width
    }else if(image.height>canvas.height){
        console.log(2);
        h = canvas.height;
        w = canvas.height*image.width/mage.height
    }else if(image.width/image.height >= canvas.width/canvas.height){
        console.log(3);
        w = canvas.width;
        h = canvas.width*image.height/image.width;
    }else if(image.width/image.height < canvas.width/canvas.height){
        console.log(4);
        w = canvas.height*image.width/image.height
        h = canvas.height;
    }
    scale = w/image.width;
    context.clearRect(0,0,canvas.width,canvas.height);
   context.drawImage(image, 0, 0,w, h); 
   console.log( w+':'+h+'###'+canvas.width+':'+canvas.height);
   imageData=  context.getImageData(0, 0, canvas.width, canvas.height);
    drawRubberband();
};
View Code

 

html代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>CarlZhang</title>
    </head>
    <body>
        <div name="container" style="height:380px;width:330px;border:#92B8B1 1px solid;text-align:center">
            <canvas id="canvas" style="z-index: 9999; " height="359" width="324"></canvas>
        </div>
        <!--预览-->
        <div name="display" style="height:150px;width:180px;border:#92B8B1 1px solid;position:absolute;left:380px;top:110px;">
            <canvas id="canvas_dp" style="z-index: 9999; " height="150" width="180"></canvas>
        </div>
        
        <!--上传-->
        <input id="myfileInput" type="file" accept="image/gif, image/jpeg, image/x-png"/>
        
        <script src="js/cavas_img_upload.js" type="text/javascript" charset="utf-8"></script>
    </body>
</html>

 

 

参考文档:

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

posted @ 2015-09-02 11:38  jinhuazhe2013  阅读(545)  评论(0编辑  收藏  举报