html5,js插件实现手机端实现头像剪切上传
思路:先打开相册,选取图片,在剪切图片,转化为base64格式,然后上传到七牛存储,返回url,再传给后端,整个流程就是这样。用的是angular框架,图像插件用到imagecropper.js,废话不多说,直接上代码。
效果:
用到的插件
<!DOCTYPE html>
<html lang="en" ng-app="">
<head>
<meta name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height"/>
<meta charset="UTF-8">
<title></title> <script type="text/javascript" src="app/lib/jquery.js"></script> <script type="text/javascript" src="app/lib/ionic/js/ionic.bundle.min.js"></script> <!-- 上传头像插件 --> <script src="app/lib/headimg/imagecropper.js"></script> <base href='/'/> </head>
<body>
<ion-nav-view>
</ion-nav-view> <script type="text/javascript" src="app/dist/js/main-396e1d7cdb.js"></script> </body>
</html>
页面
<ion-header-bar align-title="center" class="bar-light">
<button ui-sref="home.my" class="button button-clear"><i class="icon ion-ios-arrow-left"></i></button>
<h1 class="title">个人资料</h1>
</ion-header-bar>
<ion-content class="my">
<ion-list>
<ion-item class="item-input" style="height:1.1rem;" >
<form id="form0" class="item-icon-right" href="javascript:void(0);" style="width: 100%">
<span class="input-label f26" style="margin-top:0.4rem; ">头像</span>
<i class="icon "><img ng-src="{{info.headimgurl||'app/dist/img/my/me_img.png'}}" style="width: 0.8rem;position: absolute;top: 0.1rem;right:0.7rem;border-radius:50%;border:3px solid rgba(0,0,0,0.3)" /></i>
<!-- <form name="form0" id="form0" style="width: 100%"> -->
<input type="file" name="file0" id="file0" multiple="multiple"><br>
<!-- </form> -->
<i class="icon "><img src="app/dist/img/my/arrow_icon.png" class="arrow_icon"></i>
</form>
</ion-item> </ion-list> </ion-content>
<div class="img-container">
<img id="img0" src="">
<div class="close"><button class="button button-large button-light">取消</button></div>
<div class="saveBtn" on-tap="save()"><button class="button button-large button-light" >选取</button></div>
</div>
<img class="newImg" src="">
css
.albumsbox {
width: 18.9375rem;
position: absolute;
bottom:;
left: 0.53125rem;
display: none;
z-index:; }
.albumsbox .albums, .albumsbox .cancel {
width: 100%;
height: 6.1875rem;
background: #fff;
border-radius: 0.625rem;
color: #333333;
font-size: 0.8125rem;
line-height: 3.0625rem;
text-align: center; }
.albumsbox .albums .line, .albumsbox .cancel .line {
border-bottom: 1px solid #d1d1d4; }
.albumsbox .cancel {
height: 3.0625rem;
margin: 0.34375rem 0rem 0.5625rem 0rem; } .container {
position: absolute;
top:;
left:;
width: 100%;
height: 100%;
display: none;
background: #000; }
.container #wrapper {
width: 100%;
height: 12.5rem;
position: absolute;
top: 40%;
margin-top: -6.25rem;
left:; }
.container #wrapper #cropper {
width: 100%; }
.container #wrapper #previewContainer {
display: none; } /*img prev*/
.img-container {
width: 100%;
height: 100%;
position: absolute;
top:;
left:;
display: none;
background: #000; } .newImg {
display: none; } .close {
height: 1.1875rem;
width: 30%;
text-align: center;
color: #fff;
font-size: 0.8125rem;
line-height: 1.1875rem;
position: absolute;
bottom: 1.5625rem;
left:; } .saveBtn {
height: 1.1875rem;
width: 30%;
text-align: center;
color: #fff;
font-size: 0.8125rem;
line-height: 1.1875rem;
position: absolute;
bottom: 1.5625rem;
right:; } .cropper-container {
font-size:;
line-height:;
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
direction: ltr !important;
-ms-touch-action: none;
touch-action: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none; } .cropper-container img {
display: block;
width: 100%;
min-width: 0 !important;
max-width: none !important;
height: 100%;
min-height: 0 !important;
max-height: none !important;
image-orientation: 0deg !important; } .cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
position: absolute;
top:;
right:;
bottom:;
left:; } .cropper-wrap-box {
overflow: hidden; } .cropper-drag-box {
opacity:;
background-color: #fff;
filter: alpha(opacity=0); } .cropper-modal {
opacity: .5;
background-color: #000;
filter: alpha(opacity=50); } .cropper-view-box {
display: block;
overflow: hidden;
width: 100%;
height: 100%;
outline: 1px solid #39f;
outline-color: rgba(51, 153, 255, 0.75); } .cropper-dashed {
position: absolute;
display: block;
opacity: .5;
border: 0 dashed #eee;
filter: alpha(opacity=50); } .cropper-dashed.dashed-h {
top: 33.33333%;
left:;
width: 100%;
height: 33.33333%;
border-top-width: 1px;
border-bottom-width: 1px; } .cropper-dashed.dashed-v {
top:;
left: 33.33333%;
width: 33.33333%;
height: 100%;
border-right-width: 1px;
border-left-width: 1px; } .cropper-center {
position: absolute;
top: 50%;
left: 50%;
display: block;
width:;
height:;
opacity: .75;
filter: alpha(opacity=75); } .cropper-center:before,
.cropper-center:after {
position: absolute;
display: block;
content: ' ';
background-color: #eee; } .cropper-center:before {
top:;
left: -3px;
width: 7px;
height: 1px; } .cropper-center:after {
top: -3px;
left:;
width: 1px;
height: 7px; } .cropper-face,
.cropper-line,
.cropper-point {
position: absolute;
display: block;
width: 100%;
height: 100%;
opacity: .1;
filter: alpha(opacity=10); } .cropper-face {
top:;
left:;
background-color: #fff; } .cropper-line {
background-color: #39f; } .cropper-line.line-e {
top:;
right: -3px;
width: 5px;
cursor: e-resize; } .cropper-line.line-n {
top: -3px;
left:;
height: 5px;
cursor: n-resize; } .cropper-line.line-w {
top:;
left: -3px;
width: 5px;
cursor: w-resize; } .cropper-line.line-s {
bottom: -3px;
left:;
height: 5px;
cursor: s-resize; } .cropper-point {
width: 5px;
height: 5px;
opacity: .75;
background-color: #39f;
filter: alpha(opacity=75); } .cropper-point.point-e {
top: 50%;
right: -3px;
margin-top: -3px;
cursor: e-resize; } .cropper-point.point-n {
top: -3px;
left: 50%;
margin-left: -3px;
cursor: n-resize; } .cropper-point.point-w {
top: 50%;
left: -3px;
margin-top: -3px;
cursor: w-resize; } .cropper-point.point-s {
bottom: -3px;
left: 50%;
margin-left: -3px;
cursor: s-resize; } .cropper-point.point-ne {
top: -3px;
right: -3px;
cursor: ne-resize; } .cropper-point.point-nw {
top: -3px;
left: -3px;
cursor: nw-resize; } .cropper-point.point-sw {
bottom: -3px;
left: -3px;
cursor: sw-resize; } .cropper-point.point-se {
right: -3px;
bottom: -3px;
width: 20px;
height: 20px;
cursor: se-resize;
opacity:;
filter: alpha(opacity=100); } .cropper-point.point-se:before {
position: absolute;
right: -50%;
bottom: -50%;
display: block;
width: 200%;
height: 200%;
content: ' ';
opacity:;
background-color: #39f;
filter: alpha(opacity=0); } @media (min-width: 768px) {
.cropper-point.point-se {
width: 15px;
height: 15px; } }
@media (min-width: 992px) {
.cropper-point.point-se {
width: 10px;
height: 10px; } }
@media (min-width: 1200px) {
.cropper-point.point-se {
width: 5px;
height: 5px;
opacity: .75;
filter: alpha(opacity=75); } }
.cropper-invisible {
opacity:;
filter: alpha(opacity=0); } .cropper-hide {
position: absolute;
display: block;
width:;
height:; } .cropper-hidden {
display: none !important; } .cropper-move {
cursor: move; }
js
/**
* laoyou Module
*
* Description
*/
angular.module('app').controller('myEditCtrl', ['$scope', 'api', '$rootScope', '$http', '$state', '$stateParams','$ionicModal','qiniuConfig', function($scope, api, $rootScope, $http, $state, $stateParams,$ionicModal,qiniuConfig) {
var showLoad = $rootScope.showLoad; $http.post("member/info",{test:1}).success(function(data){
$scope.info=data.data;
if(!$scope.info.birthday){
$scope.info.birthday=new Date("1951-01-01");
}else{
$scope.info.birthday=new Date($scope.info.birthday);
}
}).error(function(){
$rootScope.loadFn.hide();
}); var config=angular.copy(qiniuConfig);
// console.log(config)
if(config){
var token=config.UpToken;
} /*picBase是base64图片带头部的完整编码*/
function putb64(picBase){ /*picUrl用来存储返回来的url*/
var picUrl; /*把头部的data:image/png;base64,去掉。(注意:base64后面的逗号也去掉)*/
picBase=picBase.substring(22); /*通过base64编码字符流计算文件流大小函数*/
function fileSize(str)
{
var fileSize;
if(str.indexOf('=')>0)
{
var indexOf=str.indexOf('=');
str=str.substring(0,indexOf);//把末尾的’=‘号去掉
} fileSize=parseInt(str.length-(str.length/8)*2);
return fileSize;
} /*把字符串转换成json*/
function strToJson(str)
{
var json = eval('(' + str + ')');
return json;
} var url = "http://up.qiniu.com/putb64/"+fileSize(picBase);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function()
{
if (xhr.readyState==4){
var keyText=xhr.responseText;
// alert(keyText)
/*返回的key是字符串,需要装换成json*/
keyText=strToJson(keyText); /* http://ojvh6i96g.bkt.clouddn.com/是我的七牛云空间网址,keyText.key 是返回的图片文件名*/
picUrl=config.recordPath+'/'+keyText.key;
// alert(picUrl);
$http.post("member/updateHead",{headimgurl:picUrl}).success(function (res) {
if( res.statusCode == 0) { window.location.reload();
}else{
alert("修改失败");
}
}).error(function(data){
alert("网络异常")
});
}
}
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.setRequestHeader("Authorization", "UpToken "+ token); //token换成自己申请七牛的。
xhr.send(picBase); }
// var _czc = []; $("#file0").change(function(){
// _czc.push(["_trackEvent", "个人资料页","头像",""]);
// console.log($("#img0"))
var objUrl = getObjectURL(this.files[0]) ;
console.log("objUrl = "+objUrl) ;
if (objUrl) {
$("#img0").attr("src", objUrl) ;
$('.cropper-canvas img').attr('src',objUrl);
$('.cropper-view-box img').attr('src',objUrl);
}
var File=$('#img0').attr('src');
if(File!=''||File==undefined){
// $scope.openModal();
$(".my").css('opacity','0');
$('.img-container').show();
}
}) ; //建立一個可存取到該file的url
function getObjectURL(file) {
console.log(file)
var url = null ;
if (window.createObjectURL!=undefined) { // basic
url = window.createObjectURL(file) ;
} else if (window.URL!=undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file) ;
} else if (window.webkitURL!=undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file) ;
}
return url ;
} $('.close').click(function(){
$(".my").css('opacity','1');
$('.img-container').hide();
}) function convertToData(url, canvasdata, cropdata, callback) {
var cropw = cropdata.width; // 剪切的宽
var croph = cropdata.height; // 剪切的宽
var imgw = canvasdata.width; // 图片缩放或则放大后的高
var imgh = canvasdata.height; // 图片缩放或则放大后的高 var poleft = canvasdata.left - cropdata.left; // canvas定位图片的左边位置
var potop = canvasdata.top - cropdata.top; // canvas定位图片的上边位置 var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d'); canvas.width = cropw;
canvas.height = croph; var img = new Image();
img.src = url; img.onload = function() {
this.width = imgw;
this.height = imgh;
// 这里主要是懂得canvas与图片的裁剪之间的关系位置
ctx.drawImage(this, poleft, potop, this.width, this.height);
var base64 = canvas.toDataURL('image/jpg', 1); // 这里的“1”是指的是处理图片的清晰度(0-1)之间,当然越小图片越模糊,处理后的图片大小也就越小
callback && callback(base64) // 回调base64字符串
}
} $(function(){ var $image = $('.img-container > img'); $image.on("load", function() { // 等待图片加载成功后,才进行图片的裁剪功能
$image.cropper({
aspectRatio: 1 / 1 // 1:1的比例进行裁剪,可以是任意比例,自己调整
});
}) // 点击保存
// $(".saveBtn").on("click", function() {
$scope.save = function(){ var src = $image.eq(0).attr("src");
var canvasdata = $image.cropper("getCanvasData");
var cropBoxData = $image.cropper('getCropBoxData');
convertToData(src, canvasdata, cropBoxData, function(basechar) {
// 回调后的函数处理
$(".newImg").attr("src", basechar);
// alert(basechar)
putb64(basechar); });
}
}) }]);
其中qiniuConfig是自己向后台要的,这是上传图片的身份凭证,这是我的qiniuConfig。
这是我头像上传页面的路由。
如有什么问题,欢迎指正。
html5,js插件实现手机端实现头像剪切上传的更多相关文章
- HTML5——摒弃插件和前端框架的异步文件上传
之前我从来没有体会到HTML5的便利,直到这次需要一个异步上传的功能功能.一开始我以为文件的一些声明必须为HTML5才管用,后来才知道添加了很多以前没有的标签,并可以直接播放视频,音频等.可以不再使用 ...
- 第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传
第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传 实现原理 前台用cropper插件,将用户上传头像时裁剪图片的坐标和图片,传到逻辑处理 ...
- 头像截图上传三种方式之一(一个简单易用的flash插件)(asp.net版本)
flash中有版权声明,不适合商业开发.这是官网地址:http://www.hdfu.net/ 本文参考了http://blog.csdn.net/yafei450225664/article/det ...
- 第三百九十六节,Django+Xadmin打造上线标准的在线教育平台—其他插件使用说,自定义列表页上传插件
第三百九十六节,Django+Xadmin打造上线标准的在线教育平台—其他插件使用说,自定义列表页上传插件 设置后台列表页面字段统计 在当前APP里的adminx.py文件里的数据表管理器里设置 ag ...
- HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(二)
上一篇仅仅讲到前台操作,这篇专门涉及到Java后台处理.前台通过Ajax提交将Base64编码过的图片数据信息传到Java后台,然后Java这边进行接收处理.通过对图片数据信息进行Base64解码,之 ...
- springMVC 头像裁剪上传并等比压
第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,jquery.jcrop貌似并没有对 假设是ie下图片预览效果是滤镜做的 做出对应处理,也没有时间去改;仅仅好将就一下先把图片上传 ...
- jquery插件课程2 放大镜、多文件上传和在线编辑器插件如何使用
jquery插件课程2 放大镜.多文件上传和在线编辑器插件如何使用 一.总结 一句话总结:插件使用真的还是比较简单的,引包,初始化,配置参数(json),配置数据(json),而后两步不是必须的.而且 ...
- egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名
egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名 评论:10 · 阅读:8437· 喜欢:0 一.需求 二.CSRF 校验 三.通过 form 表单上传文件 四.通过 ...
- 5.21学习总结——android开发实现用户头像的上传
最近在做个人头像的上传,具体是能调用摄像头和从相册进行选择.本篇文章参考的我的同学的博客,大家有兴趣可以去原作者那里去看看: Hi(.・∀・)ノ (cnblogs.com) 1.使用glide进行图片 ...
随机推荐
- PuTsangTo-单撸游戏开发04 给角色添加基本动画
一. 跳跃与移动的优化与完善 先给上一次的内容做一次补救,也就是上一次中还留存的,由于键盘按键事件的第一次回调与后续回调之间会间隔个小半秒带来的跳跃落地后动作延迟的情况. 最终的键盘按下回调的处理代码 ...
- 学习Redux之分析Redux核心代码分析
1. React,Flux简单介绍 学习React我们知道,React自带View和Controller库,因此,实现过程中不需要其他任何库,也可以独立开发应用.但是,随着应用程序规模的增大,其需要控 ...
- [SinGuLaRiTy] 树形存储结构阶段性测试
[SinGuLaRiTy-1011] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. G2019级信息奥赛专项训练 题目 程序名 时间 内存 ...
- 4月5日--课堂笔记--JS内置对象
JavaScript 4.5 一. JS内置对象 1.数组Array a)创建语法1:var arr=new Array(参数); i. 没有参数:创建一个初始容量为0的数组 ii. ...
- JavaScript基础学习(六)—函数
一.函数的定义 1.function语句形式 //1.function语句式 function test1(){ alert("I am test1"); } test1(); 2 ...
- Sublime text3 设置的中文翻译
// While you can edit this file, it's best to put your changes in // "User/Preferences.sublime- ...
- 腾讯云上Selenium用法示例
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 作者:崔庆才 前言 在上一节我们学习了PhantomJS 的基本用法,归根结底它是一个没有界面的浏览器,而且运 ...
- URL解析器urllib2
urllib2是Python的一个库(不用下载,安装,只需要使用时导入import urllib2)它提供了一系列用于操作URL的功能. urlopen urllib2.urlopen可以接受Requ ...
- Named function expressions demystified
Introduction Surprisingly, a topic of named function expressions doesn't seem to be covered well eno ...
- ArrayList 遍历
1.迭代器遍历 package sourceCode.ArrayList; import java.util.ArrayList; import java.util.Iterator; import ...