使用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异步循环获取功能实现代码
Sep 19 Javascript
原生js实现fadein 和 fadeout淡入淡出效果
Jun 05 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
Apr 03 Javascript
js控制文本框输入的字符类型方法汇总
Jun 19 Javascript
6种javascript显示当前系统时间代码
Dec 01 Javascript
JS组件系列之Bootstrap Icon图标选择组件
Jan 28 Javascript
JavaScript代码性能优化总结篇
May 15 Javascript
利用NPM淘宝的node.js镜像加速nvm
Mar 27 Javascript
vue中如何使用ztree
Feb 06 Javascript
Vue 实现把表单form数据 转化成json格式的数据
Oct 29 Javascript
JS中this的4种绑定规则详解
Feb 04 Javascript
Vue +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例
Nov 18 Vue.js
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
windows7配置Nginx+php+mysql的详细教程
2016/09/04 PHP
PHP自定义函数获取汉字首字母的方法
2016/12/01 PHP
PHP进阶学习之依赖注入与Ioc容器详解
2019/06/19 PHP
java script编程起步(第三课)
2007/01/10 Javascript
分享8款优秀的 jQuery 加载动画和进度条插件
2012/10/24 Javascript
js字符串转换成xml对象并使用技巧解读
2013/04/18 Javascript
js判断radiobuttonlist的选中值显示/隐藏其它模块的实现方法
2016/08/25 Javascript
轻松掌握JavaScript策略模式
2016/08/25 Javascript
AngularJs Understanding the Controller Component
2016/09/02 Javascript
详解ECharts使用心得总结
2016/12/06 Javascript
Javascript 制作图形验证码实例详解
2016/12/22 Javascript
快速解决brew安装特定版本flow的问题
2018/05/17 Javascript
vue 自定义提示框(Toast)组件的实现代码
2018/08/17 Javascript
vue实现跨域的方法分析
2019/05/21 Javascript
微信小程序如何刷新当前界面的实现方法
2019/06/07 Javascript
ES6 Iterator接口和for...of循环用法分析
2019/07/31 Javascript
JS window对象简单操作完整示例
2020/01/14 Javascript
[46:47]完美世界DOTA2联赛PWL S2 FTD vs Magma 第二场 11.20
2020/11/23 DOTA
玩转python爬虫之cookie使用方法
2016/02/17 Python
用python实现百度翻译的示例代码
2018/03/09 Python
TensorFlow神经网络优化策略学习
2018/03/09 Python
详解Python3迁移接口变化采坑记
2019/10/11 Python
Django高并发负载均衡实现原理详解
2020/04/04 Python
Python 列表推导式需要注意的地方
2020/10/23 Python
需要知道的CSS3动画技术
2010/01/01 HTML / CSS
英国羊绒服装购物网站:Pure Collection
2018/10/22 全球购物
销售人员个人求职信
2013/09/26 职场文书
30年同学聚会邀请函
2014/01/25 职场文书
简单的大学生自我鉴定
2014/02/18 职场文书
人事行政专员岗位职责
2014/07/23 职场文书
大学生求职自荐信范文
2015/03/04 职场文书
优秀员工自荐书
2015/03/06 职场文书
2015年学校减负工作总结
2015/05/19 职场文书
五星级酒店宣传口号
2015/12/25 职场文书
zabbix监控mysql的实例方法
2021/06/02 MySQL
nginx 添加http_stub_status_module模块
2022/05/25 Servers