使用canvas实现仿新浪微博头像截取上传功能

 更新时间:2015年09月02日 11:53:56   作者:jinhuazhe2013  
用户提供图像大小尺寸不合适,如何用截取上传呢?接下来小编教大家使用使用canvas实现仿新浪微博头像截取上传功能解决问题,需要的朋友一起学习吧。

最近看到微博头像上传功能很感兴趣,于是就使用canvas写了一个,本文写的不好还请见谅。本程序目前在谷歌浏览器和火狐浏览器测试可用,ie浏览器无法支持。 

因为ie的安全机制不允许img使用本地路径,所以若想ie支持本程序,必须先将图片上传,然后给img对象上传后的图片地址。

我在这里没写,是因为暂时没写上传功能的后端代码,并且还不确定有没有更好的解决办法。

如下是新浪的

如下是我做的截取部分

代码:

var canvas = document.getElementById('canvas'),
    context = canvas.getContext('d'),
    canvas = document.getElementById('canvas_dp'),
    context = canvas.getContext('d'),
    image = new Image(),//document.getElementById('myimg'),
    imageData,
   scale,//缩放比例
   rubberbandRectangle = {left:,top:,width:,height:},
   resize = ;
   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() {
    context.drawImage(image,rubberbandRectangle.left/scale,rubberbandRectangle.top/scale,rubberbandRectangle.width/scale,rubberbandRectangle.height/scale,,,,);
 }
 function drawRubberband() {
   context.save();
   context.beginPath();//开始新的路径
     rect(rubberbandRectangle.left,
      rubberbandRectangle.top,
      rubberbandRectangle.width,
      rubberbandRectangle.height);
   context.fillStyle='rgba(,,,.)';         
   addRectanglePath();
   context.fill();//填充路径
   context.fillStyle='rgba(,,,)'; 
   captureCanvasPixels();//将选取的图像copy到预览canvas中
   context.beginPath();
   context.strokeStyle = '#';
   context.lineWidth = .;
   context.arc(rubberbandRectangle.left+rubberbandRectangle.width,rubberbandRectangle.top+rubberbandRectangle.height,,,Math.PI*,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(,,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<) ? : left;
   rubberbandRectangle.top = (top < ) ? : 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(, , canvas.width, canvas.height);
   context.putImageData(imageData, ,);
 }
 // 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 - ) < loc.x && (rubberbandRectangle.top + rubberbandRectangle.height - ) < loc.y && (rubberbandRectangle.left + rubberbandRectangle.width +) > loc.x && (rubberbandRectangle.top + rubberbandRectangle.height + ) > 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 - ) < loc.x && (rubberbandRectangle.top + rubberbandRectangle.height - ) < loc.y && (rubberbandRectangle.left + rubberbandRectangle.width +) > loc.x && (rubberbandRectangle.top + rubberbandRectangle.height + ) > 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[]) {
     //火狐下,谷歌下都是支持的
     image.src = window.URL.createObjectURL(fileObj.files[]);
   } else {
     alert('对不起,您的浏览器不支持');
   }
 }
 image.src = '';
 image.onload = function () {
   console.log(image);
   var w,h;
   //计算图片缩放比例
   if(image.width>canvas.width){
     console.log();
     w = canvas.width;
     h = canvas.width*image.height/image.width
   }else if(image.height>canvas.height){
     console.log();
     h = canvas.height;
     w = canvas.height*image.width/mage.height
   }else if(image.width/image.height >= canvas.width/canvas.height){
     console.log();
     w = canvas.width;
     h = canvas.width*image.height/image.width;
   }else if(image.width/image.height < canvas.width/canvas.height){
     console.log();
     w = canvas.height*image.width/image.height
     h = canvas.height;
   }
   scale = w/image.width;
   context.clearRect(,,canvas.width,canvas.height);
  context.drawImage(image, , ,w, h); 
  console.log( w+':'+h+'###'+canvas.width+':'+canvas.height);
  imageData= context.getImageData(, , canvas.width, canvas.height);
   drawRubberband();
 };

html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-">
    <title>CarlZhang</title>
  </head>
  <body>
    <div name="container" style="height:px;width:px;border:#BB px solid;text-align:center">
      <canvas id="canvas" style="z-index: ; " height="" width=""></canvas>
    </div>
    <!--预览-->
    <div name="display" style="height:px;width:px;border:#BB px solid;position:absolute;left:px;top:px;">
      <canvas id="canvas_dp" style="z-index: ; " height="" width=""></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-"></script>
  </body>
</html>

以上代码很简单吧,附有注释,有不同见解的朋友,欢迎给我留言,共同交流学习进步。欲了解更多有关canvas头像截取上传问题,请持续关注本站,本站每天都有新的内容更新。

相关文章

  • js实现简单贪吃蛇游戏

    js实现简单贪吃蛇游戏

    这篇文章主要为大家详细介绍了js实现简单贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • JS全局变量和局部变量最新解析

    JS全局变量和局部变量最新解析

    这篇文章主要介绍了JS全局变量和局部变量最新解析的相关知识,本文给给大家补充js删除局部变量的代码,非常不错,具有参考借鉴价值,感兴趣的朋友一起学习吧
    2016-06-06
  • JavaScript高阶API数组reduce函数使用示例

    JavaScript高阶API数组reduce函数使用示例

    这篇文章主要为大家介绍了JavaScript数组高阶API reduce函数使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 详解js中的apply与call的用法

    详解js中的apply与call的用法

    在ECAMScript3给Function的原型定义了两个方法,它们是Function.prototype.call和Function.prototype.apply。本文详细介绍了apply与call的用法,有需要的可以参考下。
    2016-07-07
  • javascript引导程序

    javascript引导程序

    本网站的javascript程序架构从以下几个基本点出发
    2008-10-10
  • JavaSctit 利用FileReader和滤镜上传图片预览功能

    JavaSctit 利用FileReader和滤镜上传图片预览功能

    FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件内容,使用 File或 Blob对象指定要读取的文件或数据。下面通过本文给大家分享JavaSctit 利用FileReader和滤镜上传图片预览功能,需要的朋友参考下吧
    2017-09-09
  • JavaScript数据结构链表知识详解

    JavaScript数据结构链表知识详解

    存储有序的元素集合,但不同于数组,链表中的元素在内存中不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。下面通过本文给大家详细介绍下,需要的朋友参考下
    2016-11-11
  • 一步步教会你微信小程序的登录鉴权

    一步步教会你微信小程序的登录鉴权

    登录功能是许多小程序必备的一个功能,通过登录系统,我们可以记录用户在我们的小程序里一些行为,在后台我们也可以模糊地确认用户。下面这篇文章主要给大家介绍了关于小程序登录鉴权的相关资料,需要的朋友可以参考下。
    2018-04-04
  • JS仿万科底部的新闻滑动特效代码

    JS仿万科底部的新闻滑动特效代码

    本文通过一段实例代码给大家介绍了JS仿万科底部的新闻滑动特效代码,需要的朋友参考下
    2017-09-09
  • 文本框中禁止非数字字符输入比如手机号码、邮编

    文本框中禁止非数字字符输入比如手机号码、邮编

    总是遇到很多禁止非数字字符输入的文本框,比如手机号码了 邮编了于是下面为大家介绍下如何禁止,感兴趣的朋友可以了解下
    2013-08-08

最新评论