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


Posted in Javascript onSeptember 02, 2015

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

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

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

如下是新浪的

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

如下是我做的截取部分

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

代码:

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头像截取上传问题,请持续关注本站,本站每天都有新的内容更新。

Javascript 相关文章推荐
jQuery中的read和JavaScript中的onload函数的区别
Aug 27 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
Sep 06 Javascript
浏览器复制插件zeroclipboard使用指南
Mar 26 Javascript
jQuery插件AjaxFileUpload实现ajax文件上传
May 05 Javascript
jQuery获取访问者IP地址的方法(基于新浪API与QQ查询接口)
May 25 Javascript
js控制li的隐藏和显示实例代码
Oct 15 Javascript
AngularJS中的Promise详细介绍及实例代码
Dec 13 Javascript
jQuery DateTimePicker 日期和时间插件示例
Jan 22 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
Nov 20 Javascript
JS+HTML实现的圆形可点击区域示例【3种方法】
Aug 01 Javascript
react 中父组件与子组件双向绑定问题
May 20 Javascript
微信小程序授权登陆及每次检查是否授权实例代码
Sep 18 Javascript
js随机生成字母数字组合的字符串 随机动画数字
Sep 02 #Javascript
JS自定义选项卡函数及用法实例分析
Sep 02 #Javascript
js鼠标点击按钮切换图片-图片自动切换-点击左右按钮切换特效代码
Sep 02 #Javascript
jQuery实现自定义右键菜单的树状菜单效果
Sep 02 #Javascript
JavaScript学习小结(一)——JavaScript入门基础
Sep 02 #Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
Sep 02 #Javascript
JavaScript对象学习小结
Sep 02 #Javascript
You might like
Discuz! 5.0.0论坛程序中加入一段js代码,让会员点击下载附件前自动弹出提示窗口
2007/04/18 PHP
php cookie使用方法学习笔记分享
2013/11/07 PHP
php获取mysql字段名称和其它信息的例子
2014/04/14 PHP
php中数字0和空值的区别分析
2014/06/05 PHP
PHP7之Mongodb API使用详解
2015/12/26 PHP
javascript基础知识大集锦(一) 推荐收藏
2011/01/13 Javascript
jQuery EasyUI API 中文文档 搜索框
2011/09/29 Javascript
基于jquery封装的一个js分页
2011/11/15 Javascript
使用JavaScript动态设置样式实现代码及演示动画
2013/01/25 Javascript
使用Grunt.js管理你项目的应用说明
2013/04/24 Javascript
从数组中随机取x条不重复数据的JS代码
2013/12/24 Javascript
node.js中的socket.io入门实例
2014/04/26 Javascript
一个JavaScript操作元素定位元素的实例
2014/10/29 Javascript
js实现对table动态添加、删除和更新的方法
2015/02/10 Javascript
jQuery学习笔记之Ajax用法实例详解
2015/12/01 Javascript
JavaScript给每一个li节点绑定点击事件的实现方法
2016/12/01 Javascript
jQuery模拟下拉框选择对应菜单的内容
2017/03/07 Javascript
Vue列表页渲染优化详解
2017/07/24 Javascript
使用百度地图实现地图网格的示例
2018/02/06 Javascript
JavaScript执行环境及作用域链实例分析
2018/08/01 Javascript
leaflet加载geojson叠加显示功能代码
2020/02/21 Javascript
Python中文件遍历的两种方法
2014/06/16 Python
详解Python中with语句的用法
2015/04/15 Python
Python网络爬虫出现乱码问题的解决方法
2017/01/05 Python
python 读写excel文件操作示例【附源码下载】
2019/06/19 Python
使用python制作游戏下载进度条的代码(程序说明见注释)
2019/10/24 Python
Pytorch 卷积中的 Input Shape用法
2020/06/29 Python
python opencv实现图像配准与比较
2021/02/09 Python
Tenstickers法国:墙贴和装饰贴纸
2019/08/26 全球购物
四查四看剖析材料
2014/02/14 职场文书
党员创先争优公开承诺书
2014/03/28 职场文书
雷峰塔导游词
2015/02/09 职场文书
告知书格式
2015/07/01 职场文书
2016年小学端午节活动总结
2016/04/01 职场文书
研究生学习计划书应该怎么写?
2019/09/10 职场文书
SQL Server数据定义——模式与基本表操作
2021/04/05 SQL Server