使用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 相关文章推荐
理解Javascript_14_函数形式参数与arguments
Oct 20 Javascript
jquery仿京东导航/仿淘宝商城左侧分类导航下拉菜单效果
Apr 24 Javascript
js读取被点击次数的简单实例(从数据库中读取)
Mar 07 Javascript
javascript刷新父页面的各种方法汇总
Sep 03 Javascript
jQuery的deferred对象详解
Nov 12 Javascript
在JavaScript的正则表达式中使用exec()方法
Jun 16 Javascript
Vuejs第一篇之入门教程详解(单向绑定、双向绑定、列表渲染、响应函数)
Sep 09 Javascript
JS 组件系列之 bootstrap treegrid 组件封装过程
Apr 28 Javascript
基于vue监听滚动事件实现锚点链接平滑滚动的方法
Jan 17 Javascript
详解@angular/cli 改变默认启动端口两种方式
Nov 29 Javascript
ES6 Object.assign()的用法及其使用
Jan 18 Javascript
JavaScript实现优先级队列
Dec 06 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
PHP函数分享之curl方式取得数据、模拟登陆、POST数据
2014/06/04 PHP
在Windows XP下安装Apache+MySQL+PHP环境
2015/02/22 PHP
PHP+jQuery+Ajax实现分页效果 jPaginate插件的应用
2015/10/09 PHP
功能强大的PHP POST提交数据类
2016/07/15 PHP
php输出含有“#”字符串的方法
2017/01/18 PHP
PHP使用 Imagick 扩展实现图片合成,圆角处理功能示例
2019/09/09 PHP
在 Laravel 中动态隐藏 API 字段的方法
2019/10/25 PHP
Yii框架多语言站点配置方法分析【中文/英文切换站点】
2020/04/07 PHP
用php实现分页效果的示例代码
2020/12/10 PHP
JavaScript高级程序设计 阅读笔记(四) ECMAScript中的类型转换
2012/02/27 Javascript
JS 操作Array数组的方法及属性实例解析
2014/01/08 Javascript
用js将内容复制到剪贴板兼容浏览器
2014/03/18 Javascript
详解addEventListener的三个参数之useCapture
2015/03/16 Javascript
AngularJS实用开发技巧(推荐)
2016/07/13 Javascript
基于JavaScript实现淘宝商品广告效果
2017/08/10 Javascript
VUE2 前端实现 静态二级省市联动选择select的示例
2018/02/09 Javascript
jQuery模拟12306城市选择框功能简单实现方法示例
2018/08/13 jQuery
关于在vue 中使用百度ueEditor编辑器的方法实例代码
2018/09/14 Javascript
ES6基础之 Promise 对象用法实例详解
2019/08/22 Javascript
JavaScript实现图片轮播特效
2019/10/23 Javascript
[00:34]TI7不朽珍藏III——地穴编织者不朽展示
2017/07/15 DOTA
Python环境变量设置方法
2016/08/28 Python
python实现根据文件关键字进行切分为多个文件的示例
2018/12/10 Python
简单了解Python matplotlib线的属性
2019/06/29 Python
pywinauto自动化操作记事本
2019/08/26 Python
Python 类的魔法属性用法实例分析
2019/11/21 Python
如何向scrapy中的spider传递参数的几种方法
2020/11/18 Python
python的dict判断key是否存在的方法
2020/12/09 Python
利用python+request通过接口实现人员通行记录上传功能
2021/01/13 Python
英国巧克力贸易公司:Chocolate Trading Company
2017/03/21 全球购物
中华魂放飞梦想演讲稿
2014/08/26 职场文书
党员干部四风问题整改措施思想汇报
2014/10/12 职场文书
自我推荐信格式模板
2015/03/24 职场文书
教师节晚会主持词
2015/06/30 职场文书
浅谈node.js中间件有哪些类型
2021/04/29 Javascript
Ajax请求超时与网络异常处理图文详解
2021/05/23 Javascript